在关系数据库中存储大量的点(x,y,z)

时间:2013-11-14 15:30:47

标签: sql sqlite data-structures rdbms bigdata

我需要在磁盘上存储一个非常简单的数据结构 - Point。它的字段只是:

  • Moment - 64位整数,表示高精度的时间

  • EventType - 32位整数,对另一个对象的引用

  • Value - 64位浮点数

要求

1)这对(Moment + EventType)是Point的唯一标识符,因此我怀疑它是表的复合主键

2)有大量的Points。高达50亿(1-2 TB的磁盘空间)。所以格式必须尽可能小。

3)该表的典型和几乎单一用法是按照完整PointsEventType的范围检索(或创建一个)数百万Moments的视图。

问题:

选择哪种RDBMS?为什么?

Points表的最佳sql定义是什么?

以下对我的想法的评论也很感激

我的研究:

我是RDBMS领域的全新手,但我听说过很多关于SQLite的内容。我不需要一个庞大的专业系统,包括PostgreSQL或MSSQL等所有工具,功能和扩展。另外我觉得我不需要服务器而不是简单的“嵌入式”数据库文件,因此SQLite的选择看起来是最佳的。另一个具有嵌入式数据库功能的优秀RDBMS是Firebird,但我被SQLite的动态类型范式所诱惑。看起来它可以节省我在磁盘上的空间,因为整数字段可以以“较小”的形式存储(1,2,3,4,6字节)。

但很快就出现了问题。

首先,当主键是复合键时,SQLite会创建特殊的ROWID列(64位长度):

CREATE TABLE points (
    moment integer not null,
    event_id integer not null,
    value numeric not null,
    PRIMARY KEY (moment, event_id)
);

这意味着桌子浪费了近40%的空间。

我找到了关于"The WITHOUT ROWID Optimization"的好文章。但它只能在3.8.2版本的SQLite(2013年12月)中使用。等待我需要的ADO.NET提供程序是不合适的。

另一个问题是SQLite对表使用B-tree。我不确定,但看起来选择数据范围效率低下。我的主要任务是根据主键的范围选择一个Points的大块,所以看起来SQLite会很糟糕。

未来的研究对我来说似乎太难了(至少在今天)。期待有经验的人的帮助。

2 个答案:

答案 0 :(得分:1)

B树是选择数据范围的最有效组织。

如果您搜索常量event_id值和一系列moment值,则仅当event_id是第一列时,两列索引才可用于两个查找指数:

CREATE TABLE points (
    event_id INTEGER NOT NULL,
    moment INTEGER NOT NULL,
    value NUMERIC NOT NULL,
    PRIMARY KEY (event_id, moment)
);

您应该尝试使用版本3.8.2,以便可以使用WITHOUT ROWID优化 developers可能很高兴有人会测试这个功能,并给你一个编译的预发布版本。

答案 1 :(得分:-1)

我认为如果您的表将使用多个用户,则不应使用嵌入式数据库
那么Oracle - 由索引组织的表(也许是按事件)+按范围划分
或按范围划分的MySql

如果你的应用程序真的是一个用户,也许你可以使用文件系统?
像分区表这样的东西
您可以创建名称与范围相关的文件夹
并创建名称与event_id相关的文件,因此您只需要在文件中存储时刻+数据 更多例如你的时刻
201311141820001234567890123456
您可以创建名称为2013111418的文件夹,并仅在文件中存储时刻和数据的一部分
20001234567890123456,数据
20001234567890123457,数据