131 votes

Générer un GUID dans MySQL pour des données existantes ?

Je viens d'importer un tas de données dans une table MySQL et j'ai une colonne "GUID" que je veux essentiellement remplir toutes les lignes existantes avec de nouveaux GUID uniques et aléatoires.

Comment puis-je faire cela dans MySQL ?

J'ai essayé

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

Et faire en sorte que chaque champ soit le même

2 votes

Vous êtes vraiment sûr qu'ils sont identiques ? J'ai essayé, la plupart des caractères sont identiques, mais il y a quelques différences dans l'uuid généré.

0 votes

Oui, je confirme, c'est la même chose !

2 votes

Cela fonctionne pour moi - les différences sont mineures, mais elles sont là. Le moyen le plus rapide de vérifier est d'ajouter une contrainte UNIQUE à la colonne.

148voto

Rakesh Prajapati Points 231

J'avais besoin d'ajouter une colonne de clé primaire guidée dans une table existante et de la remplir avec des GUID uniques. Cette requête de mise à jour avec sélection interne a fonctionné pour moi :

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

Si simple :-)

48 votes

J'ai d'abord pensé que cela avait inséré des UUID en double, car ils commencent et finissent tous de la même façon, mais ils sont en fait légèrement différents.

7 votes

@SamBarnum parce que UUID est généré sur la base de la machine et horodatage . Comme une requête qui prend des millisecondes à exécuter, ils doivent être très très proches en effet ... mais jamais les mêmes ... une bonne chose à vous assurer, est d'ajouter un UNIQUE l'index de cette colonne.

3 votes

La réponse acceptée semble exagérée par rapport à celle-ci !

106voto

a1ex07 Points 23965

Je ne sais pas si c'est le moyen le plus simple, mais ça marche. L'idée est de créer un trigger qui fait tout le travail pour vous, puis, d'exécuter une requête qui met à jour votre table, et enfin de laisser tomber ce trigger :

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

Ensuite, exécutez

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

Et DROP TRIGGER beforeYourTableUpdate ;

UPDATE Une autre solution qui n'utilise pas de déclencheurs, mais nécessite une clé primaire ou un index unique :

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

UPDATE une fois de plus : Il semble que votre requête originale devrait également fonctionner (peut-être que vous n'avez pas besoin de WHERE columnID is not null donc tout mon code fantaisiste n'est pas nécessaire.

26voto

Imran-UK Points 131

La solution approuvée crée bien des identifiants uniques, mais à première vue, ils semblent identiques, seuls les premiers caractères diffèrent.

Si vous voulez des touches visiblement différentes, essayez ceci :

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

J'utilise la version du serveur MySQL : 5.5.40-0+wheezy1 (Debian)

9 votes

Dans mon cas, j'avais besoin de traits d'union dans le GUID généré. J'ai utilisé ceci : SELECT INSERT(INSERT(INSERT(INSERT(MD5(UUID()), 9, 0, '-'), 14, 0, '-'), 19, 0, '-'), 24, 0, '-') La requête n'est pas très jolie mais elle fait le travail.

9 votes

Le md5 n'est-il pas moins unique que les UUID ? Je m'inquiéterais des collisions.

23voto

Brad Johnson Points 21
select @i:=uuid();
update some_table set guid = (@i:=uuid());

2 votes

Parfait parfait parfait ! !! une si petite chose peut avoir un impact énorme ! !!

0 votes

Je confirme que la solution la plus simple et la seule qui fonctionne pour moi est de définir des UUID différents pour plusieurs lignes,

8voto

enobrev Points 10306

Juste un petit ajout à faire car je me suis retrouvé avec un résultat bizarre en essayant de modifier les UUIDs tels qu'ils ont été générés. J'ai trouvé le réponse par Rakesh est le plus simple et fonctionne bien, sauf dans les cas où l'on veut supprimer les tirets.

Pour référence :

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

Cela a parfaitement fonctionné tout seul. Mais quand j'ai essayé ça :

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

Ensuite, toutes les valeurs résultantes étaient les mêmes (pas subtilement différentes - j'ai vérifié quatre fois avec un GROUP BY some_field requête). Peu importe comment je situe les parenthèses, la même chose se produit.

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

Il semble que lorsqu'on entoure la sous-requête pour générer un UUID avec REPLACE, la requête UUID n'est exécutée qu'une seule fois, ce qui est probablement une optimisation parfaitement logique pour des développeurs bien plus intelligents que moi, mais pas pour moi.

Pour résoudre ce problème, je l'ai simplement divisé en deux requêtes :

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

Une solution simple, évidemment, mais j'espère que cela fera gagner à quelqu'un le temps que je viens de perdre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X