如果我正确理解了您的想法,您正在考虑将时间序列存储在PostgreSQL中,一个时间序列记录对应一个数据库行。不要这样做。
一方面,这是一个理论问题。关系型数据库(我认为大多数数据库也是如此)基于行独立的前提,而时间序列的记录是物理有序的。当然,数据库索引为数据库表提供了一些顺序,但该顺序旨在加速搜索或按字母顺序或某种其他顺序呈现结果;它并不意味着该顺序具有任何自然含义。无论您如何排序它们,每个客户都独立于其他客户,每个客户的购买都独立于他的其他购买,即使您可以将它们全部按时间顺序排列以形成客户的购买历史记录。时间序列记录之间的相互依赖性更强,这使得关系型数据库不适用。
实际上,这意味着表格及其索引占用的磁盘空间将会很大(可能比将时间序列存储在文件中大20倍),从数据库中读取时间序列将会非常慢,大约比存储在文件中要慢一个数量级。它也不会给你带来任何重要的好处。你可能永远不会提出查询“给我所有值大于X的时间序列记录”。如果你需要这样的查询,你还需要进行其他复杂的分析,关系型数据库无法执行这些分析,所以你仍然需要将整个时间序列读入某个对象中。
因此,每个时间序列都应该被存储为一个文件。它可以是文件系统中的文件,也可以是数据库中的二进制大对象(blob)。尽管我
已经实现了后者,但我认为前者更好;在Django中,我会写出以下代码:
class Timeseries(models.model):
name = models.CharField(max_length=50)
time_step = models.ForeignKey(...)
other_metadata = models.Whatever(...)
data = models.FileField(...)
使用
FileField
会使数据库更小,更容易进行系统的增量备份。同时,通过在文件中查找可以更容易地获取切片,这可能是使用blob无法实现或困难的。
现在,需要哪种类型的文件呢?我建议你看一下pandas。它是一个用于数学分析的Python库,支持时间序列,并且应该也有一种方法将时间序列存储在文件中。
我上面链接了我的一个库,但我不建议你使用它;一方面它不能处理比分钟更精细的时间粒度,另一方面它已经过时了——我在pandas之前编写了它,并打算在未来将其转换为使用pandas。有一本书,"Python for data analysis",由pandas的作者撰写,我发现它非常有价值。
更新(2016年):还有InfluxDB。我从未使用过它,因此我没有意见,但如果你想知道如何存储时间序列,那么它绝对是你需要检查的东西。
更新(2020年2月7日):还有TimescaleDB,这是PostgreSQL的一个扩展。
更新(2020年8月7日):我们再次更改了软件,以便使用TimescaleDB将数据存储在数据库中。我们已经熟悉PostgreSQL,并且很容易学习一些TimescaleDB。最重要的具体优点是,我们可以进行查询,例如“查找所有在2019年内24小时内降雨量>50mm的位置”,这在存储数据时使用平面文件会非常困难。另一个优点是完整性检查 - 多年来,由于这里那里的小错误,我们有一些带有重复行的时间序列。缺点也很明显。它使用10倍的磁盘空间。因此,我们可能需要更改我们的PostgreSQL备份策略。它更慢。检索具有300k记录的时间序列可能需要一秒钟。这以前是立即完成的。我们需要实现缓存以检索时间序列,这以前不需要。