데이터베이스 재 설계 기회 :이 센서 데이터 수집에 사용할 테이블 설계는 무엇입니까? B까지 센서 X에 대한 데이터를

배경

약 2000 개의 센서 네트워크가 있으며 각 센서에는 약 100 개의 데이터 포인트가 있으며 10 분 간격으로 수집합니다. 이 데이터 포인트는 일반적으로 int 값이지만 일부는 문자열과 부동 소수점입니다. 이 데이터는 가능하면 더 효율적으로 90 일 동안 저장해야합니다.

데이터베이스 디자인

이 프로젝트를 처음 수행했을 때 각 센서마다 쉼표로 구분 된 파일을 작성하는 C # 앱을 작성했습니다. 당시에는 트렌드를보고 싶을 때 Excel에서 csv를 열고 필요에 따라 그래프를 만들었습니다.

상황이 커지고 MySQL 데이터베이스로 전환했습니다. 각 센서마다 테이블을 만들었습니다 (예, 테이블이 많이 있습니다). 잘 작동했지만 몇 가지 제한 사항이 있습니다. 테이블이 너무 많으면 특정 값을 찾을 때 모든 센서에서 데이터를 찾는 쿼리를 작성하는 것이 불가능합니다.

다음 버전에서는 Microsoft SQL Server Express로 전환하여 모든 센서 데이터를 하나의 큰 테이블에 넣었습니다. 이것은 또한 작동하며, 관심있는 모든 센서 중에서 값을 찾기 위해 쿼리를 수행 할 수 있습니다. 그러나 Express 버전의 10GB 제한에 도달했으며 SQL Server Standard에 투자하기보다는 MySQL로 다시 전환하기로 결정했습니다.

질문

MySQL의 성능과 확장성에 만족하지만 모든 데이터를 한 테이블에 넣는 방법이 최선인지 확실하지 않습니다. 단일 테이블의 10GB는 다른 디자인을 요구하는 것 같습니다. 그래프를 작성하기 위해 데이터를 쿼리해야 할 필요성은 여전히 ​​남아 있으며 90 일 동안 한 센서의 온도 데이터를 그래프로 표시하는 쿼리의 성능 문제가 있을지 걱정됩니다. 즉, 그래프는 관심있는 센서를 분리하기 위해 SQL이 데이터 더미를 정렬 할 때까지 기다리지 않고 빠르게 생성 할 수있는 것이어야합니다.

성능을 향상시키기 위해이 테이블을 분할해야합니까? 아니면 그러한 큰 테이블을 갖는 것이 드문 일이 아닌가?

센서 ID 및 타임 스탬프 열에 대한 인덱스가 있는데 이는 쿼리의 경계를 정의하는 것과 거의 같습니다. (즉, 시간 A에서 시간 B까지 센서 X에 대한 데이터를 얻습니다).

샤딩 및 파티셔닝에 대해 조금 읽었지만이 경우에는 적절하다고 생각하지 않습니다.


편집하다:

지금까지 의견과 답변을 바탕으로 추가 정보가 도움이 될 수 있습니다.

무기한 저장 공간 : 현재 90 일이 지난 데이터를 저장하지 않습니다. 매일 90 일보다 오래된 데이터를 제거하는 쿼리를 실행합니다. 앞으로 중요 해지면 더 많이 저장하지만 지금은 충분합니다. 이는 크기를 확인하고 성능을 높게 유지하는 데 도움이됩니다.

엔진 유형 : 원래 MySQL 구현은 MyISAM을 사용했습니다. 이번에는 새로운 구현 (다수 대신 하나의 데이터 테이블)을 위해 테이블을 생성 할 때 기본적으로 InnoDB로 설정되었습니다. 나는 하나 또는 다른 것에 대한 요구 사항이 있다고 생각하지 않습니다.

정규화 : 데이터 수집 테이블 외에 다른 테이블도 있습니다. 이 지원 테이블에는 센서의 네트워크 정보, 사용자의 로그인 정보 등과 같은 항목이 저장됩니다. 정규화 할 것이 많지 않습니다 (내가 아는 한). 데이터 테이블에 열이 많은 이유는 각 센서에 많은 변수가 있기 때문입니다. (여러 온도, 조명 수준, 기압 등) 나에게 정규화는 중복 데이터 또는 반복 그룹이 없음을 의미합니다. (적어도 1NF의 경우) 주어진 센서에 대해 특정 시간에 모든 값을 저장하려면 하나의 데이터 행이 필요하며 여기에 관련된 1 : N 관계는 없습니다.

