Создать GUID в MySQL для существующих данных?


102

Я только что импортировал кучу данных в таблицу MySQL, и у меня есть столбец «GUID», который я хочу в основном заполнить всеми существующими строками новыми уникальными случайными GUID.

Как мне это сделать в MySQL?

Я попытался

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

И просто сделайте все поля одинаковыми


2
вы действительно уверены, что они такие же? Я пробовал, большинство символов одинаковы, но есть несколько отличий в сгенерированном uuid
xiaoyifang

Да подтверждаю, то же самое!
Кирилл Н.

У меня работает - отличия небольшие, но есть. Самый быстрый способ проверить - добавить в столбец ограничение UNIQUE.
PSU

Ответы:


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 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. Но не забудьте уронить курок!
a1ex07 08

да, конечно :) просто интересно, нужно ли мне проверять дубликаты после или это создаст уникальные значения для каждой строки в столбце?
Tom

Если UUIDон реализован правильно (а я считаю, что это так), вы сможете создать уникальный индекс без проверки дубликатов.
a1ex07 08

Я обновил свой ответ другим подходом, который также может быть полезен.
a1ex07 08

2
ваш исходный код будет работать, просто измените columnId = UUID () на columnId = (SELECT UUID ()). У меня отлично сработало. все сгенерированные значения очень близки к тому, чтобы быть одинаковыми, но каждое уникально.
EJay

114

Мне нужно было добавить столбец первичного ключа guid в существующую таблицу и заполнить его уникальными идентификаторами GUID, и этот запрос на обновление с внутренним выбором сработал для меня:

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

Так просто :-)


35
Сначала я подумал, что здесь вставлены повторяющиеся UUID, потому что все они начинаются и заканчиваются одинаково, но на самом деле они немного отличаются.
Сэм Барнум,

3
@SamBarnum, потому что UUIDсоздается на основе машины и отметки времени . Поскольку для выполнения запроса требуются миллисекунды, они должны быть действительно очень близки ... но никогда не должны быть одинаковыми ... хорошо вас заверить, это добавить UNIQUEиндекс в этот столбец.
balexandre 06

2
Принятый ответ кажется излишним по сравнению с этим!
Xtreme Biker

4
По крайней мере, в mariadb (10.1.26) это не работает, давая одинаковый uuid для каждой записи.
johanvdw 01

4
Это сгенерировало для меня один и тот же UUID для каждой записи, предположительно потому, что он находится в подзапросе, и MySQL сначала выполнит внутренний запрос и будет использовать одно и то же значение для всех строк. Чтобы решить эту проблему, удалите подзапрос:UPDATE sri_issued_quiz SET quiz_id=uuid();
Крис Уайт

22

Утвержденное решение действительно создает уникальные идентификаторы, но на первый взгляд они выглядят одинаково, отличаются только первые несколько символов.

Если вам нужны явно разные ключи, попробуйте следующее:

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: 5.5.40-0 + wheezy1 (Debian)


6
В моем случае мне понадобились дефисы в сгенерированном GUID. Я использовал это: SELECT INSERT(INSERT(INSERT(INSERT(MD5(UUID()), 9, 0, '-'), 14, 0, '-'), 19, 0, '-'), 24, 0, '-')запрос не очень красивый, но он выполняет свою работу.
соло

9
Разве md5 не менее уникален, чем UUID? Я бы беспокоился о столкновениях.
Адам

15
select @i:=uuid();
update some_table set guid = (@i:=uuid());

1
идеально идеально идеально !! такая мелочь может иметь огромное влияние !!
thekosmix

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(), '-', ''));

Кажется, что при окружении подзапроса для генерации UUID с REPLACE он запускает запрос UUID только один раз, что, вероятно, имеет смысл в качестве оптимизации для гораздо более умных разработчиков, чем я, но для меня это не так.

Чтобы решить эту проблему, я просто разделил его на два запроса:

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

Простое решение, очевидно, но, надеюсь, это сэкономит кому-то время, которое я только что потерял.


4

Похоже на простую опечатку. Разве вы не имели в виду "... где columnId равен нулю"?

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

1
У меня была такая же мысль, когда я читал вопрос, но я так не думаю: похоже, что его столбцы содержат значения, но не УНИКАЛЬНЫЕ значения. Ответы, данные задолго до вашего ответа, уже показывают, что необходимо. Оговорки быть не должно 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,
Симас Йонелиунас,

если вы хотите обновить uuid в существующих данных, запустите запрос, как указано выше, с вашим условием.
Ашутош Ниранджан

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()));
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.