我不明白为什么
SELECT UUID();
返回类似的内容:
3f06af63-a93c-11e4-9797-00505690773f
但是如果我将它插入二进制(16)字段(UUID()函数)并使用例如BEFORE INSERT触发器并运行select,它将返回如下内容:
0782ef48-a439-11
请注意,这两个UUID不是相同的数据。
我意识到二进制文件和一个UUID字符串看起来不一样,但是所选数据不应该同样长吗?否则,它怎么可能同样具有独特性?
将它存储为char(36)更好吗?我只需要它是唯一的,以防止重复插入。它永远不会被选中或用于连接。
编辑:
触发之前的就像:
BEGIN
if NEW.UUID IS NULL THEN
NEW.UUID = UUID();
END IF
END
答案 0 :(得分:50)
所以,作为对评论的回应。将36-char UUID存储为二进制(16)的正确方法是以下列方式执行插入:
INSERT INTO sometable (UUID) VALUES
(UNHEX(REPLACE("3f06af63-a93c-11e4-9797-00505690773f", "-","")))
UNHEX
因为UUID已经是一个hexed值。我们修剪(REPLACE
)语句中的短划线,使长度减少到32个ASCII字符(我们的16个字节表示为HEX
)。显然,您可以在存储之前随时执行此操作,因此不必由数据库处理。
您可以像这样检索UUID:
SELECT HEX(UUID) FROM sometable;
以防万一有人遇到这个帖子并且不确定这是如何运作的。
请记住:如果您使用UUID选择行,在条件上使用UNHEX()
:
SELECT * FROM sometable WHERE UUID = UNHEX('3f06af63a93c11e4979700505690773f');
而不是HEX()
列:
SELECT * FROM sometable WHERE HEX(UUID) = '3f06af63a93c11e4979700505690773f';
第二个解决方案虽然有效,但要求MySQL HEX
使用所有UUID,然后才能确定哪些行匹配。效率非常低。
编辑:如果你正在使用MySQL 8,你应该看看SlyDave的答案中提到的UUID功能。这个答案仍然是正确的,但它并没有优化UUID索引,这些索引可以使用这些函数本地完成。
答案 1 :(得分:18)
从MySQL 8开始,您可以使用两个新的UUID functions:
BIN_TO_UUID
SELECT BIN_TO_UUID(uuid, true) AS uuid FROM foo;
-- 3f06af63-a93c-11e4-9797-00505690773f
UUID_TO_BIN
INSERT INTO foo (uuid) VALUES (UUID_TO_BIN('3f06af63-a93c-11e4-9797-00505690773f', true));
此方法还支持重新排列uuid的时间组件以增强索引性能(通过按时间顺序排序),只需将第二个参数设置为true - 这仅适用于UUID1。
如果您使用true
UUID_TO_BIN
标记来建立索引性能(推荐),则还必须在BIN_TO_UUID
上设置它,否则它将无法正常转换。
有关详细信息,请参阅文档。
答案 2 :(得分:4)
我正在使用MariaDB,因此BIN_TO_UUID
函数系列不存在。无论如何,我设法得到了相应的值。
bin - >十六进制
这里,uuid
是uuid的二进制(16)值;你将使用下面的值来选择它的可读版本。
LOWER(CONCAT(
SUBSTR(HEX(uuid), 1, 8), '-',
SUBSTR(HEX(uuid), 9, 4), '-',
SUBSTR(HEX(uuid), 13, 4), '-',
SUBSTR(HEX(uuid), 17, 4), '-',
SUBSTR(HEX(uuid), 21)
))
hex - >仓
这里,cc6e6d97-5501-11e7-b2cb-ceedca613421
是UUID的可读版本,您将在WHERE子句中使用下面的值来寻找它。
UNHEX(REPLACE('cc6e6d97-5501-11e7-b2cb-ceedca613421', '-', ''))
干杯
答案 3 :(得分:2)
其他答案是正确的。 UUID()
函数返回一个36个字符串,需要使用显示的函数(UNHEX()
或在新平台上的UUID_TO_BIN()
)进行转换。
但是,如果您使用自己的软件来创建UUID,则可以改用Hexadecimal Literal notation。
因此,我将对MySQL UUID()
函数使用以下内容:
INSERT INTO sometable (id) VALUES (UNHEX(REPLACE(UUID(), '-', ''))); -- all versions
INSERT INTO sometable (id) VALUES (UUID_TO_BIN(UUID()); -- since v8.0
但是如果我生成自己的UUID,请使用它;
INSERT INTO sometable (id) VALUES 0x3f06af63a93c11e4979700505690773f;
类似地,您可以在WHERE
子句中使用十六进制文字:
SELECT * FROM sometable WHERE id = 0x3f06af63a93c11e4979700505690773f;
如果您不必每次都将数据转换为UUID字符串,则会更快。
注意:'x'
中的'0xaBc
区分大小写。但是,十六进制数字不是。
答案 4 :(得分:2)
针对BIN_TO_UUID和针对MySQL 5的UUID_TO_BIN的填充:
DELIMITER $$
CREATE FUNCTION BIN_TO_UUID(b BINARY(16))
RETURNS CHAR(36)
BEGIN
DECLARE hexStr CHAR(32);
SET hexStr = HEX(b);
RETURN LOWER(CONCAT(
SUBSTR(hexStr, 1, 8), '-',
SUBSTR(hexStr, 9, 4), '-',
SUBSTR(hexStr, 13, 4), '-',
SUBSTR(hexStr, 17, 4), '-',
SUBSTR(hexStr, 21)
));
END$$
CREATE FUNCTION UUID_TO_BIN(uuid CHAR(36))
RETURNS BINARY(16)
BEGIN
RETURN UNHEX(REPLACE(uuid, '-', ''));
END$$
DELIMITER ;
答案 5 :(得分:-1)
在 MySQL 4.0 及更高版本中,您可以像使用 MID 一样更改 UUID 的大小
SELECT MID(UUID(),1,32); # 32 characters long UUID
SELECT MID(UUID(),1,11); # 11 characters long UUID
正如@nickdnk 指出的那样,您不应该这样做。 UUID 的总长度使它们独一无二。将其中的一部分条带化可能会导致非唯一值。