我需要在磁盘上存储一个非常简单的数据结构--Point
。它的字段只是:
Moment
-64位整数,表示时间的高精度。EventType
-32位整数,引用另一个对象。Value
-64位浮点数。
所需经费:
1.(Moment
+EventType
)是Point
的唯一标识,所以我怀疑它是一个复合主键。
1.有大量的Points
。高达50亿(1-2 TB的磁盘空间)。因此,格式必须尽可能小。
1.表的典型且几乎单一的用法是通过精确的EventType
和范围Moments
检索(或创建视图)数百万个Points
。
问题:
- 选择哪种RDBMS?为什么?
Points
表的最佳SQL定义是什么?- 并对我下面的想法发表评论也很感谢。
我不需要一个庞大的专业系统,包括所有工具、功能和扩展,如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)
);
这意味着table浪费了近40%的空间,而不是为了什么。我找到了"The WITHOUT ROWID Optimization"。但它将只在3.8.2版本的SQLite(2013年12月)中可用。等待我需要的ADO.NET提供程序是不合适的。
另一个问题是SQLite对表使用B-tree。它看起来对选择数据范围的效率很低。根据主键的范围选择一大块Points
,看起来SQLite将不是一个好的选择。
2条答案
按热度按时间ggazkfy81#
B树是选择数据范围的最有效的组织。
如果搜索一个常量
event_id
值和一系列moment
值,则仅当event_id
是索引中的第一列时,两列索引才能用于两种查找:您应该尝试使用版本3.8.2,这样您就可以使用没有ROWID优化的。
developers可能会很高兴有人会测试这个函数,并给你一个编译后的预发行版。
vc9ivgsu2#
我认为如果您表将使用多个用户,则不应该使用Embedded DB
Oracle怎么样--按索引组织表(可能是按事件)+按范围分区
或MySQL按范围分区
如果在你的应用程序中真的会有一个用户,也许你可以使用文件系统?
类似于分区表的内容
您可以使用与范围相关的名称创建文件夹
并创建与Event_id相关的名称的文件,因此您只需要存储在文件中的时刻+数据
更像是你的时刻看起来像是
201311141820001234567890123456
您可以创建名为2013111418的文件夹,并只将部分时间和数据存储在文件中
20001234567890123456,数据
20001234567890123457,数据