我正在比较两个非常准系统的 SQLite 数据库,其中相同的数据以不同的方式存储。
数据库 A 有这样的表:
字符串(唯一文本) | count_1(整数) | count_2(整数) |
---|---|---|
这 | 23 | 10 |
它 | 56 | 44 |
曾是 | 32 | 89 |
数据库 B 有这样的表:
字符串(文本) | count_1(整数) | count_2(整数) |
---|---|---|
这 | 23 | null |
这 | null |
10 |
它 | 56 | null |
它 | null |
44 |
曾是 | 32 | null |
曾是 | null |
89 |
奇怪的是,在两者之后,数据库 A 占用的磁盘空间比数据库 B多近 50%(4.8MB 对 2.5MB)VACUUM
。这违背了我的预期,因为数据库 B 有双倍的行并且必须重复每个字符串值两次。我想知道是否对此有任何解释,或者我是否只是以某种方式错误地生成了表格。如果我在这里遗漏了一些非常基本的东西,我深表歉意——我是 RDB 的新手。
更新:我现在确定数据库 A 中字符串列的 UNIQUE 约束是导致大小加倍的原因——我很好奇为什么会这样!
添加 UNIQUE 约束会强制 SQLite 为数据库中的表创建唯一索引。
对于表中的每一行,索引都有一个字符串列的副本和对表中 ROWID 的引用(它是一个整数),因此它的大小与表的大小相当。
SQLite 在存储值方面非常高效,因此数据库 B 中的 NULL 不会占用不必要的空间,并且使用 varint 存储 INTEGERS,其长度取决于存储的值。
count_1 和 count_2 具有可以存储在单个字节中的低值。唯一索引中的 ROWID 可以占用 2,3 或更多字节(如果有数百万行),因此索引中的 string+ROWID 可以比表中的 string+NULL+byte 占用更多的空间。