GUID in MySQL für vorhandene Daten generieren?

100

Ich habe gerade eine Reihe von Daten in eine MySQL-Tabelle importiert und ich habe eine Spalte "GUID", die ich grundsätzlich alle vorhandenen Zeilen mit neuen und eindeutigen zufälligen GUIDs füllen möchte.

Wie mache ich das in MySQL?

Ich habe es versucht

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

Und einfach jedes Feld gleich bekommen

Tom
quelle
2
Bist du dir wirklich sicher, dass sie gleich sind? Ich habe versucht, die meisten Charaktere sind gleich, aber es gibt ein paar Unterschiede in der generierten UUID
Xiaoyifang
Ja, ich bestätige, es ist das gleiche!
Cyril N.
Es funktioniert bei mir - die Unterschiede sind gering, aber vorhanden. Die schnellste Möglichkeit zur Überprüfung besteht darin, der Spalte eine EINZIGARTIGE Einschränkung hinzuzufügen.
Netzteil

Antworten:

88

Ich bin mir nicht sicher, ob es der einfachste Weg ist, aber es funktioniert. Die Idee ist, einen Trigger zu erstellen, der alles für Sie erledigt, dann eine Abfrage auszuführen, die Ihre Tabelle aktualisiert, und diesen Trigger schließlich zu löschen:

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

Dann ausführen

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

Und DROP TRIGGER beforeYourTableUpdate;

UPDATE Eine andere Lösung, die keine Trigger verwendet, aber einen Primärschlüssel oder einen eindeutigen Index erfordert:

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 noch einmal: Es scheint, dass Ihre ursprüngliche Abfrage auch funktionieren sollte (vielleicht brauchen Sie sie nicht WHERE columnID is not null, also wird mein ganzer ausgefallener Code nicht benötigt.

a1ex07
quelle
Ja, es sollte sogar in 5.0 funktionieren. Aber vergessen Sie nicht, den Abzug zu betätigen!
a1ex07
Ja sicher :) Ich frage mich nur, ob ich danach nach Duplikaten suchen muss oder ob dadurch eindeutige Werte für jede Zeile in der Spalte erstellt werden.
Tom
Wenn UUIDes richtig implementiert ist (und ich glaube es ist), sollten Sie in der Lage sein, einen eindeutigen Index zu erstellen, ohne nach Duplikaten zu suchen.
a1ex07
Ich habe meine Antwort mit einem anderen Ansatz aktualisiert, der ebenfalls nützlich sein kann.
a1ex07
2
Ihr ursprünglicher Code würde funktionieren, ändern Sie einfach columnId = UUID () in columnId = (SELECT UUID ()). Hat super für mich funktioniert. Alle generierten Werte sind nahezu gleich, aber jeder ist einzigartig.
EJay
111

Ich musste einer vorhandenen Tabelle eine Guid-Primärschlüsselspalte hinzufügen und diese mit eindeutigen GUIDs füllen, und diese Aktualisierungsabfrage mit innerer Auswahl funktionierte für mich:

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

So einfach :-)

Rakesh Prajapati
quelle
35
Zuerst dachte ich, dies hätte doppelte UUIDs eingefügt, weil sie alle gleich beginnen und enden, aber sie unterscheiden sich tatsächlich geringfügig.
Sam Barnum
3
@SamBarnum, da UUIDbasierend auf der Maschine und dem Zeitstempel generiert wird . Als Abfrage, deren Ausführung Millisekunden dauert, müssen sie zwar sehr, sehr nahe beieinander liegen ... aber niemals gleich ... eine gute Sache, um Ihnen zu versichern, ist das Hinzufügen eines UNIQUEIndex zu dieser Spalte.
Balexandre
2
Die akzeptierte Antwort scheint im Vergleich dazu ein Overkill zu sein!
Xtreme Biker
4
Zumindest in Mariadb (10.1.26) scheint dies nicht zu funktionieren, da für jede Aufzeichnung dieselbe UUID angegeben wird.
Johanvdw
4
Dies hat für mich in jedem Datensatz dieselbe UUID generiert, vermutlich weil es sich in einer Unterabfrage befindet und MySQL zuerst die innere Abfrage ausführt und für alle Zeilen den gleichen Wert verwendet. Um es zu lösen, entfernen Sie die Unterabfrage:UPDATE sri_issued_quiz SET quiz_id=uuid();
Chris White
22

Die genehmigte Lösung erstellt zwar eindeutige IDs, sieht jedoch auf den ersten Blick identisch aus, nur die ersten Zeichen unterscheiden sich.

