在 SQLite 表中使用文本作为主键不好?
Posted
技术标签:
【中文标题】在 SQLite 表中使用文本作为主键不好?【英文标题】:Using text as a primary key in SQLite table bad? 【发布时间】:2014-04-18 15:40:24 【问题描述】:在 SQLite 数据库中将文本作为主键是不是很糟糕?我听说由于性能原因这很糟糕,这是真的吗?在这种情况下,rowid 会被用作实际的主键吗?
【问题讨论】:
【参考方案1】:在 SQLite 数据库中将文本作为主键是不是很糟糕?听说性能不好,这是真的吗?
从正确性的角度来看,TEXT PRIMARY KEY
是可以的。
从性能的角度来看,更喜欢INTEGER
键。但与任何性能问题一样,请自行衡量,看看您的数据和用例是否存在显着差异。
在这种情况下,rowid 会被用作实际的主键吗?
只有INTEGER PRIMARY KEY
与ROWID
有别名。其他类型的主键没有,除非指定WITHOUT ROWID
,否则会有隐式整数rowid。 Reference.
【讨论】:
那么隐含的rowid是干什么用的? 为了清楚起见,您能否明确说明是否是 TEXT 主键引用的隐式 rowid?【参考方案2】:在现实世界中,如果我们谈论 UUID,使用字符串作为主键有很多好处。能够在创建实体“护照”时准确地创建它可以大大简化异步代码和/或分布式系统(如果我们谈论的是更复杂的移动客户端/服务器架构)。
在性能方面,我在运行基准以执行 10000 次主键查找时没有发现任何可衡量的差异,因为实际上,数据库索引在运行索引搜索时既不存储也不比较字符串。
【讨论】:
我会说 UUID 由有限数量的符号 (VARCHAR) 组成。所以它有点多字节整数,你可以把它看成是对 char, word, int, long,.... 【参考方案3】:是的,如果你使用 TEXT,你会得到 android.database.sqlite.SQLiteConstraintException:唯一约束失败:TableName.ColumnName(代码1555)
如果此插入成功,SQLite 具有要插入的会话并返回最后插入的行的行 ID。 否则将返回 -1。
return 被映射到 _ID ,这就是他们强制你为表接口 BaseColumns 的原因
很奇怪,插入调用必须返回 rowid,而不是布尔值左右
我希望 SQLite 中有 TEXT PRIMARY KEY 功能
【讨论】:
【参考方案4】:PRIMARY KEY 类型的字段意味着比较值。比较数字比比较文本更简单。
原因是64位数值比较有专门的汇编指令。这总是比比较理论上可以无限大小的文本快得多。
比较数字的例子:
CMP DX, 00 ; Compare the DX value with zero
JE L7 ; If yes, then jump to label L7
.
.
L7: ...
在此处阅读有关CMP
汇编指令的更多信息:https://www.tutorialspoint.com/assembly_programming/assembly_conditions.htm
知道这一点让我们知道数字总是更具表现力(至少在我们今天拥有的计算中)。
【讨论】:
【参考方案5】:在 SQLite 数据库中将文本作为主键是不是很糟糕?我听说 出于性能原因,这很糟糕,这是真的吗?
我从未听说有人在表中使用字符串作为主键。对我来说(老实说,我也希望对其他人)非常“丑陋”的做法,性能非常低。
如果您将使用字符串作为主键,您需要考虑“一些”事情:
3 个符号的组合就够了吗? 还是应该使用 5 个符号?在这里,每一行必须有相同的格式(当然是可读性问题)并且必须是唯一的。哦!下面是 "piggy work" ->
你需要创建一些 "unique string generator" 来生成唯一的1 字符串标识符2.
还有下一个问题值得考虑:
更长的字符串=
自动比较难比较
桌子的大小急剧增加,因为很明显
字符串的大小比数字大得多
行数 - 如果你使用字符串作为主键是很疯狂的
表可以有 1000+ 行
这是一个更复杂的主题,但我想说好的,对于非常小的表,可以使用字符串作为主键(如果它有意义的话),但如果你要看看缺点,它是更好的技术一定要用数字作为主键!
什么是结论?
我不建议你使用字符串作为主键。它有更多的缺点作为优点(它真的有一些优点吗?)。
使用数字作为主键要好得多(我不敢说最好)。
在这种情况下,rowid 会被用作实际的主键吗?
如果您将使用字符串作为主要不。
1真正的字符串很少是唯一的。
2当然,你可以说你可以从行中的项目名称创建标识符,但这又是意大利面条代码(项目可以具有相同的名称)。
【讨论】:
我的字符串来自服务器,保证是唯一的,并且总是设置长度改变这个答案的事实吗? @mpellegr 一般来说,使用字符串作为主键不是我在回答中写的好习惯;) 我即将创建一个表,该表有一个唯一的、索引的文本列,并且对该表的每个查询都将使用它来引用行。该表不打算用外键引用。当我想到这个问题时,我几乎只是从例程中添加了一个整数 ID 列,我为什么要这样做?那么,在这种特殊情况下,是否有任何理由创建 ID 列? 您是否能够测量与文本主键相关的“非常低的性能”?因为this question 的答案(除了SQLite 部分与当前的非常相似)没有提到这样的问题。 所有好的和有效的点,但有一个边缘情况,递增整数只会导致问题,即当您需要在多个设备和主数据存储之间保持数据同步时.而且 GUID 足够独特。以上是关于在 SQLite 表中使用文本作为主键不好?的主要内容,如果未能解决你的问题,请参考以下文章
使用 char(17) 作为主键在 SQL Server 的表中存储 VIN 号如何影响性能? [关闭]