테이블을 기능적으로 분리하여 한 테이블의 모든 온도 관련 값과 다른 공기 압력 관련 값을 만들 수 있습니다. 이렇게하면 온도 전용 쿼리를 만드는 사람의 효율성이 향상 될 수 있지만 모든 데이터를 한 번에 삽입해야합니다. 그럼에도 불구하고 효율성 향상은 SELECT 작업에 유용 할 수 있습니다. 분명히 사용자가 데이터를 요청하는 빈도에 따라 테이블을 세로로 분리하는 것이 좋습니다. 아마도 이것이 내가해야 할 전부입니다. 내 질문을 할 때 이것이 가치가 있다는 확인을 찾고 있다고 가정합니다.


편집 2 :

데이터 사용 : 일반적으로 문제가있는 항목에만 초점을 맞추기 때문에 궁극적으로 많은 데이터를 보거나 필요로하지 않습니다. 그러나 문제 를 찾기 위해 다양한 도구를 사용하여 데이터를 검색하고 확대 할 항목을 결정합니다.

예를 들어, 메모리 사용 값 (고객 별 독점 소프트웨어 프로그램)과 재부팅 / 크래시 사이의 상관 관계를 발견했습니다. 내가 수집하는 데이터 포인트 중 하나는이 메모리 사용량과 관련이 있으며 특정 메모리 사용량을 초과 한 후 장치가 불안정 해지는 것을 보여주기 위해 기록 데이터를 볼 수있었습니다. 현재이 소프트웨어를 실행하는 장치의 하위 집합에 대해이 값을 확인하고 너무 높은 경우 재부팅 명령을 실행합니다. 이것이 발견 될 때까지, 나는이 데이터를 수집하는 것이 가치 있다고 생각하지 않았습니다.

이러한 이유로, 나는 가치가 의심스러운 경우에도 약 100 개의 데이터 포인트가 수집되고 저장되도록 유지했습니다. 그러나 일상적인 일상적인 사용에서 사용자는 일반적으로 이러한 매개 변수 수십 개를 검사합니다. 사용자가 특정 지역에 관심을 가지면 소프트웨어를 사용하여 수십 개의 센서에 대한 데이터의 그래프 또는 스프레드 시트를 생성 할 수 있습니다. 온도, 기압 및 조도 등을 나타내는 2 ~ 3 개의 플롯 선이있는 30 일 그래프를 보는 것은 드문 일이 아닙니다. 이렇게하면 다음과 비슷한 쿼리가 실행됩니다.

SELECT sensor_id, location, data_timestamp, temp1, air1, light1
FROM data
WHERE data_timestamp >= '2012-02-01'
AND sensor_id IN (1, 2, 3);

(각 센서마다 자체 테이블이있는 원래 MySQL 버전에서는 세 개의 개별 쿼리가 발행되지만 결과는 소프트웨어로 결합되어 그래프를 작성합니다.)

data테이블에 너무 많은 행 (~ 1 천만)이 포함되어 있기 때문에 idand에 인덱스가 있음에도 불구하고 data_timestamp성능은 다중 테이블 시나리오보다 훨씬 나쁩니다 (이 예제에서는 1 초 미만이 아닌 9 초 내에 4500 개의 행이 반환 됨). 다중 테이블 스키마에서 특정 기준에 맞는 센서를 찾는 기능은 실제로 제로이므로 단일 테이블로 이동하는 이유가 있습니다.

이 유형의 쿼리는 여러 사용자가 서로 다른 데이터 그룹을 선택하고 각 결과에서 그래프를 비교할 때 빠르게 연속해서 수행 할 수 있습니다. 그래프 또는 스프레드 시트 당 거의 10 초 정도 기다리는 것이 상당히 실망 스러울 수 있습니다.

90 일 후에 데이터가 삭제됩니다. 아카이브 될 수 있지만 현재 요구 사항은 아닙니다.

이 정보가 수집 및 저장 후 데이터가 사용되는 방식을보다 적절하게 보여줄 수 있기를 바랍니다.



답변

큰 이유로 테이블을 분할하는 것에 대해 생각해야합니다.

