【发布时间】:2019-07-25 13:30:32
【问题描述】:
初步情况
假设我有一个如下所示的简单表格:
CREATE TABLE AppData (
id INTEGER PRIMARY KEY,
elementId VARCHAR(36),
timestampMs INTEGER,
enterTypeA SMALLINT,
exitTypeA SMALLINT,
enterTypeB SMALLINT,
exitTypeB SMALLINT
);
CREATE UNIQUE INDEX app_data_index ON AppData (timestampMs DESC, elementId);
增加了索引,因为很多查询都是基于timestampMs和elementId来选择实体的。
我存储每分钟退出并为不同的elements 输入不同的types 值。例如:
elementId, timestampMs, enterTypeA, exitTypeA, enterTypeB, exitTypeB
1, 1559383200000, 4, 3, 1, 5
2, 1559383200000, 8, 2, 3, 7
1, 1559383260000, 2, 2, 4, 0
2, 1559383260000, 1, 0, 9, 2
问题描述
新的types 需要添加到数据库中。未来可能还会添加更多types。所以我尝试了两种不同的方法:
方法 1:
为新的types 添加更多列:
CREATE TABLE AppData (
id INTEGER PRIMARY KEY,
elementId VARCHAR(36),
timestampMs INTEGER,
enterTypeA SMALLINT,
exitTypeA SMALLINT,
enterTypeB SMALLINT,
exitTypeB SMALLINT,
enterTypeC SMALLINT,
exitTypeC SMALLINT
);
CREATE UNIQUE INDEX app_data_index ON AppData (timestampMs DESC, elementId);
方法 2:
每个type 都有一个新行(意味着更大的索引):
CREATE TABLE AppData (
id INTEGER PRIMARY KEY,
elementId VARCHAR(36),
timestampMs INTEGER,
enterValue SMALLINT,
exitValue SMALLINT,
type SMALLINT
);
CREATE UNIQUE INDEX app_data_index ON AppData (timestampMs DESC, elementId, type);
我个人更喜欢方法 2,因为它减少了重复。
我用 5 个elements 和 3 个types 测试了这两种方法并插入了 10 天的测试数据。结果表明,方法 1 的数据库大小远小于方法 2 的大小(从我的角度来看,这是合理的逻辑,因为方法 2 的行数增加了三倍):
方法 1: 8.2 MB | 144'000 个条目
方法 2: 24.6 MB | 432'000 个条目
问题
正如我所见,两种解决方案中的索引大小约为数据库大小的 50%,因此很明显方法 2 的数据库大小总是会更大。
SQLite 中的更多行而不是更多列总是会对数据库大小产生如此大的影响吗?
到目前为止,我还没有找到进一步减小方法 2 大小的解决方案。也许这是由于索引而无法实现的?
【问题讨论】:
-
您也许可以删除
id列,并使用您当前的唯一索引将其设为WITHOUT ROWID 表作为新的主键。这将大大减少大小(并在给定 pk 列的情况下加快非 pk 列的查找速度) -
感谢您的提示。我以前不知道
WITHOUT ROWID。所以我测试了它,没有索引和新的主键。它将第二种方法的数据库大小减少了大约 12 MB。
标签: sqlite