在MySQL中为现有数据生成GUID吗?


100

我刚刚将一堆数据导入到MySQL表中,并且有一列“ GUID”,我想基本上用新的和唯一的随机GUID填充所有现有行。

如何在MySQL中做到这一点?

我试过了

UPDATE db.tablename
  SET columnID = UUID()
  where columnID is not null

并且让每个领域都一样


2
我真的试过了,大多数字符都一样,但是生成的uuid有一些区别
xiaoyifang

是的,我确认,是一样的!
西里尔N.18年

它对我有用-差异很小,但确实存在。最快的检查方法是向列添加UNIQUE约束。
PSU

Answers:


88

我不确定这是否是最简单的方法,但是可以。这个想法是创建一个可以为您完成所有工作的触发器,然后执行查询以更新您的表,最后删除该触发器:

delimiter //
create trigger beforeYourTableUpdate  BEFORE UPDATE on YourTable
FOR EACH ROW
BEGIN
  SET new.guid_column := (SELECT UUID());
END
//

然后执行

UPDATE YourTable set guid_column = (SELECT UUID());

DROP TRIGGER beforeYourTableUpdate;

UPDATE 另一个不使用触发器,但需要主键或唯一索引的解决方案:

UPDATE YourTable,
INNER JOIN (SELECT unique_col, UUID() as new_id FROM YourTable) new_data 
ON (new_data.unique_col = YourTable.unique_col)
SET guid_column = new_data.new_id

再次更新:看来您的原始查询也应该工作(也许您不需要WHERE columnID is not null,所以不需要我所有的花哨代码。


是的,它甚至在5.0中也可以工作。但不要忘记放下扳机!
2011年

是的,肯定:)只是想知道我之后是否需要检查重复项,否则是否会为列中的每一行创建唯一值?
汤姆(Tom)

如果UUID实施正确(我相信是正确的),那么您应该能够创建唯一索引而无需检查重复项。
a1ex07 2011年

我用另一种可能也有用的方法更新了答案。
a1ex07 2011年

2
您的原始代码将起作用,只需将columnId = UUID()更改为columnId =(SELECT UUID())。对我来说很棒。所有生成的值几乎都相同,但每个值都是唯一的。
EJay 2012年

111

我需要在现有表中添加一个guid主键列,并用唯一的GUID填充它,而使用内部选择的更新查询对我来说很有效:

UPDATE sri_issued_quiz SET quiz_id=(SELECT uuid());

很简单 :-)


35
起初我以为这插入了重复的UUID,因为它们的开始和结束都相同,但是实际上它们稍有不同。
Sam Barnum

3
@SamBarnum因为UUID是基于计算机和时间戳生成的。作为需要花费毫秒才能运行的查询,它们确实确实必须非常接近……但绝不相同……向您保证的一件好事是UNIQUE向该列添加索引。
balexandre 2014年

2
相较于此,可接受的答案似乎有些过分!
Xtreme Biker

4
至少在mariadb(10.1.26)中,这似乎不起作用,因为每条记录都使用相同的uuid。
johanvdw

4
这为我在每条记录上生成了相同的UUID,大概是因为它在子查询中,而MySQL将首先执行内部查询并对所有行使用相同的值。要解决此问题,请删除子查询:UPDATE sri_issued_quiz SET quiz_id=uuid();
克里斯·怀特

22

批准的解决方案确实会创建唯一的ID,但乍一看它们看起来是相同的,只是前几个字符不同。

如果您想要明显不同的键,请尝试以下操作:

update CityPopCountry set id = (select md5(UUID()));


MySQL [imran@lenovo] {world}> select city, id from CityPopCountry limit 10;
+------------------------+----------------------------------+
| city                   | id                               |
+------------------------+----------------------------------+
| A Coruña (La Coruña)   | c9f294a986a1a14f0fe68467769feec7 |
| Aachen                 | d6172223a472bdc5f25871427ba64e46 |
| Aalborg                | 8d11bc300f203eb9cb7da7cb9204aa8f |
| Aba                    | 98aeeec8aa81a4064113764864114a99 |
| Abadan                 | 7aafe6bfe44b338f99021cbd24096302 |
| Abaetetuba             | 9dd331c21b983c3a68d00ef6e5852bb5 |
| Abakan                 | e2206290ce91574bc26d0443ef50fc05 |
| Abbotsford             | 50ca17be25d1d5c2ac6760e179b7fd15 |
| Abeokuta               | ab026fa6238e2ab7ee0d76a1351f116f |
| Aberdeen               | d85eef763393862e5fe318ca652eb16d |
+------------------------+----------------------------------+

