SQLITE中是否有UID数据类型?如果有,那么如何生成该值?

44

我正在创建这样的表格:

CREATE TABLE foobar (id uniqueidentifier, foo text, bar text, PRIMARY  KEY (id))

如何在表foobar中插入或生成id字段的值?

5个回答

74

你可以认为SQLite根本不支持任何数据类型。在SQLite3中,例如可以这样做。

sqlite> create table test (id wibblewibble primary key);

SQLite可以愉快地创建具有“数据类型”wibblewibble的列。SQLite还可以愉快地创建具有“数据类型”uuid、guid和SuperChicken的列。

对于您来说,关键点可能是如何自动生成uid。在这方面SQLite帮不上什么忙。

您可以完全由客户端程序决定。如果您使用python编程,请使用uuid模块。在ruby中,您可以使用SecureRandom.uuid函数。其他语言也有类似的功能或解决方法。

您可以在C中编写自己的uid生成函数。 (请参见创建或重新定义SQL函数。)我认为这是相对极端的方法。

您可以将其以二进制文本格式存储。


在线上的其他讨论中,人们普遍存在对UUID的误解。 UUID不仅仅是一个128位的随机数。 UUID具有结构和规则。 请参见RFC 4122


3
感谢你的帮助。我这样为 Android 应用程序生成 UUID:String sUUiDValue=UUID.randomUUID().toString();然后将其插入到表中... - Pranita Patil

24

Benjamin Berry的答案是不正确的,它会产生格式不正确的UUIDUUID,但它展示了一种有趣的技术,使用子查询生成随机数,然后从中选择子字符串。这里有一个类似的东西,我确认它可以工作:

select substr(u,1,8)||'-'||substr(u,9,4)||'-4'||substr(u,13,3)||
  '-'||v||substr(u,17,3)||'-'||substr(u,21,12) from (
    select lower(hex(randomblob(16))) as u, substr('89ab',abs(random()) % 4 + 1, 1) as v);

一些示例输出:

c71122df-18e4-4a78-a446-fbf7b8f2969b
61e75f87-978b-4d9e-b587-bedcc2d23898
30eee0fa-2ff2-4ff5-b8ef-f99378272999

2
对我来说,它为我的迁移从一个表复制到另一个表创建了20个完全相同的UUID(在这里我将_id从int更改为此UUID)。 - miroslavign
2
与@miroslavign相同,如果在一个请求中用于更新所有表记录,例如,为每个记录生成完全相同的uuid。 - fharreau
1
如果您想为每行创建随机uuid,我制作了一个小混合。字符串u =“lower(hex(randomblob(16)))”;字符串v =“substr('89ab',abs(random())%4 + 1,1)”; rawquery =“update table set guid = substr(”+ u +“,1,8)||'-'||substr(”+ u +“,9,4)||'-4'||substr(”+ u +“,13,3)||'-'||”+ v +“||substr(”+ u +“,17,3)||'-'||substr(”+ u +“,21,12) ”); - P. Sohm
2
这与时间、种子或毫秒无关(伪随机生成器不会在每次调用时播种),表达式只由SQLite评估一次。查询中没有任何地方要求多个值,您只是说要多次使用它,因此SQLite使用一个满足您请求的值。请记住,SQL不是命令式的,因此更新/选择不一定是循环。 - remram
1
这个例子中存在一个严重的缺陷。当在更新或多行插入中包含在“set var=formula”中时,优化会将公式计算一次作为优化。因此,所有行都获得相同的值,这可能不是期望的效果。我添加了一个“random()*rowid”,现在每一行都被单独计算。即使是一个16位数字的随机数,仍然存在重复值失败的潜在风险。 - Richard
显示剩余2条评论

22

这里有类似的内容可以直接用作表达式:

lower(hex(randomblob(4))) || '-' || lower(hex(randomblob(2))) || '-4' || substr(lower(hex(randomblob(2))),2) || '-' || substr('89ab',abs(random()) % 4 + 1, 1) || substr(lower(hex(randomblob(2))),2) || '-' || lower(hex(randomblob(6)))

例如,作为列的默认值传递:

sqlite> create table "table" (
  "id" char(36) default (lower(hex(randomblob(4))) || '-' || lower(hex(randomblob(2))) || '-4' || substr(lower(hex(randomblob(2))),2) || '-' || substr('89ab',abs(random()) % 4 + 1, 1) || substr(lower(hex(randomblob(2))),2) || '-' || lower(hex(randomblob(6)))), 
  "data" varchar(255), primary key ("id")
);

sqlite> insert into "table" ("data") values ('foo');
sqlite> insert into "table" ("data") values ('bar');
sqlite> select * from "table";
947efcc9-4212-442a-b68c-eb6fbd8a7128|foo
a2c3857b-1eb4-40bd-aed2-6e8d68cc2ab8|bar

2
这里发生了什么:substr('89ab',abs(random()) % 4 + 1,1) - scape
5
它选择下一个要放置的字符是'8'、'9'、'a'或'b'。它来自UUID规范,并说明这是UUID变体1。https://en.wikipedia.org/wiki/Universally_unique_identifier#Variants - Mikael Lepistö

1
需要这个项目的内容。
select SUBSTR(UUID, 0, 8)||'-'||SUBSTR(UUID,8,4)||'-'||SUBSTR(UUID,12,4)||'-'||SUBSTR(UUID,16)
from (
select lower(hex(randomblob(16))) AS UUID 
);

9
不幸的是,这会生成格式不正确的UUID,例如:284e630-2293-bea6-21b1095ac11fe4f04。它的第一组应该有8个字符,第三组应该有4个字符,最后一组应该有12个字符。此外,UUID版本位应为4,而非随机的。 - Tim Ruddick

0
我创建了一个用户定义的函数(用于在我的C#应用程序中生成guid/uuid列的默认值)。
var connection = new SqliteConnection("DataSource=:memory:");
connection.CreateFunction("newid", Guid.NewGuid); 

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