2015-01-08 1 views
0

내가 만든 모니터링 시스템의 데이터를 저장할 데이터베이스를 만들고 있습니다. 시스템은 1 분에 2 번 데이터 포인트 (~ 4000)를 가져 와서 데이터베이스에 저장합니다. 타임 스탬프를 기반으로 샘플을 다운시킬 수 있어야합니다.mysql이 여분의 값을 없애는 중

결과 : 지금 나는 세 개의 열이 하나 개의 테이블을 사용하여 계획입니다
1 point_id
2. 타임 스탬프
3. 값

때문에 쿼리가 나는 것 할 같은 것 :

SELECT point_id, 
     MAX(value) AS value 
FROM results 
WHERE timestamp BETWEEN date1 AND date2 
GROUP BY point_id; 

나는이 문제가 메모리와 관련하여 매우 비효율적이라고 생각합니다. 이 구조를 사용할 때마다 각 시간 스탬프는 4000 번 기록되어야하는데 이는 약간 과장된 것 같습니다. 내가 생각한 유일한 해결책은 내 데이터베이스의 메모리 사용량을 줄이기 위해 별도의 표를 사용하거나 (필자의 이해에 따르면 아주 나쁜 습관이다) CSV 파일에 데이터를 저장해야한다.이 경우 CSV 파일에 검색 코드를 작성해야한다. 데이터 (내 이해가 날 부랑자가되지 않을 필요가 ... 그리고 아마도 상당히 느린 검색). 너무 많은 중복 데이터를 저장할 필요가없는 구현할 수있는 데이터베이스 구조가 있습니까?

+0

걱정하지 마십시오. 데이터베이스는 영리합니다. 복제는 괜찮습니다. 귀하의 구조는 건전하고 정상화되었습니다. 인덱스를 사용하면 성능 이점을 얻을 수 있습니다. 예, 반복되는 타임 스탬프에 대해 일부 저장소가 필요합니다. 테이블을 찌그러 뜨릴 필사적 인 필요가 없다면 걱정할 필요가 없습니다. –

+0

지금 두 개의 테이블을 사용하고 있습니까? scans.timestamp와 FROM 결과는 어디에서 발생합니까? 얼마나 자주 질문합니까? 샘플링을 녹음 한 다음 최대 값을 찾는 것처럼 보입니까? 얼마나 자주 '최대'복용하고 있습니까? – terary

+0

미안하지만, 나는 두 번째 테이블을 정규화하고 필요가 없다는 질문을 입력하는 도중에 깨달을 필요가 있다고 생각했습니다. 질의는 매우 규칙적이지는 않지만 주 단위로 이루어집니다. –

답변

1

데이터 구조가있는 데이터베이스는 사용자 지정 코드보다 비효율적입니다. 맞춰봐. 그것은 드문 일이 아닙니다.

먼저, 실제로 성능 문제가 발생할 때까지 기다려야한다고 생각합니다. 소수 자릿수 초가없는 timestamp에는 4 바이트가 필요합니다 (here 참조). 따라서 레코드는 4 + 4 + 8 = 16 바이트라고 가정합니다 (value에 대한 이중 부동 소수점 표현으로 가정). 타임 스탬프를 제거하면 12 바이트가 생겨 25 %의 비용이 절감됩니다. 나는 그것이 중요하지 않다는 말은 아니다. 코드 작동과 같은 다른 고려 사항이 더 중요 할 수도 있습니다.

귀하의 데이터에 따르면, 그 차이는 184 Mbytes/day에서 138 Mbytes/day 또는 67 Gbytes/year와 50 Gbytes 사이입니다. 타임 스탬프를 저장하는 방법과 상관없이 큰 데이터 문제를 처리해야합니다.

데이터에 타임 스탬프를 유지하면 다른 최적화, 특히 파티션을 사용하여 각 날짜를 별도의 파일에 저장할 수 있습니다. where 조건이 파티션과 호환된다고 가정하면 쿼리에 큰 이점이됩니다. (here을 파티션하는 방법에 대해 알아보십시오.) 특정 쿼리 예에 대해 파티션이 충분해야하지만 인덱스가 필요할 수도 있습니다.

SQL의 요점은 주어진 문제를 해결하는 가장 좋은 방법이 아니라는 것입니다. 대신, 매우 다양한 문제에 대해 합리적인 해결책을 제시하며, 개별적으로 구현하기 어려운 다양한 기능을 제공합니다. 따라서 합리적인 솔루션을 제공하는 데 걸리는 시간은 맞춤식 코드를 개발하는 것보다 훨씬 적습니다.

+1

꽤 많은 지점에 –

+0

굉장한 것은 통찰력이있다. 이 맥락에서 나는 데이터베이스가 얼마나 많은 공간을 차지하고 있는지 혼란스러워합니다. 필자는 행을 int (타임 스탬프) (4 바이트), smallint를 point_id (2 바이트), float을 단 정밀도 (value) (4 바이트)로 정의했습니다. 그래서 그것은 행 당 10 바이트를 의미해야하지만, 내 테이블 ("SHOW TABLE STATUS LIKE 'tablename'")의 상태를 얻으면 행 당 평균 37 바이트를 따옴표로 묶습니다. 데이터베이스의 크기가 잘못 예측되거나 데이터 길이 속성이 크기를 계산하는 데 부적절한 방법입니까? –

0

이 구조를 사용하면 각 시간 스탬프를 4000 번 기록해야하는데, 이는 나에게 과도한 것으로 보입니다.

아니요. 날짜 값은 그다지 크지 않으며 각 행에 대해 동일한 값을 저장하는 것이 매우 합리적입니다.

...별도의 테이블을 사용하십시오. (저의 이해는 초라한 나쁜 습관입니다.)

누가 그렇게 말 했나요? 데이터를 정규화 (별도의 링크 된 데이터 구조로 분리)하는 것은 사실 좋은 연습입니다. 과용하지 않는 한 SQL은 관계형 테이블에서 잘 수행되도록 설계되었습니다. "시간"테이블을 작성하고 다른 테이블의 데이터에 링크하는 것은 완벽하게 좋을 것입니다. 조금 더 많은 메모리를 사용하지만 아주 제한된 메모리 환경에서 작업하지 않는 한 정말 걱정하지 않아야합니다.

+0

별도의 테이블을 사용할 때 타임 스탬프가 한 번만 테이블 이름에서 참조 될 수 있도록 각 스윕에 대해 별도의 테이블이 있어야한다는 것을 의미했습니다 ... 이는 매 30 초마다 새 테이블을 생성하고 수천 개의 테이블을 사용하여 내 데이터를 쿼리합니다. 파이썬 같은 것을 사용하여 쿼리를 작성할 수는 있지만, 이는 mysql을 사용하는 목적을 완전히 무효로 만듭니다. 나는 우스꽝스럽게 노력하고 있었지만, 내가 분명히 충분히 명확하게 제시 한 것을 설명하지 않았 음을 이제 깨닫습니다. 혼란스러워서 죄송합니다. 응답 해 주셔서 감사합니다. –

관련 문제