MySql UUID重复BUG

时间:2012-03-17 13:56:58

标签: mysql duplicates uuid

我在MySql 5.5.19中发现了一个错误。

执行时:

select uuid(), uuid();

你得到两个等于id。

当我将两个uuids插入我的桌子时,我遇到了两个这个bug,我总是得到相同的值。

有没有其他人在这两个错误中运行?如何为我的键执行需要两个uuids的插入命令?

修改

实际上我错了,他们在一位数上是不同的,所以很难看到

  

c3db913的 7 -705e-11e1的-ae17-1c6f6531b785
  c3db913的˚F -705e-11e1的-ae17-1c6f6531b785

5 个答案:

答案 0 :(得分:9)

我坚信你没有得到重复的值,而是一些几乎相同的值(可能是1个不同的字符)。由于UUID的第一个块是从时间戳(以毫秒为单位)生成的,这意味着函数在相同的毫秒内执行(你是在超级计算机上运行吗?),说实话,这是不太可能的。 如果你真的得到重复,那么运行两个单独的SELECT uuid()查询并使用你想要的查询中返回的值

答案 1 :(得分:6)

From the docs UUID被设计为在空间和时间上全局唯一的数字。由于查询是在执行之前编译的,因此您在两次调用UUID()同一时刻。因此,您不能指望它在同一查询中返回两个唯一值,因为两个值都使用相同的时间戳。这对我来说听起来像是预期的行为。

答案 2 :(得分:2)

这不是uuid()函数的错误

出现意外结果是因为当您的字符集客户端和字符集结果不是utf8时发生了明确转换;

1 uuid()输出是utf8,无论您的字符集是什么;

2当您的字符集客户端和字符集结果具有比utf8高的优先级(例如utf8mb4)时,则会发生不明确的转换,而其他优先级较低的字符集(如latin1)则可以正常工作;

3显式转换将在sql执行之前将uuid()转换为常量字符串,因此在sql执行完成之后,相同的uuid()返回

您可以查看所有这些事情,方法是使用解释扩展+您的子句,然后使用显示警告;

如何解决? 1次从隐式转换到显式转换 例如 : 设置名称utf8mb4; replace(convert(uuid()using utf8mb4),'-','')

设置名称utf8mb4; replace(uuid(),_ utf8'-',_ utf8'')

2不明转换 例如:设置名称utf8

enter link description here

答案 3 :(得分:0)

我遇到了同样的问题,因为mysql正在创建uuid_v1,除了使用不同类型的uuid之外别无他法。我尝试使用uuid_v4使用随机数生成uuid。它运行得很好,你也可以在迁移到uuid后改回uuid_v1,我希望它有所帮助

-- Change delimiter so that the function body doesn't end the function 
declaration
DELIMITER //

CREATE FUNCTION uuid_v4()
    RETURNS CHAR(36)
BEGIN
    -- Generate 8 2-byte strings that we will combine into a UUIDv4
    SET @h1 = LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0');
    SET @h2 = LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0');
    SET @h3 = LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0');
    SET @h6 = LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0');
    SET @h7 = LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0');
    SET @h8 = LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0');

    -- 4th section will start with a 4 indicating the version
    SET @h4 = CONCAT('4', LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'));

    -- 5th section first half-byte can only be 8, 9 A or B
    SET @h5 = CONCAT(HEX(FLOOR(RAND() * 4 + 8)),
                LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'));

    -- Build the complete UUID
    RETURN LOWER(CONCAT(
        @h1, @h2, '-', @h3, '-', @h4, '-', @h5, '-', @h6, @h7, @h8
    ));
END
//
-- Switch back the delimiter
DELIMITER ;

The code is taken from here

答案 4 :(得分:0)

这是MySQL 5.6 / 5.7中的错误(已在8.0中更正)。 MariaDB没有此错误。 错误已在此处填充:https://bugs.mysql.com/bug.php?id=101820 正如@ user1862341所解释的,这是由于转换不明确造成的,但这仍然是一个错误