时间序列数据库线性存储

时间:2014-11-08 08:51:45

标签: mysql database time-series

我想将时间序列存储在MySQL数据库中。我想以线性方式进行,即每行代表一个独特的观察(1个度量,1个站点,1个时间戳)。目前,它需要84 096 000行,并且每年会增加约2 102 400行。

为了正确设计时间序列表,索引和相关查询(基本上是确定测量,地点和时间范围的数据的选择),必须采取哪些预防措施。

修改

添加表格设计提案:

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分钟。无论如何,粒度不是恒定的,并且不会小于一分钟(一些数据是每天或每周)。

1 个答案:

答案 0 :(得分: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排序。

要改善您的结构,将有助于将您的唯一约束更改为

  

CONSTRAINT UNIQUE(MeasureId,SiteId,MeasureTimeStamp)

该索引现在将使用12_68_2014-12-23 09:01:43之类的值进行排序,我希望这些值能够表现出更好的性能,因为MySQL现在可以在索引中选择离散且可预测的范围数量。这涵盖了SELECT语句,同时使索引冗余。