【发布时间】:2015-01-05 01:55:17
【问题描述】:
我想将时间序列存储在 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 个通道(站点和度量对)。它可能会在几十年内增加一点,但不会超过 10000 个频道。大多数数据的时间粒度约为 30 分钟。无论如何时间粒度不是恒定的,不会小于一分钟(有些数据是每天或每周)。
【问题讨论】:
-
MySQL 可以轻松搞定。你预计会有什么样的 WHERE 子句?最低限度,“网站”的索引。
-
WHERE子句将至少选择两个外键site和measure使用IN列表标准(这些列当然会被索引)和timestamp使用 @ 987654330@(索引,因为它是主键的一部分)。 -
那么我建议同时使用
site和measure创建一个索引。这两列将减少结果以提高效率。如果您将 Timestamp 添加到组合中,那么您的索引将拥有与数据表一样多的行,而 MySQL 将忽略它。 -
您的年度增长与您每秒的实际写入操作数(可能包括 FK)相比,并没有那么重要。你能多谈谈数据的“密度”吗……有 5 个站点吗?还是50000?有多少措施?是每秒记录 TS,每秒 10 次吗?等
-
@cerd 增加了 FK 密度的精度
标签: mysql database time-series