Generare GUID in MySQL per i dati esistenti?


100

Ho appena importato un mucchio di dati in una tabella MySQL e ho una colonna "GUID" che voglio fondamentalmente riempire tutte le righe esistenti con GUID casuali nuovi e unici.

Come posso farlo in MySQL?

Provai

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

E ottieni lo stesso ogni campo


2
sei proprio sicuro che siano uguali? Ho provato, la maggior parte dei caratteri è uguale, ma ci sono alcune differenze
nell'uuid

Sì, confermo, è lo stesso!
Cyril N.

Per me funziona: le differenze sono minori, ma ci sono. Il modo più rapido per verificare è aggiungere un vincolo UNIQUE alla colonna.
PSU

Risposte:


88

Non sono sicuro che sia il modo più semplice, ma funziona. L'idea è di creare un trigger che faccia tutto il lavoro per te, quindi, per eseguire una query che aggiorna la tua tabella e infine per rilasciare questo trigger:

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

Quindi esegui

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

E DROP TRIGGER beforeYourTableUpdate ;

UPDATE Un'altra soluzione che non utilizza trigger, ma richiede chiave primaria o indice univoco:

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

AGGIORNAMENTO ancora una volta: sembra che anche la tua query originale dovrebbe funzionare (forse non ne hai bisogno WHERE columnID is not null, quindi tutto il mio codice fantasia non è necessario.


sì, dovrebbe funzionare anche in 5.0. Ma non dimenticare di premere il grilletto!
a1ex07

sì certo :) mi chiedo solo se devo controllare i duplicati dopo o se questo creerà valori univoci per ogni riga nella colonna?
Tom

Se UUIDè implementato correttamente (e credo che lo sia), dovresti essere in grado di creare un indice univoco senza controllare i duplicati.
a1ex07

Ho aggiornato la mia risposta con un altro approccio che potrebbe essere utile.
a1ex07

2
il tuo codice originale funzionerebbe, cambia semplicemente columnId = UUID () in columnId = (SELECT UUID ()). Ha funzionato alla grande per me. tutti i valori generati sono molto vicini all'essere gli stessi ma ognuno è unico.
EJay

111

Avevo bisogno di aggiungere una colonna della chiave primaria GUID in una tabella esistente e popolarla con GUID univoci e questa query di aggiornamento con selezione interna ha funzionato per me:

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

Così semplice :-)


35
All'inizio ho pensato che questo avesse inserito UUID duplicati perché iniziano e finiscono tutti allo stesso modo, ma in realtà sono leggermente diversi.
Sam Barnum

3
@SamBarnum perché UUIDviene generato in base alla macchina e al timestamp . Poiché una query che impiega millisecondi per essere eseguita, deve essere davvero molto molto vicina ... ma mai la stessa ... una buona cosa per assicurarti, è aggiungere un UNIQUEindice a quella colonna.
balexandre

2
La risposta accettata sembra eccessiva rispetto a questa!
Xtreme Biker

4
Almeno in mariadb (10.1.26) questo non sembra funzionare, dando lo stesso uuid per ogni record.
johanvdw

4
Questo ha generato per me lo stesso UUID su ogni record, presumibilmente perché è in una sottoquery e MySQL eseguirà prima la query interna e utilizzerà lo stesso valore per tutte le righe. Per risolverlo, rimuovere la sottoquery:UPDATE sri_issued_quiz SET quiz_id=uuid();
Chris White

22

La soluzione approvata crea ID univoci ma a prima vista sembrano identici, solo i primi caratteri differiscono.

Se vuoi chiavi visibilmente diverse, prova questo:

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

Sto usando la versione di MySQL Server: 5.5.40-0 + wheezy1 (Debian)


5
Nel mio caso, avevo bisogno di trattini nel GUID generato. Ho usato questo: SELECT INSERT(INSERT(INSERT(INSERT(MD5(UUID()), 9, 0, '-'), 14, 0, '-'), 19, 0, '-'), 24, 0, '-')Query non è molto carino ma fa il lavoro.
solo il

9
Non è md5 meno univoco degli UUID? Mi preoccuperei delle collisioni.
Adam

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

1
perfetto perfetto perfetto !! una cosa così piccola può avere un impatto enorme !!
thekosmix

5

Solo una piccola aggiunta da fare perché ho ottenuto uno strano risultato quando ho provato a modificare gli UUID mentre venivano generati. Ho trovato la risposta di Rakesh la più semplice che ha funzionato bene, tranne nei casi in cui si desidera rimuovere i trattini.

Per riferimento:

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

Funzionava perfettamente da solo. Ma quando ho provato questo:

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

Quindi tutti i valori risultanti erano gli stessi (non leggermente diversi - ho quadruplicato il controllo con una GROUP BY some_fieldquery). Non importa come ho posizionato le parentesi, succede la stessa cosa.

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

Sembra che quando circonda la sottoquery per generare un UUID con REPLACE, esegua la query UUID solo una volta, il che probabilmente ha perfettamente senso come ottimizzazione per sviluppatori molto più intelligenti di me, ma non per me.

Per risolvere questo problema, l'ho diviso in due query:

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

Soluzione semplice, ovviamente, ma spero che questo farà risparmiare a qualcuno il tempo che ho appena perso.


4

Sembra un semplice errore di battitura. Non intendevi "... where columnId is null"?

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

1
Ho avuto lo stesso pensiero quando ho letto la domanda, ma non la penso così: sembra che le sue colonne contengano valori, ma non valori UNICI. Le risposte fornite molto prima della tua risposta mostrano già ciò che è necessario. Non dovrebbe esserci una WHEREclausola. E i valori generati sono molto simili, quindi bisogna guardarli da vicino per vedere che sono effettivamente diversi.
ToolmakerSteve

3

Ho affrontato principalmente lo stesso problema. Nel mio caso uuid è memorizzato come BINARY (16) e non ha vincoli UNIQUE NULL. E ho affrontato il problema quando è stato generato lo stesso UUID per ogni riga e il vincolo UNIQUE non lo consente. Quindi questa query non funziona:

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

Ma per me ha funzionato, quando ho usato una query del genere con selezione interna annidata:

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

Quindi viene prodotto un risultato unico per ogni voce.


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

2
Si prega di aggiungere qualche spiegazione su come funziona il codice. Il codice senza commenti non è sempre facile da capire agli altri utenti SO
Simas Joneliunas il

se vuoi aggiornare uuid nei dati esistenti, esegui la query come sopra con la tua condizione.
Ashutosh Niranjan

0

MYsql UPDATE tablename SET columnName = UUID ()

oracle UPDATE tablename SET columnName = SYS_GUID ();

SQLSERVER UPDATE tablename 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()));
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.