是否可以在 SQLITE 数据库中使用 GUID 作为主键?如果可能,可以使用哪种数据类型?
2 回答
SQLite 本身不支持GUID
作为内部类型。
除此之外,确实如此!(有点)。请记住,在 SQLite 中,任何字符串都可以用作类型名称,其中包括GUID
或UUID
(阅读有关SQLite 数据类型的更多信息)。
根据这些规则,GUID
类型具有亲和力NONE
,这与BLOB
字段相同。考虑到这一点,您可以创建GUID
类型列,并使用以下规则访问它:
将其存储为类似字符串
X'01020304050607080910111213141516'
(X 表示法用于表示 16 字节BLOB
值)。要插入,请使用:INSERT INTO mytable (uuid) VALUES (X'01020304050607080910111213141516');
将其读取为 16-byte
BLOB
。quote(uuid)
可用于使用 X 表示法格式化输出:SELECT quote(uuid) FROM mytable
这样的列也可以用作主键。不幸的是,没有像整数主键那样的 AUTOINCREMENT 功能——你必须自己处理它。您可以使用如此简单的东西randomblob(16)
,但它并不完全符合标准UUID
的定义。
令人困惑的是,您还可以将 UUID 的文本表示形式存储在同一字段中(SQLite 不会阻止您这样做),但它至少会占用 2 倍以上的空间:BLOB 是 16 个字节,UUID 作为文本至少是 32 个字节。
sqlite3
本身没有原生 UUID 128 位格式。
但是,GUID 可以用作 SQLite 中的键,既可以是二进制表示也可以TEXT
是二进制BLOB
表示。
根据在回答类似问题时发布的性能数字,二进制和字符串 UUID 在 SQLite 中对于创建和查询索引时都可以有效。
见表:https ://stackoverflow.com/a/11337522/3103448
SQLite 可以使用 和 生成 BLOB 或 TEXT 128 位随机数,randomblob(16)
例如hex(X)
:lower(hex(randomblob(16)))
有了类似的索引性能,一个重要的权衡变成了人类可读的字符串是否更适合较小的二进制数据大小。
注意: 2020-01-22 的SQLite 版本 3.31.0 添加了 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 合规性,请执行以下操作:
- 生成 16 个随机字节(=128 位)
根据 RFC 4122 第 4.4 节调整某些位,如下所示:
一个。将第 7 个字节的最高 4 位设置为 0100'B,因此高半字节为“4” b。将第 9 个字节的两个最高有效位设置为 10'B,因此高半字节将是“8”、“9”、“A”或“B”之一