Wygenerować GUID w MySQL dla istniejących danych?

101

Właśnie zaimportowałem kilka danych do tabeli MySQL i mam kolumnę „GUID”, w której chcę w zasadzie wypełnić wszystkie istniejące wiersze nowymi i unikalnymi losowymi identyfikatorami GUID.

Jak to zrobić w MySQL?

próbowałem

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

I po prostu wszystkie pola są takie same

Tomek
źródło
2
czy na pewno są takie same? Próbowałem, większość znaków jest taka sama, ale jest kilka różnic w wygenerowanym
uuidzie
Tak, potwierdzam, to to samo!
Cyril N.
U mnie to działa - różnice są niewielkie, ale są. Najszybszym sposobem sprawdzenia jest dodanie UNIQUE ograniczenia do kolumny.
PSU

Odpowiedzi:

88

Nie jestem pewien, czy to najłatwiejszy sposób, ale działa. Chodzi o to, aby utworzyć wyzwalacz, który działa za Ciebie, a następnie wykonać zapytanie aktualizujące tabelę, a na końcu porzucić ten wyzwalacz:

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

Następnie wykonaj

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

Oraz DROP TRIGGER beforeYourTableUpdate;

UPDATE Inne rozwiązanie, które nie używa wyzwalaczy, ale wymaga klucza podstawowego lub unikalnego indeksu:

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 jeszcze raz: Wygląda na to, że Twoje pierwotne zapytanie również powinno działać (może nie potrzebujesz WHERE columnID is not null, więc cały mój wymyślny kod nie jest potrzebny.

a1ex07
źródło
tak, powinno działać nawet w 5.0. Ale nie zapomnij upuścić spustu!
a1ex07
tak, jasne :) zastanawiam się tylko, czy po prostu muszę sprawdzić duplikaty, czy to stworzy unikalne wartości dla każdego wiersza w kolumnie?
Tom
Jeśli UUIDjest prawidłowo zaimplementowany (i uważam, że tak), powinno być możliwe utworzenie unikalnego indeksu bez sprawdzania duplikatów.
a1ex07
Zaktualizowałem swoją odpowiedź innym podejściem, które również może być przydatne.
a1ex07
2
Twój oryginalny kod zadziała, po prostu zmień columnId = UUID () na columnId = (SELECT UUID ()). U mnie zadziałało świetnie. wszystkie wygenerowane wartości są bardzo bliskie bycia takimi samymi, ale każda jest niepowtarzalna.
EJay
113

Musiałem dodać kolumnę klucza podstawowego guid do istniejącej tabeli i wypełnić ją unikalnymi identyfikatorami GUID, a to zapytanie aktualizujące z wewnętrznym wyborem zadziałało:

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

Tak prosty :-)

Rakesh Prajapati
źródło
35
Na początku myślałem, że to wstawiło zduplikowane identyfikatory UUID, ponieważ wszystkie zaczynają się i kończą tak samo, ale w rzeczywistości są nieco inne.
Sam Barnum
3
@SamBarnum, ponieważ UUIDjest generowany na podstawie maszyny i sygnatury czasowej . Jako zapytanie, które trwa milisekundy, musi być rzeczywiście bardzo, bardzo blisko ... ale nigdy tak samo ... dobrą rzeczą, aby Cię zapewnić, jest dodanie UNIQUEindeksu do tej kolumny.
balexandre
2
Przyjęta odpowiedź wydaje się przesada w porównaniu z tym!
Xtreme Biker
4
Przynajmniej w mariadbie (10.1.26) nie wydaje się to działać, dając ten sam płyn dla każdego rekordu.
johanvdw
4
To wygenerowało dla mnie ten sam identyfikator UUID w każdym rekordzie, prawdopodobnie dlatego, że znajduje się w podzapytaniu, a MySQL wykona najpierw zapytanie wewnętrzne i użyje tej samej wartości dla wszystkich wierszy. Aby go rozwiązać, usuń podzapytanie:UPDATE sri_issued_quiz SET quiz_id=uuid();
Chris White,
22

Zatwierdzone rozwiązanie tworzy unikalne identyfikatory, ale na pierwszy rzut oka wyglądają identycznie, tylko kilka pierwszych znaków się różni.

