我不明白为什么
SELECT UUID();
字符串
返回类似于以下内容的内容:
3f06af63-a93c-11e4-9797-00505690773f
型
但是,如果我用BEFORE INSERT触发器将它插入到一个二进制(16)字段(UUID()函数)中,然后运行select,它会返回如下内容:
0782ef48-a439-11
型
注意,这两个UUID不是相同的数据。
我意识到二进制和UUID字符串看起来并不相同,但所选数据至少应该一样长吧?否则它怎么可能是唯一的呢?
把它存储为char(36)更好吗?我只需要它是唯一的,以防止重复插入。它永远不会被选中或用于联接。
编辑:
触发器之前的代码如下:
BEGIN
if NEW.UUID IS NULL THEN
NEW.UUID = UUID();
END IF
END
型
6条答案
按热度按时间bqucvtff1#
作为对评论的回应。将36字符的UUID存储为二进制(16)的正确方法是以如下方式执行插入:
字符串
UNHEX
,因为UUID已经是十六进制值。我们修剪(REPLACE
)语句中的破折号,使长度减少到32个字符(我们的16个字节表示为HEX
)。显然,您可以在存储它之前的任何时候执行此操作,因此它不必由数据库处理。您可以像这样检索UUID:
型
以防万一有人遇到这个线程,并不确定这是如何工作的。
记住:如果您使用UUID选择一行,则在条件下使用
UNHEX()
:型
或者literal notation(正如Alexis Wilke所提到的):
型
且列上的NOT
HEX()
:型
最后一个解决方案,当它工作时,要求MySQL
HEX
在确定哪些行匹配之前es所有UUID。效率很低。编辑:如果你使用的是MySQL 8,你应该看看SlyDave的回答中提到的UUID函数。这个答案仍然是正确的,但它没有优化UUID索引,而UUID索引可以使用这些函数在本机完成。如果你使用的是< MySQL 8或MariaDB,你可以实现德文郡的polyfill,它提供了与以前版本的MySQL相同的功能。
c8ib6hqw2#
从MySQL 8开始,你可以使用两个新的UUID functions:
字符串
型
此方法还支持重新排列uuid的时间分量以增强索引性能(通过按时间顺序排序),只需将第二个参数设置为true -这只适用于UUID 1。
如果您使用
true
onUUID_TO_BIN
标志来提高索引性能(推荐),则还必须在BIN_TO_UUID
上设置它,否则它将无法正确转换回来。更多详细信息请参见文档。
bjg7j2ky3#
使用swap_flag参数对MySQL 5或MariaDB的BIN_TO_UUID和UUID_TO_BIN进行Polyfill。
字符串
其中包括来自www.example.com的SELECT示例https://dev.mysql.com/doc/refman/8.0/en/miscellaneous-functions.html#function_uuid-to-bin,这些示例表明上述代码返回的结果与8.0函数完全相同。这些函数被认为是确定性的,因为它们总是为给定的输入产生相同的输出。参见https://dev.mysql.com/doc/refman/8.0/en/create-procedure.html
axr492tv4#
我正在使用MariaDB,所以
BIN_TO_UUID
函数家族不存在。无论如何,我设法得到了相应的值。bin -> hex
这里,
uuid
是uuid的二进制(16)值;您将使用下面的值来选择它的可读版本。字符串
hex -> bin
这里,
cc6e6d97-5501-11e7-b2cb-ceedca613421
是UUID的可读版本,您将在WHERE子句中使用下面的值来查找它。型
干杯
aamkag615#
其他答案都是正确的。
UUID()
函数返回一个36个字符的字符串,需要使用所示函数(UNHEX()
,或者在较新的平台上,UUID_TO_BIN()
)进行转换。但是,如果您使用自己的软件创建UUID,则可以使用Hexadecimal Literal notation来代替。
因此,我会在MySQL
UUID()
函数中使用以下内容:字符串
但是在我生成自己的UUID的情况下使用它;
型
同样,你可以在
WHERE
子句中使用十六进制文字:型
如果您不必每次都将数据转换为UUID字符串,则会更快。
'0xaBc
中的'x'
区分大小写。然而,十六进制数字不是。*nc1teljy6#
在MySQL4.0及以上版本中,您可以像使用MID一样更改UUID的大小
字符串
正如@nickdnk指出的那样,你不应该这样做。UUID的总长度使它们唯一。对其中的一部分进行条带化可能会导致非唯一值。