Wenn Sie sichtbar unterschiedliche Schlüssel wünschen, versuchen Sie Folgendes:

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

Ich verwende MySQL Server Version: 5.5.40-0 + wheezy1 (Debian)

Imran-UK
quelle
5
In meinem Fall brauchte ich Bindestriche in der generierten GUID. Ich habe das benutzt: SELECT INSERT(INSERT(INSERT(INSERT(MD5(UUID()), 9, 0, '-'), 14, 0, '-'), 19, 0, '-'), 24, 0, '-')Query ist nicht sehr hübsch, aber es macht den Job.
Solo
9
Ist md5 nicht weniger eindeutig als UUIDs? Ich würde mir Sorgen um Kollisionen machen.
Adam
15
select @i:=uuid();
update some_table set guid = (@i:=uuid());
Brad Johnson
quelle
1
perfekt perfekt perfekt !! so ein kleines Ding kann große Auswirkungen haben !!
Thekosmix
5

Nur eine kleine Ergänzung, da ich beim Versuch, die UUIDs so zu ändern, wie sie generiert wurden, ein seltsames Ergebnis erzielt habe. Ich fand die Antwort von Rakesh die einfachste, die gut funktionierte, außer in Fällen, in denen Sie die Striche entfernen möchten.

Als Referenz:

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

Dies funktionierte perfekt für sich. Aber als ich das versuchte:

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

Dann waren alle resultierenden Werte gleich (nicht subtil unterschiedlich - ich vervierfachte mit einer GROUP BY some_fieldAbfrage). Egal wie ich die Klammern angeordnet habe, das gleiche passiert.

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

Es scheint, dass beim Umgeben der Unterabfrage zum Generieren einer UUID mit REPLACE die UUID-Abfrage nur einmal ausgeführt wird, was als Optimierung für viel intelligentere Entwickler als ich wahrscheinlich durchaus sinnvoll ist, für mich jedoch nicht.

Um dies zu beheben, habe ich es einfach in zwei Abfragen aufgeteilt:

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

Natürlich eine einfache Lösung, aber hoffentlich spart dies jemandem die Zeit, die ich gerade verloren habe.

enobrev
quelle
4

Sieht aus wie ein einfacher Tippfehler. Hast du nicht , dass „... wo columnid ist null“?

UPDATE db.tablename
  SET columnID = UUID()
  where columnID is null
evan.leonard
quelle
1
Ich hatte den gleichen Gedanken, als ich die Frage las, aber ich glaube nicht: Klingt so, als ob seine Spalten Werte enthalten, aber keine EINZIGARTIGEN Werte. Die Antworten, die lange vor Ihrer Antwort gegeben wurden, zeigen bereits, was benötigt wird. Es sollte keine WHEREKlausel geben. Und die generierten Werte sind sehr ähnlich, daher müssen Sie sie genau betrachten, um festzustellen, dass sie tatsächlich unterschiedlich sind.
ToolmakerSteve
3

Ich hatte meistens das gleiche Problem. Im my case uuid wird als BINARY (16) gespeichert und hat KEINE NULL UNIQUE-Einschränkungen. Und ich war mit dem Problem konfrontiert, als für jede Zeile dieselbe UUID generiert wurde und die UNIQUE-Einschränkung dies nicht zulässt. Diese Abfrage funktioniert also nicht:

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

Aber für mich hat es funktioniert, als ich eine solche Abfrage mit verschachtelter innerer Auswahl verwendet habe:

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

Dann wird für jeden Eintrag ein eindeutiges Ergebnis erstellt.

Oleksandr Korniienko
quelle
1
UPDATE db.tablename SET columnID = (SELECT UUID()) where columnID is not null
Ashutosh Niranjan
quelle
2
Bitte fügen Sie eine Erklärung zur Funktionsweise Ihres Codes hinzu. Code ohne Kommentare ist für andere SO-Benutzer nicht immer leicht zu verstehen
Simas Joneliunas
Wenn Sie die UUID in vorhandenen Daten aktualisieren möchten, führen Sie die Abfrage wie oben beschrieben mit Ihrer Bedingung aus.
Ashutosh Niranjan
0

MYsql UPDATE Tabellenname SET columnName = UUID ()

oracle UPDATE Tabellenname SET columnName = SYS_GUID ();

SQLSERVER UPDATE Tabellenname SET columnName = NEWID () ;;

Hugo R.
quelle
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
quelle