我正在研究一个包含大量不可压缩的时间序列数据的项目,并想知道使用原始SQL的Django+Postgres是否合适.

我有每小时约2K个对象的时间序列数据.我每年存储大约200万行,我希望1)能够通过连接切掉数据进行分析,2)能够在Django提供的web上进行基本的概述工作.我认为最好的方法是对对象本身使用Django,但使用原始SQL来处理相关的大型时间序列数据.我认为这是一种混合方法;这可能是一个危险信号,但对一长串数据样本使用完整的ORM感觉有些过头了.有更好的办法吗?

推荐答案

如果我理解正确,您正在考虑将时间序列存储在PostgreSQL中,在一个数据库行中存储一条时间序列记录.不要那样做.

一方面,这个问题是理论性的.关系数据库(我认为大多数数据库)是基于行独立性的前提,而时间序列的记录是按物理顺序排列的.当然,数据库索引为数据库表提供了某种顺序,但这种顺序是为了加快搜索速度或按字母顺序或其他顺序显示结果;这并不意味着对该秩序有任何自然意义.无论您如何订购,每个客户都是独立于其他客户的,每个客户的购买都是独立于其他客户的购买,即使您可以按时间顺序获得它们,以形成客户的购买历史记录.时间序列记录之间的相互依赖性更强,这使得关系数据库变得不合适.

实际上,这意味着表及其索引占用的磁盘空间将是巨大的(可能比存储在文件中的时间序列大20倍),从数据库中读取时间序列的速度将非常慢,大约比存储在文件中慢一个数量级.它也不会给你带来任何重要的好处.您可能永远不会进行查询"给我所有值大于X的时间序列记录".如果你需要这样一个查询,你还需要一个地狱般的其他分析,而关系数据库并没有被设计来执行,所以你无论如何都会把整个时间序列读入某个对象.

因此,每个时间序列都应该存储为一个文件.它可能是文件系统中的一个文件,也可能是数据库中的一个blob.尽管我有implemented the latter个,但我相信前者更好;在Django,我会这样写:

class Timeseries(models.model):
    name = models.CharField(max_length=50)
    time_step = models.ForeignKey(...)
    other_metadata = models.Whatever(...)
    data = models.FileField(...)

使用FileField将使数据库更小,并使系统的增量备份更容易.通过在文件中搜索,也可以更容易地获得切片,这对于一个blob来说可能是不可能或困难的.

现在,什么样的文件?我建议你go 看看Pandas .它是一个用于数学分析的python库,支持时间序列,并且应该有一种将时间序列存储在文件中的方法.

我在上面链接了我的一个图书馆,我不推荐你使用;一方面,它做不到你想要的(它不能处理比一分钟更细的粒度,它还有其他缺点),另一方面,它已经过时了——我在pandas之前写过它,我打算在future 将其转换为使用pandas.有一本书叫《数据分析的Python》,作者是《Pandas 》,我觉得这本书很有价值.

Update (2016):还有XDB.从未使用过它,因此我没有意见,但如果你想知道如何存储时间序列,肯定需要判断它.

Update (2020-02-07):还有TimescaleDB,是PostgreSQL的扩展.

Update (2020-08-07):我们(再次)更改了软件,以便使用TimescaleDB将数据存储在数据库中.我们已经精通PostgreSQL,学习一些TimescaleDB很容易.最重要的具体优势是,我们可以进行类似"查找2019年24小时内降雨量大于50毫米的所有位置"这样的查询,这在以平面文件存储数据时非常困难.另一个优点是多年来的完整性判断,因为这里和那里的小错误,我们有一些重复行的时间序列.缺点也很明显.它使用的磁盘空间是原来的10倍.因此,我们可能需要更改PostgreSQL备份策略.比较慢.检索一个包含30万条记录的时间序列可能需要一秒钟的时间.这是前一刻.我们需要实现缓存来检索时间序列,这在以前是不需要的.

Postgresql相关问答推荐

PostgreSQL中btree_gist索引涉及integer和tstzrange属性查询计划的问题

Keycloak和PostgreSQL

PostgreSQL(container)中使用80K子分区表处理共享内存不足错误

正在应用序列化迁移,但数据库没有更改

将XML解析从T-SQL迁移到Postgres时出现问题

PL/pgSQL中的IP递增函数

尽管违反了部分索引约束,Postgres 插入仍在发生

PostgreSQL 中的 Datum 数据类型是什么以及它的用途是什么?

如何准确确定边界附近的点和地理的 ST_Intersects(ST_Intersects geography vs. Geometry diffrepancy)

JOOQ:数据库版本早于 COCKROACHDB 支持的方言:13.0.0

我在try 访问我的数据库表时在 postgresql 中收到 aclcheck_error 错误

PL/pgSQL 中 PL/SQL %ISOPEN 的类似功能是什么?

什么是 postgres 超级用户

Rails 4 迁移: has_and_belongs_to_many table name

SQL:多次重复结果行,并对行进行编号

使用枚举与布尔值?

全文的 Postgresql 前缀通配符

如何在postgresql中编写关于最大行数的约束?

我应该在 Django DATABASE ENGINE 中使用哪个 Postgres 值?

使用python将数据从csv复制到postgresql