Jeśli chcesz mieć widoczne inne klucze, spróbuj tego:

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

Używam wersji serwera MySQL: 5.5.40-0 + wheezy1 (Debian)

Imran-UK
źródło
6
W moim przypadku potrzebowałem łączników w wygenerowanym identyfikatorze GUID. Użyłem tego: SELECT INSERT(INSERT(INSERT(INSERT(MD5(UUID()), 9, 0, '-'), 14, 0, '-'), 19, 0, '-'), 24, 0, '-')Query nie jest zbyt ładne, ale spełnia swoje zadanie.
solo
9
Czy md5 nie jest mniej unikatowy niż identyfikatory UUID? Martwiłbym się kolizjami.
Adam
15
select @i:=uuid();
update some_table set guid = (@i:=uuid());
Brad Johnson
źródło
1
idealne idealne idealne !! taka mała rzecz może mieć ogromny wpływ !!
thekosmix
5

Tylko drobny dodatek do zrobienia, ponieważ skończyło się na dziwnym wyniku, gdy próbowałem zmodyfikować UUID w trakcie ich generowania. Znalazłem odpowiedź u Rakesh być najprostszy, że działa dobrze, z wyjątkiem przypadków, w których chcesz się rozebrać kreski.

Na przykład:

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

To działało doskonale samodzielnie. Ale kiedy próbowałem tego:

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

Wtedy wszystkie otrzymane wartości były takie same (nie różniły się nieznacznie - czterokrotnie sprawdziłem GROUP BY some_fieldzapytaniem). Nie ma znaczenia, jak umieściłem nawiasy, dzieje się to samo.

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

Wydaje się, że otaczając podzapytanie w celu wygenerowania UUID za pomocą polecenia REPLACE, uruchamia zapytanie UUID tylko raz, co prawdopodobnie ma sens jako optymalizacja dla znacznie mądrzejszych programistów niż ja, ale nie dla mnie.

Aby rozwiązać ten problem, po prostu podzieliłem go na dwa zapytania:

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

Oczywiście proste rozwiązanie, ale mam nadzieję, że pozwoli to komuś zaoszczędzić czas, który właśnie straciłem.

enobrev
źródło
4

Wygląda na zwykłą literówkę. Czy nie chodziło Ci o „... gdzie columnId jest null”?

UPDATE db.tablename
  SET columnID = UUID()
  where columnID is null
evan.leonard
źródło
1
Miałem tę samą myśl, kiedy czytałem pytanie, ale nie sądzę: brzmi tak, jakby jego kolumny zawierały wartości, ale nie wartości UNIKALNE. Odpowiedzi udzielone na długo przed Twoją odpowiedzią pokazują, co jest potrzebne. Nie powinno być WHEREklauzuli. Wygenerowane wartości są bardzo podobne, więc należy się im dokładnie przyjrzeć, aby zobaczyć, że rzeczywiście są różne.
ToolmakerSteve
3

Miałem w większości ten sam problem. W moim przypadku uuid jest przechowywany jako BINARY (16) i ma NIE NULL UNIQUE ograniczenia. I napotkałem problem, gdy ten sam identyfikator UUID był generowany dla każdego wiersza, a ograniczenie UNIQUE na to nie pozwala. Więc to zapytanie nie działa:

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

Ale dla mnie zadziałało, gdy użyłem takiego zapytania z zagnieżdżonym wyborem wewnętrznym:

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

Następnie tworzony jest unikalny wynik dla każdego wpisu.

Oleksandr Korniienko
źródło
1
UPDATE db.tablename SET columnID = (SELECT UUID()) where columnID is not null
Ashutosh Niranjan
źródło
2
Dodaj wyjaśnienie, jak działa Twój kod. Kod bez komentarzy nie zawsze jest łatwy do zrozumienia dla innych użytkowników SO
Simas Joneliunas
jeśli chcesz zaktualizować uuid w istniejących danych, uruchom zapytanie jak powyżej ze swoim warunkiem.
Ashutosh Niranjan
0

MYsql UPDATE nazwa tabeli SET columnName = UUID ()

oracle UPDATE nazwa tabeli SET nazwa_kolumny = SYS_GUID ();

SQLSERVER UPDATE nazwa tabeli SET columnName = NEWID () ;;

Hugo R.
źródło
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
źródło