34

我有一个 7.4Gb 的 csv 文件。使用python 脚本将其转换为 sqlite 数据库后,输出数据库为 4.7Gb,约为原始大小的 60%。

csv 有大约 150,000,000 行。它有标题:

tkey,ipaddr,healthtime,numconnections,policystatus,activityflag

每行看起来像

261846,172.10.28.15,2012-02-03 16:15:00,22,1,1

该脚本使用 healthtime 将数据拆分为表 192 表

当我第一次看到这些数字时,我以为我在某个地方犯了错误。从仅写入健康时间 192 次而不是 150,000,000 次的附加效率中,我应该期望文件大小减少多大?

编辑:我一发布这个我就意识到了答案。我删除了大约 40% 的字符串,因此大小减少了 40%。

编辑2让我们计算纯文本之间的大小差异:

"261846,172.10.28.15,2012-02-03 16:15:00,22,1,1" 

和数据库条目:

db(261846,'172.10.28.15',22,1,1)

首先,我们在纯文本表示中从 46 个字符减少到 26 个字符。

剩下的字符是:

"261846,172.10.28.15,22,1,1"

或 26 个字节。如果每个整数都需要以 32 位(4 字节)存储,那么我们有:

12 字节 (ipaddr) + 4 字节 * 4(整数字段)= 28 字节。

所以看起来转换为整数会降低存储效率,而我的所有收益都来自于减少每行中存储的字符数。

4

3 回答 3

37

SQLite 没有运行压缩算法,但它将数据存储在二进制文件而不是文本文件中。这意味着可以更有效地存储数据,例如使用 32 位(4 字节)数字来表示10,000,000,而不是将其存储为 8 字节的文本(如果文件是 unicode 则更多)。

如果您有兴趣,这里有更多关于SQL 数据库文件格式的详细信息。

那有意义吗?

于 2012-05-30T21:18:07.450 回答
21

默认情况下,SQLite 不会压缩它写入磁盘的数据;但是,SQLite 确实有一组“专有扩展”用于该目的和其他目的。ZIPVFS在以下链接中查找。

http://www.sqlite.org/support.htmlhttp://www.hwaci.com/sw/sqlite/prosupport.html

通过将字段编码为整数,您可以在数据中实现大量“压缩”。例如,IP 地址被设计成适合一个字(4 个字节)。地址的每个八位字节可以用一个字的一个字节来表示。

string[] octets = '172.168.0.1'.split('.')
int ip = atoi(octets[0]) << 24
ip |= atoi(octets[1]) << 16
ip |= atoi(octets[2]) << 8
ip |= atoi(octets[3])

此外,您的时间戳可能以 Unix 时间表示,即自纪元以来的秒数。

UPDATE mytable SET healthtime = CAST(strftime('%s',healthtime) AS INTEGER);

查看日期和时间函数

注意CAST上面 SQL 中的指令: SQLite 不对列强制类型,因此您可能将一组数字存储为字符串;增加你的字段大小超过必要的(这也会使某些查询表现得很奇怪)。

还有一件事:字段大小不是故事的唯一部分。请记住,索引也占用空间,整数索引更有效——就磁盘大小和性能而言。

于 2013-12-04T01:40:56.093 回答
2

我的 GIT 存储库中有一个相当大的 SQLite 文件,我想知道为什么我的存储库总大小没有增长那么多,反而比我的 SQLite- 文件还要小.db。事实证明,GIT 默认压缩存储库。对我的.db-file 的快速检查也表明了这一点,因为压缩.db-file 会生成一个 zip-archive,它只有.db-file 大小的 20%。

因此,至少在默认设置下,SQLite 看起来并没有以压缩方式存储数据。然而,不管怎样,将一个大的 SQLite 文件添加到 GIT 存储库可能会很好,因为 GIT 会自动执行压缩。

于 2020-01-28T11:26:33.137 回答