【发布时间】:2013-09-23 07:46:41
【问题描述】:
是否可以在 SQLITE 数据库中使用 GUID 作为主键?如果可以,可以使用哪种数据类型?
【问题讨论】:
标签: android sqlite primary-key guid uuid
是否可以在 SQLITE 数据库中使用 GUID 作为主键?如果可以,可以使用哪种数据类型?
【问题讨论】:
标签: android sqlite primary-key guid uuid
SQLite 本身不支持 GUID 作为内部类型。
除此之外,确实如此! (有点)。请记住,在 SQLite 中,任何字符串都可以用作类型名称,包括 GUID 或 UUID(阅读有关 SQLite datatypes 的更多信息)。
根据这些规则,GUID 类型具有亲和性NONE,这与BLOB 字段相同。考虑到这一点,您可以创建GUID 类型的列,并使用以下规则访问它:
将其存储为类似X'01020304050607080910111213141516' 的字符串(X 表示法用于表示16 字节BLOB 值)。
要插入,请使用:
INSERT INTO mytable (uuid)
VALUES (X'01020304050607080910111213141516');
将其读取为 16 字节 BLOB。 quote(uuid) 可用于使用 X 表示法格式化输出:
SELECT quote(uuid)
FROM mytable
这样的列也可以用作主键。不幸的是,没有像整数主键那样的 AUTOINCREMENT 功能——你必须自己处理它。你可以使用像randomblob(16) 这样简单的东西,但它并不完全是UUID 所定义的by standard。
令人困惑的是,您还可以将 UUID 的文本表示形式存储在同一字段中(SQLite 不会阻止您这样做),但它至少会占用 2 倍以上的空间:BLOB 是 16 个字节,UUID 作为文本至少是32 字节。
【讨论】:
{04030201-0605-0807-0910-111213141516} 形式的 GUID(本地生成或从服务器接收)时,您需要在插入 SQLite 之前将其格式化为X'01020304050607080910111213141516'。
sqlite3 本身没有原生 UUID 128 位格式。
但是,GUID 可以作为TEXT 或二进制BLOB 表示形式在SQLite 中用作键。
根据在回答类似问题时发布的性能数据,二进制和字符串 UUID 在 SQLite 中对于创建和查询索引时都非常有效。
见表:https://stackoverflow.com/a/11337522/3103448
SQLite 可以使用 randomblob(16) 和 hex(X) 生成 BLOB 或 TEXT 128 位随机数,例如:lower(hex(randomblob(16)))
在相似的索引性能的情况下,一个重要的权衡是人类可读的字符串是否更适合较小的二进制数据大小。
注意:SQLite Release 3.31.0 on 2020-01-22 添加了 uuid.c 扩展模块实现处理 RFC-4122 UUID 的功能。
uuid() // generate a version 4 UUID as a string
uuid_str(X) // convert a UUID X into a well-formed UUID string
uuid_blob(X) // convert a UUID X into a 16-byte blob
否则,对于 RFC 4122 UUID(随机)4 类合规性,请执行以下操作:
根据 RFC 4122 第 4.4 节调整某些位,如下所示:
一个。将第 7 个字节的最高 4 位设置为 0100'B,因此高半字节为“4” 湾。将第 9 个字节的两个最高有效位设置为 10'B,因此高半字节将是“8”、“9”、“A”或“B”之一
【讨论】: