是否可以在 SQLITE 数据库中使用 GUID 作为主键?如果可能,可以使用哪种数据类型?
SQLite本身不支持GUID
作为内部类型。
除此之外,它确实如此!(有点)。请记住,在SQLite中,任何字符串都可以用作类型名称,其中包括GUID
或UUID
(阅读有关SQLite数据类型的更多信息)。
根据这些规则,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
此类列也可以用作主键。不幸的是,没有像整数主键那样的自动增量功能 - 您必须自己处理它。您可以使用像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 可以使用 randomblob(16)
和 hex(X)
生成 BLOB 或 TEXT 128 位随机数,例如: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 节调整某些位,如下所示:
a. 将第 7 个字节的四个最高有效位设置为 0100'B,因此高半字节为"4"b. 将第 9 个字节的两个最高有效位设置为 10'B,因此高半字节将是 "8"、"9"、"A" 或 "B" 之一