2013-10-06 5 views
1

매시간 온도 판독 값을 매 30 분마다 동물 보호소의 여러 동물 케이지에서 수집하여 파일로 버립니다. cron은 해당 데이터를 처리하여이를 MYSQL 데이터베이스에 삽입합니다. 현재 하루 48 건의 온도 판독 값이 모두 하나의 테이블에 저장되고 데이터가 들어올 때 업데이트됩니다. 또는 레코드가 없으면 첫 번째 온도를 저장하는 새 레코드가 만들어집니다.MYSQL에 온도 값 모음을 저장하는 가장 효율적인 방법은 무엇입니까?

현재 케이지 정보 표와 케이지 온도 판독 표가 있습니다. 우리의 실제 갯수는 45 개입니다. 보유한 데이터의 양은 7 년입니다 (대략 2557 일). 온도 테이블의 총 레코드 수는 다음과 같습니다. 115,065

시스템에 다른 위치와 추가 케이지가 추가되므로 전체 케이지 수가 1,000보다 커집니다. 우리는 데이터 사용이 매우 빠르게 성장할 것으로 기대합니다.

아래 표를 구성하여 읽기 속도를 최적화하는 효율적인 방법이 있습니까? 이 데이터는 매일 아침 표시되는 모든 케이지의 그래프를 생성하고 30 분의 cron을 사용하여 케이지 내부의 통풍이 적절하지 않은지 확인합니다.

CREATE TABLE `temperature_readings` (
    `CAGE_ID` int(10) NOT NULL DEFAULT '0', 
    `INT_VALUE_0000` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0030` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0100` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0130` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0200` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0230` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0300` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0330` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0400` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0430` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0500` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0530` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0600` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0630` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0700` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0730` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0800` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0830` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0900` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_0930` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1000` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1030` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1100` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1130` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1200` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1230` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1300` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1330` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1400` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1430` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1500` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1530` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1600` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1630` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1700` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1730` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1800` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1830` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1900` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_1930` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_2000` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_2030` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_2100` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_2130` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_2200` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_2230` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_2300` decimal(5,2) DEFAULT NULL, 
    `INT_VALUE_2330` decimal(5,2) DEFAULT NULL, 
    PRIMARY KEY (`CAGE_ID`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

내 생각과 같은

halfhour_read{ 
- cage_id 
- datetime 
- temperature reading 
} 

또는 해시 temperature_readings 중 하나 cage_id하여 halfhour_read 테이블에 여러 개의 온도 측정을 정상화하는 중이었다, 또는 :

현재 온도 테이블은 다음과 같습니다 오늘 (날짜)를 분할하여 분할합니다.

내가 이해하는 한, 첫 번째 옵션은 레코드 수를 115,065에서 5,523,120으로 늘려서 비교할 때 빠르게 증가하여 향후 공간 문제를 발생시킵니다.

+0

왜 7 년의 역사를 유지해야합니까? –

+0

@ 짐 가르온, 나도 몰라, 과학?!?!?!? –

+0

현실적으로 7 년은 필요하지 않지만 적어도 2 년은 이미 우리가 가진 것입니다. 데이터 캡처의 급격한 증가로 인해 기본 데이터베이스가 현재 구성되어있는 방식을 다시 고려해야합니다. 우리는 매일 최소 1,000 회의 완전한 판독 (48 시간 반 온도 간격)을 얻게 될 것입니다. – Bill

답변

2

예, 구조를 표준화하십시오. 그냥 재미로, 현재 구조로 다음과 같은 쿼리를 작성하십시오. 케이지 A의 지난 주 온도 피크는 얼마입니까?

은 본능에 따라이 구조를 사용

CREATE TABLE readings (
    cage_id INT, 
    dateofreading DATETIME, 
    temperature DECIMAL(10,2), 
    PRIMARY KEY (cage_id, dateofreading), 
    INDEX (dareofreading, cage_id) -- suggested index, useful for time-based queries 
) 

예상 행 크기 (데이터 만) : 4 + 8 + 4 = 16 바이트.

16 바이트 x 48 독서 x 10,000 케이지 x 365 일 = 2.6GB/년. 원하는 경우 색인을 제공하기 위해 3 또는 4를 곱하십시오. 어쨌든, 저장 공간에 대해 걱정하지 마십시오.

수십억 개의 레코드가 포함되어 있어도 적절한 색인 생성 덕분에이 테이블의 데이터를 추출하는 것은 사실상 즉시 이루어져야합니다. 작업 세트 (지난 몇 주 동안의 데이터)는 항상 어쨌든 항상 메모리에 저장됩니다.

(그리고 귀하의 요구 사항이었다 "4800000 매일 독서와 100,000 케이지"경우에, 당신의 주요 관심사는 초당 삽입의 저장 공간 만 취급 수백만되지 않을 것)

그리고 합리적으로 설정 작업 데이터를 유지하기를 size, yes, partition your table, 또는 오래된 레코드를 매번 아카이브 테이블로 이동하십시오.

+0

그냥 재미로, 나는 그것을 보았을 때 내 머리카락을 꺼냈다. 내가 가장 많이 사용하고 잘 작동했지만,보기 흉한 경이로운 쿼리였습니다. 추가 할 수도 있지만 합리적으로 빠른 쿼리입니다 .0001 현재 모든 데이터를 벡터에 추가하고 계산을 수행하여 Java에서 논리를 수행합니다. 초당 수백만 회의 삽입을 처리하려면 어떻게해야합니까? 현재이 프로그램은 수천 개의 배치 삽입물을 준비합니다. – Bill

+0

좋은 게임이라면 아마 포기했을 것입니다. 초당 수백만 건의 삽입을 처리해야한다면 샤딩이나 클러스터링을 생각할 것입니다. 또한 RDBMS의 기능 (트랜잭션 및 관계형 구조)을 사용하지 않는 것 때문에 데이터베이스에이 데이터를 저장하는 것이 좋은 선택인지 여부를 스스로 묻습니다. 하지만 지금은 걱정하지 마세요. 30 분마다 1 시간에 10 억 건의 삽입이 가능하며 저가형 컴퓨터에서도 사용할 수 있습니다. – RandomSeed

1

가장 확실히 정상화 ...하지만 당신은 사실, 5 개 백만 짧은 행이 많은 데이터가 정말없는

:-) 더 큰 디스크가 필요 할 것입니다. MySQL은 그 이상을 처리 할 수 ​​있습니다. 500 만 reading 행은 100MB 정도입니다.

기록 데이터가 변경되지 않으므로 연도별로 데이터를 분할하는 것도 고려해야합니다.

+0

1 년 단위로 데이터를 분할하는 것이 좋습니다. 우리는 가장 큰 디스크를 확실히 얻을 수 있지만, 데이터 입력이 7 년 예제 대신 4,800,000 개의 일일 온도 판독 값을 가진 가상의 100,000 케이지에서 나온 것이라면 똑같은 (정규화) 결과가 유지됩니까? – Bill

+0

예. 정규화하지 않으면 큰 행을 처리하는 것입니다. 역사적인 데이터는 바뀌지 않습니다. 파티션 간격을 좁히고 1 년 대신 1 주일을 말하고 디스크를 계속 추가하십시오. 아직도 많은 역사적인 데이터를 보관해야하는 이유가 아직도 없습니다. –

관련 문제