Mevcut Veriler için MySQL'de GUID oluşturulsun mu?


103

Bir MySQL tablosuna bir grup veriyi aktardım ve temelde tüm mevcut satırları yeni ve benzersiz rastgele GUID'lerle doldurmak istediğim bir "GUID" sütunum var.

Bunu MySQL'de nasıl yaparım?

denedim

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

Ve her alanı aynı olsun


2
gerçekten emin misiniz,
aynılar

Evet, onaylıyorum, aynı!
Cyril N.

Benim için işe yarıyor - farklılıklar küçük ama var. Kontrol etmenin en hızlı yolu, sütuna EŞSİZ bir kısıtlama eklemektir.
PSU

Yanıtlar:


88

Bunun en kolay yolu olduğundan emin değilim ama işe yarıyor. Buradaki fikir, hepsi sizin için çalışan bir tetikleyici oluşturmak, ardından tablonuzu güncelleyen bir sorgu yürütmek ve son olarak bu tetikleyiciyi bırakmaktır:

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

Sonra çalıştır

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

Ve DROP TRIGGER beforeYourTableUpdate;

GÜNCELLEME Tetikleyiciler kullanmayan ancak birincil anahtar veya benzersiz dizin gerektiren başka bir çözüm:

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

Bir kez daha GÜNCELLEME : Görünüşe göre orijinal sorgunuzun da çalışması gerekiyor (belki ihtiyacınız yok WHERE columnID is not null, bu yüzden tüm fantezi koduma gerek yok.


evet, 5.0'da bile çalışmalı. Ancak tetiği düşürmeyi unutmayın!
a1ex07

evet elbette :) daha sonra kopyaları kontrol etmem gerekip gerekmediğini veya bunun sütundaki her satır için benzersiz değerler yaratıp yaratmayacağını merak mı ediyorsunuz?
Tom

Eğer UUID(ve bence de) doğru şekilde uygulandığını Yinelenen kişiler kontrol edilmeden benzersiz bir dizin oluşturmak mümkün olmalıdır.
a1ex07

Cevabımı faydalı olabilecek başka bir yaklaşımla güncelledim.
a1ex07

2
orijinal kodunuz çalışır, sadece columnId = UUID () 'i columnId = (SELECT UUID ()) olarak değiştirin. Benim için harika çalıştı. üretilen tüm değerler aynı olmaya çok yakındır ancak her biri benzersizdir.
EJay

116

Mevcut bir tabloya bir kılavuz birincil anahtar sütunu eklemem ve onu benzersiz GUID'lerle doldurmam gerekiyordu ve bu güncelleme sorgusu iç seçim ile benim için çalıştı:

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

Çok basit :-)


36
İlk başta bunun yinelenen UUID'leri eklediğini düşündüm çünkü hepsi aynı başlayıp bitiyor, ama aslında biraz farklılar.
Sam Barnum

3
@SamBarnum çünkü makine ve zaman damgasınaUUID göre oluşturulur . Çalıştırılması milisaniyeler süren bir sorgu olarak, gerçekten çok yakın olmaları gerekir ... ama asla aynı değildir ... sizi temin etmek için iyi bir şey, o sütuna bir dizin eklemektir . UNIQUE
balexandre

2
Kabul edilen cevap, buna kıyasla abartılı görünüyor!
Xtreme Biker

4
En azından mariadb'de (10.1.26) bu işe yaramıyor, her kayıt için aynı uuid'i veriyor.
johanvdw

5
Bu, benim için her kayıtta aynı UUID'yi oluşturdu, çünkü muhtemelen bir alt sorguda ve MySQL ilk önce iç sorguyu çalıştıracak ve tüm satırlar için aynı değeri kullanacak. Çözmek için alt sorguyu kaldırın:UPDATE sri_issued_quiz SET quiz_id=uuid();
Chris White

22

Onaylanan çözüm benzersiz kimlikler yaratır, ancak ilk bakışta aynı görünürler, yalnızca ilk birkaç karakter farklıdır.

Gözle görülür şekilde farklı anahtarlar istiyorsanız, şunu deneyin:

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

MySQL Sunucusu sürümünü kullanıyorum: 5.5.40-0 + wheezy1 (Debian)


6
Benim durumumda, oluşturulan GUID'de tirelere ihtiyacım vardı. Bunu kullandım: SELECT INSERT(INSERT(INSERT(INSERT(MD5(UUID()), 9, 0, '-'), 14, 0, '-'), 19, 0, '-'), 24, 0, '-')Sorgu çok hoş değil ama işi yapıyor.
solo

9
Md5, UUID'lerden daha az benzersiz değil mi? Çarpışmalar konusunda endişelenirim.
Adam

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

1
mükemmel mükemmel mükemmel !! böyle küçük bir şeyin çok büyük etkisi olabilir !!
thekosmix

5

UUID'leri oluşturuldukları gibi değiştirmeye çalışırken garip bir sonuçla sonuçlandığım için yapmam gereken küçük bir ekleme. Bulduğum cevabı ile Rakesh , iyi gitti en basit olması size tire şerit istediğiniz durumlarda hariç için.

Referans için:

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

Bu kendi başına mükemmel çalıştı. Ama bunu denediğimde:

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

Sonra ortaya çıkan tüm değerler aynıydı (pek de farklı değil - bir GROUP BY some_fieldsorgu ile dört kez kontrol ettim ). Parantezleri nasıl yerleştirdiğim önemli değil, aynı şey oluyor.

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

Görünüşe göre, REPLACE ile bir UUID oluşturmak için alt sorguyu çevrelediğinde, UUID sorgusunu yalnızca bir kez çalıştırıyor, bu muhtemelen benden çok daha akıllı geliştiriciler için bir optimizasyon olarak mükemmel bir anlam ifade ediyor, ancak bana etmedi.

Bunu çözmek için, sadece iki sorguya ayırdım:

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

Açıkçası basit bir çözüm, ama umarım bu birisine kaybettiğim zamandan tasarruf ettirir.


4

Basit bir yazım hatası gibi görünüyor. Eğer "... nerede Columnıd ifade etmedi olan boş"?

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

1
Soruyu okuduğumda da aynı düşünceye sahiptim ama öyle düşünmüyorum: sütunları değerler içeriyor gibi sesler, ancak BENZERSİZ değerler değil. Cevabınızdan çok önce verilen cevaplar zaten neye ihtiyaç duyulduğunu gösteriyor. Bir WHEREcümle olmamalı . Ve üretilen değerler çok benzer, bu yüzden gerçekten farklı olduklarını görmek için onlara yakından bakmalısınız.
ToolmakerSteve

3

Çoğunlukla aynı sorunla karşılaştım. Im my case uuid, BINARY (16) olarak saklanır ve NULL UNIQUE kısıtlamalarına sahip değildir. Ve her satır için aynı UUID üretildiğinde ve UNIQUE kısıtlaması buna izin vermediğinde sorunla karşılaştım. Yani bu sorgu çalışmıyor:

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

Ama iç içe geçmiş iç seçim ile böyle bir sorgu kullandığımda benim için işe yaradı:

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

Daha sonra her giriş için benzersiz sonuç üretilir.


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

2
Lütfen kodunuzun nasıl çalıştığına dair bazı açıklamalar ekleyin.
Yorumsuz kodu

Mevcut verilerdeki uuid'i güncellemek istiyorsanız, koşulunuzla yukarıdaki gibi sorguyu çalıştırın.
Ashutosh Niranjan

1

MYsql

UPDATE tablename   SET columnName = UUID()

kehanet

UPDATE tablename   SET columnName = SYS_GUID();

SQL SERVER

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()));
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.