mysql - 时序数据库线性存储

标签 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);

如果存在 Measure 和 Site 表,如果我的主要查询是:

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 个 channel (站点和度量对)。几十年后可能会增加一点点,但不会超过10000个 channel 。大多数数据的时间粒度约为 30 分钟。反正时间粒度不是恒定的,不会小于一分钟(有些数据是每天或每周)。

最佳答案

一些线索:

  • MySQL 中的索引是按“索引列”排序的主键列表。您希望以尽可能容易找到所需值的方式对该列表进行排序。
  • MySQL 一次只在一张表上使用一个索引。
  • MySQL 可以使用从左到右的索引(MySQl Multi-column indexes)。这意味着 Index(A,B,C) 允许您执行 WHERE A=? AND B=? 但不是 WHERE B=?和 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 的 block ,但随后它需要进入主表中的每个值以检查是否MeasureTimeStamp 在范围内。 使用唯一约束,它可以轻松选择时间范围。然而,此索引子集具有随机排序的 MeasureIdSiteId,仍按 MeasureTimeStamp 排序。

为了改进您的结构,将您的唯一约束更改为

CONSTRAINT UNIQUE (MeasureId,SiteId,MeasureTimeStamp)

该索引现在将使用 12_68_2014-12-23 09:01:43 这样的值进行排序,我希望它能显示更好的性能,因为 MySQL 现在可以在索引中选择离散且可预测的范围数.这会覆盖您的 SELECT 语句并同时使您的索引变得多余。

关于mysql - 时序数据库线性存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26815394/

相关文章:

php - 带有 mysql 变量的 Mysqli 准备语句

mysql - rails : Performance issue with joining of records

mysql - 左连接 - 当仍然存在类似的记录拟合匹配条件时,尝试在第二个表中查找丢失的记录

c# - 是否有任何好的/可自动化的依赖管理工具来管理应用程序、数据库和外部资源的依赖关系?

python - 工程进度中的异常值

mysql - 扩展结果集,添加从另一个表的不同行中获取的列

Android sqlite 返回 : error code = 14

database - 我试图在一个巨大的二进制负载后重建 Progress 数据库上的索引,得到这个错误

python - 如何有效地将 Pandas 中的相似数据框组合成一个巨大的数据框

r - 在 R 中使用线性插值添加缺失的 xts/zoo 数据