2013-10-06 43 views
1

每隔30分鐘從動物收容所的幾個動物籠中收集每小時的溫度讀數,並將它們傾倒入文件中。 cron處理該數據並將其插入MYSQL數據庫。目前,當天所有48個溫度讀數都存儲在一個表格中,並且在數據進入時將其更新,或者如果沒有記錄存在,則會創建一個存儲第一個溫度的新記錄。將溫度值集合存儲到MYSQL中的最有效方法是什麼?

我們目前有一個籠子信息表和一個籠子溫度讀數表。 我們的籠子總數是45. 我們擁有的數據量爲7年(大約2557天)。 溫度表的記錄總數爲:115,065

我們將向系統添加不同的位置和附加籠,因此籠的總數將大於1,000。我們預計數據使用增長非常快。

是否有更有效的方法來構建下表來優化讀取速度?數據用於生成每天早上顯示的每個籠子的圖表,以及30分鐘的crons以檢查籠子內通風不足。

當前溫度表如下:

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; 

我的想法是通過任一cage_id如

halfhour_read{ 
- cage_id 
- datetime 
- temperature reading 
} 

或哈希temperature_readings要麼規格化多個溫度讀數到一個halfhour_read表或今天(日期),以便分區。

據我所知,第一個選項會將記錄數從115,065增加到5,523,120,並且相比之下會迅速增長,從而產生未來的空間問題。

+0

爲什麼你需要保持7年的歷史? –

+0

@JimGarrison,我不知道,科學?!?!?!? –

+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.6 GB。如果需要,乘以3或4以提供索引。無論如何,不​​要擔心存儲空間。

從適當的索引中提取數據表應該幾乎是即時的,即使它包含數十億條記錄。無論如何,你的工作集(過去幾周的數據)可能總是適合記憶。

(如果你的要求是「每天閱讀480萬10萬個籠」,您的主要關注不會是每秒插入的存儲空間,但處理上百萬)

並保持工作數據設置爲一個合理的大小,是的,分區你的表,或者只是現在將舊的記錄移動到存檔表。

+0

只是爲了好玩,當我看着它時,我把頭髮拉出來。我用GREATEST,它運行良好,但這是一個醜陋的不靈活的查詢。儘管我可能會補充一點,但這是一個相當快的查詢。我們目前通過將所有數據添加到矢量中並從中進行計算來完成Java中的邏輯。 我們如何才能處理每秒數百萬次插入?目前該程序準備了數千個批量插入。 – Bill

+0

好的遊戲,我可能會放棄:)如果我不得不處理每秒數百萬次插入,我會認爲分片或聚類。我還會問自己,將這些數據存儲在數據庫中是否是一個不錯的選擇,因爲您似乎沒有使用RDBMS的功能(即事務和關係結構)。但現在不要擔心,即使在低端機器上,每半小時10K插入也是一塊蛋糕。 – RandomSeed

1

最絕的正常化...但你會需要:-)

更大的磁盤實際上,500萬個短行是不是一個真正的大量的數據。 MySQL可以處理的不僅僅是這些。 5百萬reading行將在100MB的數量級。

您還應該考慮按年份劃分數據,因爲歷史數據永不改變。

+0

按年劃分數據的好主意。我們絕對可以得到一個更大的磁盤,但是如果數據輸入來自假設的100,000個網箱,每天有4,800,000個溫度讀數而不是7年的例子,那麼相同的(標準化)也是如此? – Bill

+0

是的。如果你沒有規範化你正在處理大行。歷史數據不會改變,對吧?縮小分區間隔,比如說1周而不是1年,只是繼續添加磁盤。我仍然不明白爲什麼你需要保存那麼多的歷史數據。 –

相關問題