2014-11-08 48 views
5

我想將時間序列存儲在MySQL數據庫中。我想以線性方式做到這一點,也就是說,每一行代表一個獨特的觀察(1次測量,1個站點,1次時間戳)。目前,這將需要84 096 000行,它每年將增長約2 102 400行。Timeserie數據庫線性存儲

必須以正確設計的時間序列表,索引和相關查詢(本質上是一個數據的選擇,其中確定的措施,部位和時間範圍)採取什麼措施。

編輯:

添加表設計的建議:

CREATE TABLE TimeSeries(
    Id     INT   NOT NULL  AUTO_INCREMENT, 
    MeasureTimeStamp DATETIME  NOT NULL, 
    MeasureId   INT   NOT NULL, 
    SiteId    INT   NOT NULL, 
    Measure    FLOAT  NOT NULL, 
    Quality    INT   NOT NULL, 
    PRIMARY KEY (Id), 
    CONSTRAINT UNIQUE (MeasureTimeStamp,MeasureId,SiteId), 
    FOREIGN KEY (MeasureId) REFERENCES Measure(Id), 
    FOREIGN KEY (SiteId) REFERENCES Site(Id) 
); 
CREATE INDEX ChannelIndex ON TimeSeries(MeasureId,SiteId); 

提供測量和站點表中,應該怎樣改善這種結構,如果我的主要疑問是:

SELECT * 
FROM TimeSeries 
WHERE (MeasureId IN (?,?,?)) 
    AND (SiteId IN (?,?,?)) 
    AND (MeasureTimeStamp BETWEEN ? AND ?) 
ORDER BY MeasureId ASC, 
     SiteId ASC, 
     MeasureTimeStamp ASC; 

編輯2:

網站約20個,措施約50個。這導致最多1000個頻道(對網站和措施)。它可能會在幾十年內增加一點,但不會超過10000個通道。大部分數據的時間粒度大約爲30分鐘。無論如何,時間粒度不是恆定的,並且不會小於一分鐘(有些數據是每天或每週)。

+0

MySQL可以輕鬆處理它。你預計什麼樣的WHERE子句?最低限度爲「網站」的索引。 – mainstreetmark 2014-11-08 08:54:36

+0

'WHERE'子句至少會使用'IN'列表標準(這些列當然會被編入索引)和'timestamp''使用'BETWEEN'來選擇兩個外鍵'site'和'measure'(索引,因爲它是主鍵的一部分)。 – jlandercy 2014-11-08 08:59:12

+0

然後我建議用'site'和'measure'做一個索引。這兩列將會降低結果的效率。如果您將Timestamp添加到混合中,那麼您的索引將具有與數據表一樣多的行,並且MySQL將忽略它。 – mainstreetmark 2014-11-08 09:03:29

回答

1

一些線索:

  • 在MySQL索引是指您的「索引列」命令主鍵的列表。您想要排列這樣的列表,以便儘可能輕鬆地找到您需要的值。
  • MySQL一次只能在表上使用一個索引。
  • 的MySQL可以使用索引從左到右(MySQl Multi-column indexes)。這意味着指數(A,B,C)允許您執行WHERE A=? AND B=?而不是WHERE B=? AND C=?

在您的例子中,四個指標創建:

  • MeasureId,SiteId(ChannelIndex)
  • MeasureTimeStamp,MeasureId,SiteId(唯一約束)
  • MeasureId(外鍵)
  • SiteId(外鍵)

簡體在放置時,ChannelIndex按照組合MeasureId和SiteId的字符串列表排序。例如。對於MeasureId = 12和Site ID = 68,您可以將排序值設想爲12_68。 您的唯一約束根據像2014-12-23 09:01:43_12_68這樣的值排序。

爲了解決您的查詢時,MySQL既可以使用索引或唯一約束。它取決於您選擇的表格中的數據。但不是最佳的。使用索引它很快就會發現,其中有正確的MeasureIdSiteId索引塊,但隨後將需要進入每個值在主表檢查MeasureTimeStamp是否在範圍內。 使用獨特的約束,可以輕鬆選擇時間範圍。然而,該索引子集具有MeasureIdSiteId,因爲仍然按照MeasureTimeStamp排序。

要提高你的結構,這將有助於你的唯一約束變爲

約束UNIQUE(MeasureId,SITEID,MeasureTimeStamp)

這個指數現在將排序與像12_68_2014-12-23 09:01:43值我期望顯示更好的性能,因爲MySQL現在可以在索引內選擇離散且可預測的範圍數。這涵蓋了你的SELECT語句,並且使索引在同一時間是冗餘的。