如果我在SQLite中使用BLOB字段作为主键,会遇到性能问题吗?

14

我有一个SQLite数据库,其中所有主键都是GUID。目前它们被存储为固定长度的字符串,但我想将它们作为BLOB存储,因为这简化了存储和检索数据的代码。我已经转换了部分数据库,一切正常运行。但是,我不确定是否会遇到性能问题。

例如,像这样的语句在字符串上比在BLOB上更快吗?

SELECT * FROM table1 t1, table2 t2 WHERE t1.id = t2.parent_id

我的直觉告诉我不行,但这并不真正意味着什么。


3
我的直觉告诉我是的,但那并不意味着什么。 - Dominic Rodger
1
SQLite可以对Blob类型进行索引吗? - KM.
3个回答

13

最好的方法是使用分析器/SQLite定时器运行查询。设置一个测试,使用字符串运行查询1000次,然后使用blob 1000次运行查询。获胜者是最快的。

直觉和硬数据是两回事。


3
也尝试使用二进制格式,这比文本字符串更适合您的 GUID 数据。 - finnw
10
多米尼克:你做了这个吗?你的结果是什么? - Ztyx
3
我运行了这种类型的测试(通过Qt的sqlite驱动程序sqlite3),并且搜索36个字符的UUID字符串比相应的16字节紧凑UUID blob慢约4%。我更喜欢字符串版本,因为它更容易调试。 - jmalmari
11
回答不错,但并不是很有价值。被接受的事实表明实验已经被进行了(由问题的作者@lawrence-barsanti执行),如果实验已经进行了,那么分享结果非常值得期待! :-) - Ivan
对于任何想知道的人,我使用Python 3和SQLite3编写了这个测试:https://gist.github.com/caioariede/7d765aa37241e1ccd56d5bc1631a3d18 - caio
请查看以下链接以获取数据: https://stackoverflow.com/questions/11337324/how-to-efficient-insert-and-fetch-uuid-in-core-data/11337522#11337522 - undefined

1

我认为如果我是你的话,我会将GUID存储在SQLITE的两个整数类型中(SQLITE INTEGER是64位)。

然而,在这种情况下,blob可能实际上效果更好。

LFSR是对的,进行性能分析。


-6

为什么不应该使用它

主键通常是索引并用于排序的。 BLOB 无法进行索引,这使它成为所有数据类型中最慢的。实际上,它是最糟糕的选择,作为主键,包括 SQL99 标准在内的大多数数据库都不允许使用。

BLOB 的问题在于数据库不知道它的数据类型(BLOB 只适用于任何未定义的东西,比如标志、图像、Word 文档等只能存储为二进制数据)。因此,它无法进行优化。另一个问题是显示。BLOB 不能简单地显示为文本。

大多数 SQL 实现不允许比较 BLOB 字段,但 SQLite 允许。然而,它会将您要比较的任何内容转换为 BLOB,然后逐位进行比较。

最佳替代方案

在SQLite中,主键列的最佳选项是使用 INTEGER PRIMARY KEY ,如此处所述:http://www.sqlite.org/lang_createtable.html#rowid它提供了最佳性能(它已经作为 rowid 列存在,只是别名)。

结论

回答你的问题:是的,它会严重影响性能。但更重要的是,它将使您很难管理表格。使用 INTEGER PRIMARY KEY ,确实是最好的选择,可以保证唯一性并具有极快的速度。


31
实际上,SQLite中的BLOB可以被索引。 - finnw
7
关于为什么会有人想这样做的问题......您可以使用包含两个BLOB键和值的表格,将SQLite用作简单的NOSQL数据库。此外,有许多情况下,您希望将哈希代码存储在索引列中的表格中。如果没有可索引的“二进制”类型,人们通常会将哈希代码存储为十六进制(或base64)编码的字符串。这很好,但它浪费了空间。 - Paul Groke
1
虽然我不同意Abel的推理,但我认为他的答案是正确的。在我看来,最好的解决方案是在表上有一个INTEGER PRIMARY KEY和一个BLOB上的唯一索引。INTEGER PRIMARY KEY使用SQLite的内部ROWID,提供了一种快速访问和操作数据的方式。 - Kevin Delaney
3
@KevinDelaney 这个方法吸引人的主要原因是,很常见的一种主键类型是 UUID。如果你能将 UUID 以数字形式而非字符串形式存储,你可以节省9倍的空间。 - chacham15
5
IP地址、哈希值、全局唯一标识符等都是可以作为索引的良好二进制数据。 - jjxtra
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接