UUID
UUID(通用唯一标识符)数据类型存储128位值,该值在空间和时间上都是唯一的。要自动生成唯一行ID,我们建议使用带有gen_random_uuid()函数的UUID作为默认值。有关详细信息,请参阅下面的示例
语法
可以使用以下格式表示UUID值:
- 标准RFC4122指定的格式
连字符分隔的8,4,4,4,12个十六进制数字组。
示例: acde070d-8c4c-4f0d-9d8a-162843c10333
- 带大括号
标准RFC4122指定带有大括号的格式。
示例: {acde070d-8c4c-4f0d-9d8a-162843c10333}
- 字节格式
UUID值指定为字节。
示例: b’kafef00ddeadbeed’
- 用作URN
UUID可以用作统一资源名称(URN)。在这种情况下,格式指定为“urn:uuid:”后面跟着标准的RFC4122指定格式。
示例: urn:uuid:63616665-6630-3064-6465-616462656564
UUID值的宽度为128位,但由于ZNBASE元数据因素,总存储大小可能会更大。
类型转换
UUID值可以转换为BYTES类型的数据。需要支持的字节字符串格式,例如,b’\141\061\142\062\143\063’。
示例
示例1:以标准RFC4122指定格式创建具有UUID的表:
CREATE TABLE v (token uuid);
INSERT INTO v VALUES (‘63616665-6630-3064-6465-616462656562’);
SELECT * FROM v;
token
+———————————————————+
63616665-6630-3064-6465-616462656562 |
示例2:使用带大括号的格式创建具有UUID的表:
INSERT INTO v VALUES (‘{63616665-6630-3064-6465-616462656563}’);
SELECT * FROM v;
token
+———————————————————+
63616665-6630-3064-6465-616462656562 63616665-6630-3064-6465-616462656563
示例3:使用字节格式创建具有UUID的表
INSERT INTO v VALUES (b’kafef00ddeadbeed’);
SELECT * FROM v;
token
+———————————————————+
63616665-6630-3064-6465-616462656562
63616665-6630-3064-6465-616462656563
6b616665-6630-3064-6465-616462656564
示例4:使用用作URN创建具有UUID的表
INSERT INTO v VALUES (‘urn:uuid:63616665-6630-3064-6465-616462656564’);
SELECT * FROM v;
token
+———————————————————+
63616665-6630-3064-6465-616462656562
63616665-6630-3064-6465-616462656563
6b616665-6630-3064-6465-616462656564
63616665-6630-3064-6465-616462656564
示例5:使用带有gen_random_uuid()函数的UUID列作为默认值,来创建创建一个包含自动生成的唯一行ID的表user:
CREATE TABLE users (id UUID NOT NULL DEFAULT gen_random_uuid(), name STRING, PRIMARY KEY(id, name));
CREATE TABLE
INSERT INTO users(name) VALUES (‘小蓝’), (‘小红’), (‘小白’);
INSERT 3
SELECT * FROM users;
id | name
+———————————————————+———+
8a4271fb-3e5a-46bd-9c13-fe18d4ad255e | 小红
ab8f2a97-a893-4593-be2c-7743bfec43aa | 小白
b1f354ff-a8e0-42f5-9db3-445f21f38fa1 | 小蓝
示例6:使用带有uuid_v4()函数的BYTES列作为默认值,来创建创建一个包含自动生成的唯一行ID的表user2:
CREATE TABLE users2 (id BYTES DEFAULT uuid_v4(), name STRING, PRIMARY KEY(id, name));
CREATE TABLE
INSERT INTO users2(name) VALUES (‘小蓝’), (‘小红’), (‘小白’);
INSERT 3
SELECT * FROM users2;
id | name
+———————————————————————————+———+
\377\035\237\024\200I\256\262+\236\011u\004\251C | 小白
\007\311\374\310\351L\014\217\341J\341h\261\024\373 | 小蓝
\316P\302\027&1B\216\234O\270”\351/\217^ | 小红
无论是示例5还是示例6,生成的ID都是128位,几乎没有机会生成非唯一值。此外,一旦表超出单个键值范围(默认情况下超过64MB),新的ID将散布在表的所有范围内,因此可能散布在不同的节点上。这意味着多个节点将分担负载。这种方法的缺点是创建一个主键,该主键在直接查询中可能没有用,这可能需要与另一个表或辅助索引联接。
如果将生成的ID存储在相同的键值范围内很重要,则可以显式地或通过SERIAL伪类型将整数类型与unique_rowid()函数用作默认值,示例如下:
示例7:使用unique_rowid()函数用作默认值:
CREATE TABLE users3 (id INT DEFAULT unique_rowid(), name STRING, PRIMARY KEY(id, name));
CREATE TABLE
INSERT INTO users3(name) VALUES (‘小蓝’), (‘小红’), (‘小白’);
INSERT 3
SELECT * FROM users3;
id | name
+——————————+———+
519264430636171265 | 小蓝
519264430636269569 | 小红
519264430636302337 | 小白
在执行insert操作的过程中,unique_rowid()函数会根据执行insert节点的时间戳和ID生成默认值。 除在每个节点每秒生成超大量ID(100,000+)的这种情况以外,这种时间排序的值几乎是全局唯一的。同样,可能存在差距,不能完全保证顺序。