거대한 테이블에있는 모든 인덱스, 심지어 하나의 인덱스 만 있으면 INSERT, UPDATE 및 DELETE를 실행할 때 인덱스 유지 관리를 수행하기 위해 많은 CPU로드 및 디스크 I / O를 생성 할 수 있습니다.

2011 년 10 월 7 일 에 테이블 분할이 큰 도움이되는 이유 대한 이전 게시물을 썼습니다 . 다음은 지난 게시물에서 발췌 한 것입니다.

데이터 분할은 동일한 클래스에 논리적이고 응집력있는 데이터를 그룹화하는 역할을합니다. 데이터가 올바르게 그룹화되어 있으면 각 파티션 검색 성능을 고려해야합니다. 논리 파티셔닝을 달성하면 검색 시간에 집중하십시오. ID로만 데이터를 분리하는 경우 읽기 또는 쓰기를 위해 많은 데이터 행에 액세스하지 못할 수 있습니다. 가장 중요한 고려 사항은 다음과 같습니다. 가장 자주 액세스하는 모든 ID를 찾아서 파티션합니다. 자주 액세스하지 않는 모든 ID는 하나의 큰 아카이브 테이블에 있어야하며,이 인덱스는 ‘블루 문에서 한 번’쿼리에 대한 인덱스 조회로 여전히 액세스 할 수 있습니다.

나중에 내 게시물 전체 를 읽을 수 있습니다 .

추격을 바로 잡으려면 10GB 테이블에서 거의 사용되지 않는 데이터를 조사하고 찾아야합니다. 이 데이터는 기록 특성에 대한 임시 쿼리가 필요한 경우 쉽게 액세스 할 수있는 아카이브 테이블에 배치해야합니다. 10GB에서 그 뒤에 OPTIMIZE TABLE10GB 테이블 에서 해당 아카이브를 마이그레이션 하면 작업 세트가 더 빨리 SELECT, INSERT, UPDATE 및 DELETE를 실행할 수 있습니다. DDL조차도 10GB 테이블보다 2GB 작업 세트에서 더 빠릅니다.

업데이트 2012-02-24 16:19 EDT

고려해야 할 두 가지 사항

  1. 귀하의 의견으로는 정규화가 필요한 것 같습니다.
  2. 90 일이 지난 모든 것을 아카이브 테이블로 마이그레이션해야하지만 여전히 아카이브와 작업 세트에 동시에 액세스해야합니다. 데이터가 모두 MyISAM이면 MERGE 스토리지 엔진을 사용하는 것이 좋습니다. 먼저 작업 세트 MyISAM 테이블과 아카이브 MyISAM 테이블을 통합하는 MERGE 테이블 맵을 작성하십시오. 하나의 MyISAM 테이블에 91 일 미만의 데이터를 보관하고 90 일이 지난 데이터를 아카이브로 롤오버합니다. MERGE 테이블 맵만 쿼리합니다.

사용 방법에 대한 두 가지 게시물이 있습니다.

여기에 많은 열이있는 테이블에 추가 게시물이 있습니다.

MySQL에 열이 너무 많습니다


답변

흥미 롭다 … 모든 센서가 같은 종류의 데이터를 생산한다면 모두 같은 테이블에 두는 것이 합리적이지만, 그 정도의 데이터로 성능에 대해 걱정하는 이유를 알 수 있습니다.

그래프를 생성하는 데 보통 90 일이 있습니까? 그렇다면 90 일 전부터 오늘까지 데이터를 저장하는 기본 센서 데이터 테이블과 그보다 오래된 모든 데이터는 보관 테이블에 저장됩니다. 이는 보고서가 생성되는 테이블의 크기를 줄이는 데 도움이 될 수 있으며 10GB의 대부분의 데이터는 기본 테이블이 아닌 아카이브 테이블에있을 것입니다. 보관 작업은 매일 밤 실행되도록 예약 할 수 있습니다.

또한 보고서를 생성하기에 더 적합한 구조로 데이터를 저장하는 별도의보고 데이터베이스를 구축하는 것도 고려해 볼 수 있습니다. 가능한 경우) 생성하고 정기적으로 (예 : 야간) 기본 데이터베이스에서 다시 채 웁니다. 물론 최신 데이터로 생성 된 보고서가 필요한 경우에는 제대로 작동하지 않을 수 있습니다.


답변