我有一个7.4Gb的csv文件。将其转换为带有python script的sqlite数据库后,输出DB为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个字节。
所以看起来转换为整数会使存储效率降低,而且我所有的收益都会减少每行中存储的字符数。
答案 0 :(得分:28)
SQLite没有运行压缩算法,但它会将数据存储在二进制文件而不是文本文件中。这意味着可以更有效地存储数据,例如使用32位(4字节)数字来表示10,000,000
,而不是将其存储为8字节的文本(如果文件是unicode,则存储更多)。 / p>
如果您有兴趣,请参阅SQL Database File Format的详细信息。
这有意义吗?
答案 1 :(得分:17)
默认情况下,SQLite不压缩它写入磁盘的数据;但是,SQLite确实有一套"专有扩展"为此和其他目的。在链接中查找ZIPVFS
,如下所示。
http://www.sqlite.org/support.html和 http://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);
See the Date and Time functions
请注意上面SQL中的CAST
指令:SQLite不会对列强制执行类型,因此您可能将一组数字存储为字符串;增加你的字段大小超过必要(这也会使某些查询表现得很奇怪)。
还有一件事:场地大小不是故事的唯一部分。请记住,索引占用空间,整数索引更有效 - 就磁盘大小和性能而言。
答案 2 :(得分:1)
我的GIT存储库中有一个很大的SQLite文件,我想知道为什么我的存储库总大小没有增长那么大,而是比我的SQLite-.db
文件小。事实证明,GIT默认情况下会压缩存储库。快速检查我的.db
文件也表明了这一点,因为压缩.db
文件会导致zip归档文件,压缩文件的大小仅为.db
文件的20%。
因此,至少在默认设置下,SQLite看起来不是以压缩方式存储数据。但是,无论如何,最好将一个较大的SQLite文件添加到GIT存储库中,因为GIT会自动执行压缩。