我正在使用MySQL Server版本:5.5.40-0 + wheezy1(Debian)


5
就我而言,我需要在生成的GUID中使用连字符。我用了这个: SELECT INSERT(INSERT(INSERT(INSERT(MD5(UUID()), 9, 0, '-'), 14, 0, '-'), 19, 0, '-'), 24, 0, '-')查询不是很漂亮,但是可以完成任务。
2013年

9
md5是否不比UUID独特?我担心碰撞。
亚当(Adam)


5

当我尝试在生成UUID时修改它们时,我最后做了一个小的补充,结果很奇怪。我找到了答案通过拉克什是最简单的运作良好,除了要剥去破折号案件。

以供参考:

UPDATE some_table SET some_field=(SELECT uuid());

这本身就完美地工作了。但是当我尝试这样做时:

UPDATE some_table SET some_field=(REPLACE((SELECT uuid()), '-', ''));

然后所有的结果值都是相同的(没有细微的不同-我用GROUP BY some_field查询检查了四倍)。无论如何放置括号,都会发生相同的情况。

UPDATE some_table SET some_field=(REPLACE(SELECT uuid(), '-', ''));

似乎在围绕子查询以使用REPLACE生成UUID时,它只运行一次UUID查询,对于比我聪明得多的开发人员来说,这对于优化是很有意义的,但对我而言却不是。

为了解决这个问题,我将其分为两个查询:

UPDATE some_table SET some_field=(SELECT uuid());
UPDATE some_table SET some_field=REPLACE(some_field, '-', '');

很明显,这是一个简单的解决方案,但是希望这可以为我节省一些时间。


4

看起来像是一个简单的错字。您不是说“ ... where columnId null”吗?

UPDATE db.tablename
  SET columnID = UUID()
  where columnID is null

1
阅读问题时我有相同的想法,但我不这么认为:听起来像他的列中包含值,但不包含UNIQUE值。在您的答案早已给出的答案已经表明需要什么。不应有任何WHERE条款。而且生成的值非常相似,因此必须仔细查看它们以确保它们确实不同。
ToolmakerSteve

3

我几乎都遇到了同样的问题。我的情况是,uuid存储为BINARY(16)并具有NOT NULL UNIQUE约束。当每行都生成相同的UUID时,我遇到了问题,而UNIQUE约束不允许这样做。因此此查询不起作用:

UNHEX(REPLACE(uuid(), '-', ''))

但是对我来说,它有效,当我使用带有嵌套内部选择的查询时:

UNHEX(REPLACE((SELECT uuid()), '-', ''))

然后为每个条目产生唯一的结果。


1
UPDATE db.tablename SET columnID = (SELECT UUID()) where columnID is not null

2
请添加一些有关您的代码如何工作的解释。没有注释的代码对于其他SO用户而言并不总是易于理解
Simas Joneliunas

如果您想更新现有数据中的uuid,请根据您的条件运行上述查询。
Ashutosh Niranjan

0

MYSQL UPDATE表名SET columnName = UUID()

oracle UPDATE表名SET columnName = SYS_GUID();

SQLSERVER UPDATE表名SET columnName = NEWID();;


0
// UID Format: 30B9BE365FF011EA8F4C125FC56F0F50
UPDATE `events` SET `evt_uid` = (SELECT UPPER(REPLACE(@i:=UUID(),'-','')));

// UID Format: c915ec5a-5ff0-11ea-8f4c-125fc56f0f50
UPDATE `events` SET `evt_uid` = (SELECT UUID());

// UID Format: C915EC5a-5FF0-11EA-8F4C-125FC56F0F50
UPDATE `events` SET `evt_uid` = (SELECT UPPER(@i:=UUID()));
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.