배경
약 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 천만)이 포함되어 있기 때문에 id
and에 인덱스가 있음에도 불구하고 data_timestamp
성능은 다중 테이블 시나리오보다 훨씬 나쁩니다 (이 예제에서는 1 초 미만이 아닌 9 초 내에 4500 개의 행이 반환 됨). 다중 테이블 스키마에서 특정 기준에 맞는 센서를 찾는 기능은 실제로 제로이므로 단일 테이블로 이동하는 이유가 있습니다.
이 유형의 쿼리는 여러 사용자가 서로 다른 데이터 그룹을 선택하고 각 결과에서 그래프를 비교할 때 빠르게 연속해서 수행 할 수 있습니다. 그래프 또는 스프레드 시트 당 거의 10 초 정도 기다리는 것이 상당히 실망 스러울 수 있습니다.
90 일 후에 데이터가 삭제됩니다. 아카이브 될 수 있지만 현재 요구 사항은 아닙니다.
이 정보가 수집 및 저장 후 데이터가 사용되는 방식을보다 적절하게 보여줄 수 있기를 바랍니다.