¿Generar GUID en MySQL para datos existentes?

100

Acabo de importar un montón de datos a una tabla MySQL y tengo una columna "GUID" que básicamente quiero llenar todas las filas existentes con GUID aleatorios nuevos y únicos.

¿Cómo hago esto en MySQL?

Lo intenté

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

Y haz que todos los campos sean iguales

Tom
fuente
2
¿Estás realmente seguro de que son iguales? Lo he intentado, la mayoría de los personajes son iguales, pero hay algunas diferencias en el
uuid
Sí, lo confirmo, ¡es lo mismo!
Cyril N.
Funciona para mí, las diferencias son menores, pero existen. La forma más rápida de verificar es agregar una restricción ÚNICA a la columna.
PSU

Respuestas:

88

No estoy seguro de si es la forma más fácil, pero funciona. La idea es crear un disparador que haga todo el trabajo por usted, luego, ejecutar una consulta que actualice su tabla y, finalmente, soltar este disparador:

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

Entonces ejecuta

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

Y DROP TRIGGER beforeYourTableUpdate;

ACTUALIZAR Otra solución que no usa activadores, pero requiere una clave principal o un índice único:

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

ACTUALIZAR una vez más: Parece que su consulta original también debería funcionar (tal vez no lo necesite WHERE columnID is not null, por lo que no se necesita todo mi código elegante.

a1ex07
fuente
sí, debería funcionar incluso en 5.0. ¡Pero no olvide soltar el gatillo!
a1ex07
sí, claro :) solo me pregunto si necesito verificar si hay duplicados después o si esto creará valores únicos para cada fila en la columna.
Tom
Si UUIDse implementa correctamente (y creo que lo es), debería poder crear un índice único sin verificar si hay duplicados.
a1ex07
Actualicé mi respuesta con otro enfoque que también puede ser útil.
a1ex07
2
su código original funcionaría, simplemente cambie columnId = UUID () a columnId = (SELECT UUID ()). Funcionó muy bien para mí. todos los valores generados están muy cerca de ser iguales pero cada uno es único.
EJay
111

Tuve la necesidad de agregar una columna de clave primaria guid en una tabla existente y completarla con GUID únicos y esta consulta de actualización con selección interna funcionó para mí:

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

Tan sencillo :-)

Rakesh Prajapati
fuente
35
Al principio pensé que esto había insertado UUID duplicados porque todos comienzan y terminan igual, pero de hecho son ligeramente diferentes.
Sam Barnum
3
@SamBarnum porque UUIDse genera en función de la máquina y la marca de tiempo . Como una consulta que tarda milisegundos en ejecutarse, tienen que estar muy, muy cerca de hecho ... pero nunca iguales ... una buena cosa para asegurarles es agregar un UNIQUEíndice a esa columna.
balexandre
2
¡La respuesta aceptada parece una exageración en comparación con esto!
Xtreme Biker
4
Al menos en mariadb (10.1.26) esto no parece funcionar, dando el mismo uuid para cada registro.
johanvdw
4
Esto generó el mismo UUID en cada registro para mí, presumiblemente porque está en una subconsulta y MySQL ejecutará la consulta interna primero y usará el mismo valor para todas las filas. Para resolverlo, elimine la subconsulta:UPDATE sri_issued_quiz SET quiz_id=uuid();
Chris White
22

La solución aprobada crea identificaciones únicas, pero a primera vista parecen idénticas, solo difieren los primeros caracteres.

Si desea claves visiblemente diferentes, intente esto:

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 |
+------------------------+----------------------------------+

Estoy usando la versión del servidor MySQL: 5.5.40-0 + wheezy1 (Debian)

Imran-Reino Unido
fuente
5
En mi caso, necesitaba guiones en el GUID generado. Usé esto: La SELECT INSERT(INSERT(INSERT(INSERT(MD5(UUID()), 9, 0, '-'), 14, 0, '-'), 19, 0, '-'), 24, 0, '-')consulta no es muy bonita pero hace el trabajo.
solo
9
¿No es md5 menos exclusivo que los UUID? Me preocuparía por las colisiones.
Adam
15
select @i:=uuid();
update some_table set guid = (@i:=uuid());
Brad Johnson
fuente
1
perfecto perfecto perfecto !! ¡Una cosa tan pequeña puede tener un gran impacto!
thekosmix
5

Solo una pequeña adición para hacer, ya que terminé con un resultado extraño al intentar modificar los UUID a medida que se generaban. Encontré que la respuesta de Rakesh es la más simple que funcionó bien, excepto en los casos en los que desea eliminar los guiones.

Para referencia:

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

Esto funcionó perfectamente por sí solo. Pero cuando probé esto:

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

Entonces, todos los valores resultantes fueron los mismos (no sutilmente diferentes, lo cuadriplicaron con una GROUP BY some_fieldconsulta). No importa cómo ubique los paréntesis, sucede lo mismo.

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

Parece que al rodear la subconsulta para generar un UUID con REPLACE, solo ejecuta la consulta UUID una vez, lo que probablemente tiene mucho sentido como optimización para desarrolladores mucho más inteligentes que yo, pero no para mí.

Para resolver esto, lo dividí en dos consultas:

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

Solución simple, obviamente, pero espero que esto le ahorre a alguien el tiempo que acabo de perder.

enobrev
fuente
4

Parece un simple error tipográfico. ¿No quiso decir "... donde columnId es nulo"?

UPDATE db.tablename
  SET columnID = UUID()
  where columnID is null
evan.leonard
fuente
1
Tuve el mismo pensamiento cuando leí la pregunta, pero no lo creo: parece que sus columnas contienen valores, pero no valores ÚNICOS. Las respuestas dadas mucho antes de su respuesta ya muestran lo que se necesita. No debería haber una WHEREcláusula. Y los valores generados son muy similares, por lo que hay que mirarlos de cerca para ver que efectivamente son diferentes.
ToolmakerSteve
3

Enfrenté principalmente el mismo problema. En mi caso, el uuid se almacena como BINARIO (16) y NO tiene restricciones NULL ÚNICAS. Y me enfrenté al problema cuando se generó el mismo UUID para cada fila, y la restricción ÚNICA no lo permite. Entonces esta consulta no funciona:

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

Pero para mí funcionó, cuando usé una consulta de este tipo con selección interna anidada:

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

Entonces se produce un resultado único para cada entrada.

Oleksandr Korniienko
fuente
1
UPDATE db.tablename SET columnID = (SELECT UUID()) where columnID is not null
Ashutosh Niranjan
fuente
2
Agregue una explicación sobre cómo funciona su código. El código sin comentarios no siempre es fácil de entender para otros usuarios de SO
Simas Joneliunas
Si desea actualizar uuid en los datos existentes, ejecute la consulta como se indicó anteriormente con su condición.
Ashutosh Niranjan
0

MYsql UPDATE nombre de tabla SET columnName = UUID ()

oracle UPDATE tablename SET columnName = SYS_GUID ();

SQLSERVER UPDATE nombre de tabla SET columnName = NEWID () ;;

Hugo R
fuente
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()));
Leonardo Filipe
fuente