4 年前,我在 SO 上回答了一个问题,“如何为每一行批量设置 UUID”。
我试了之后回答
UPDATE table SET uuidcol = UUID();
它对我有用,但大约一半(似乎)的人报告说它不起作用,说所有行的 ID 都是相同的。
所以今天,我再次尝试,每次删除列,并创建一个具有新类型的新列,例如
text, char(36), varchar(36)
它再次起作用,每次都为每行创建一个唯一的 UUID。
是什么让它对其他人不起作用?
比如发动机?(在 MySQL 5.7 上使用 InnoDB)
编辑
做了另一个测试
- 创建一个简单
t
的表uu varchar(36)
uu
插入10,000,000行null
- 做了
UPDATE t SET uu=UUID();
并且所有 10M 行都有不同的唯一UUID。
我现在有这个完全相同的问题。
我编写了一个示例 java 应用程序来演示该问题:
MariaDBTestUUID.java:
客户端库的版本在这里设置:
构建.gradle:
要运行测试应用程序,只需:
1 - 连接到每个数据库并运行以下查询:
2 - 替换出于安全原因屏蔽的连接信息并在每个数据库上运行它。
3 - 在 build.gradle 中设置要在测试中使用的 mariadb 客户端版本
4 - 运行 main()
如果输出为每个不同的查询显示 3,则更新 stmt 在每列中创建了不同的值。如果显示为 1,则更新为该列的所有行设置相同的值。查询都应该返回 3。
我所看到的,对于所有数据库:
所以,到目前为止我的发现:
在 mariadb 客户端库的 2.2.3 版本之前,一切都没有问题(每行中的所有列都设置了不同的值)。
replace(uuid(),'-', '')
从版本 2.2.4 开始,它开始为我们设置为使用单个更新语句的列的每一行设置相同的值。其他几个 mariadb 客户端版本也会发生这种情况,包括最新的 (2.7.0)。该问题与 REPLACE() 函数有关,或者与更新中的函数调用嵌套有关。这绝对不是由函数 UUID() 引起的。
这个问题同样发生在 MySQL 5.7.22(本地安装在我的环境中)、MySQL 5.7.30(测试 docker 容器),更重要的是 Aurora DB (MySQL 5.6.10)。
-------------------------------------------------- - 编辑 - - - - - - - - - - - - - - - - - - - - - - - - -----
对我来说,这是由以下因素的结合引起的:
将 CONVERT() 添加到图片中解决了它:
UPDATE sometable SET uuid=UNHEX(REPLACE(CONVERT(UUID() using utf8mb4), '-', '')) WHERE uuid IS NULL;
有关更多详细信息(和赞成票):https ://stackoverflow.com/a/51393124/5154619
我在 9 版本的 MySQL/MariaDB 上试过这个:
每个版本有4 个不同的行,因此有 4 个不同的 uuid。
如果您有生成相同uuid 的代码,那么您在做什么不同?
在 mysql中实现和定义的问题
uuid()
在于它并不是真正随机生成的,因此可能会发生冲突,尤其是在批量执行时。更好的是使用 uuid v4,它保证了整个过程的随机性,请参阅实现https://stackoverflow.com/a/32965744/5193536它有点慢。