สร้าง GUID ใน MySQL สำหรับข้อมูลที่มีอยู่หรือไม่


103

ฉันเพิ่งนำเข้าข้อมูลจำนวนมากไปยังตาราง MySQL และฉันมีคอลัมน์ "GUID" ที่ฉันต้องการเติมเต็มแถวที่มีอยู่ทั้งหมดด้วย GUID แบบสุ่มใหม่และไม่ซ้ำใคร

ฉันจะทำสิ่งนี้ใน MySQL ได้อย่างไร?

ฉันเหนื่อย

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

และรับทุกฟิลด์เหมือนกัน


2
คุณแน่ใจจริงๆเหรอพวกมันเหมือนกันฉันได้ลองแล้วตัวละครส่วนใหญ่เหมือนกัน แต่มีความแตกต่างเล็กน้อยใน uuid ที่สร้างขึ้น
xiaoyifang

ใช่ฉันยืนยันเหมือนเดิม!
Cyril N.

มันได้ผลสำหรับฉัน - ความแตกต่างเป็นเรื่องเล็กน้อย แต่ก็มี วิธีตรวจสอบที่เร็วที่สุดคือเพิ่มข้อ จำกัด UNIQUE ลงในคอลัมน์
PSU

คำตอบ:


88

ฉันไม่แน่ใจว่าเป็นวิธีที่ง่ายที่สุด แต่ได้ผล แนวคิดคือการสร้างทริกเกอร์ที่ทำงานให้คุณทั้งหมดจากนั้นดำเนินการค้นหาที่อัปเดตตารางของคุณและสุดท้ายจะวางทริกเกอร์นี้:

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

จากนั้นดำเนินการ

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

และDROP TRIGGER beforeYourTableUpdate;

อัปเดต โซลูชันอื่นที่ไม่ใช้ทริกเกอร์ แต่ต้องการคีย์หลักหรือดัชนีเฉพาะ:

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

อัปเดตอีกครั้ง: ดูเหมือนว่าข้อความค้นหาเดิมของคุณควรใช้งานได้ (บางทีคุณอาจไม่ต้องการWHERE columnID is not nullดังนั้นรหัสแฟนซีทั้งหมดของฉันจึงไม่จำเป็นต้องใช้


ใช่มันควรจะใช้งานได้แม้ใน 5.0 แต่อย่าลืมวางไก!
a1ex07

ใช่แล้ว :) แค่สงสัยว่าฉันต้องตรวจสอบรายการที่ซ้ำกันหรือไม่หรือจะสร้างค่าที่ไม่ซ้ำกันสำหรับทุกแถวในคอลัมน์หรือไม่
ทอม

หากUUIDมีการใช้งานอย่างถูกต้อง (และฉันเชื่อว่าเป็นเช่นนั้น) คุณควรจะสร้างดัชนีเฉพาะได้โดยไม่ต้องตรวจสอบรายการที่ซ้ำกัน
a1ex07

ฉันอัปเดตคำตอบด้วยวิธีการอื่นซึ่งอาจเป็นประโยชน์เช่นกัน
a1ex07

2
รหัสเดิมของคุณจะใช้งานได้เพียงแค่เปลี่ยน columnId = UUID () เป็น columnId = (SELECT UUID ()) ทำงานได้ดีสำหรับฉัน ค่าที่สร้างขึ้นทั้งหมดใกล้เคียงกันมาก แต่แต่ละค่าจะไม่ซ้ำกัน
EJay

116

ฉันจำเป็นต้องเพิ่มคอลัมน์คีย์หลัก guid ในตารางที่มีอยู่และเติมข้อมูลด้วย GUID ที่ไม่ซ้ำกันและแบบสอบถามการอัปเดตพร้อมการเลือกภายในนี้ใช้ได้กับฉัน:

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

ง่ายมาก :-)


36
ตอนแรกฉันคิดว่าสิ่งนี้ได้แทรก UUID ที่ซ้ำกันเพราะทั้งหมดเริ่มต้นและสิ้นสุดเหมือนกัน แต่จริงๆแล้วมันแตกต่างกันเล็กน้อย
Sam Barnum

3
@SamBarnum เพราะUUIDถูกสร้างขึ้นบนพื้นฐานของเครื่องและเวลา ในฐานะที่เป็นแบบสอบถามที่ใช้เวลาในการรันมิลลิวินาทีจึงต้องอยู่ใกล้กันมากอย่างแน่นอน ... แต่ไม่เหมือนเดิม ... สิ่งที่ดีที่จะทำให้คุณมั่นใจได้คือการเพิ่มUNIQUEดัชนีลงในคอลัมน์นั้น
balexandre

2
คำตอบที่ได้รับการยอมรับดูเหมือนจะมากเกินไปเมื่อเทียบกับสิ่งนี้!
Xtreme Biker

4
อย่างน้อยใน mariadb (10.1.26) สิ่งนี้ดูเหมือนจะไม่ได้ผลโดยให้ uuid เดียวกันสำหรับทุกระเบียน
johanvdw

5
สิ่งนี้สร้าง UUID เดียวกันในทุกระเบียนสำหรับฉันน่าจะเป็นเพราะอยู่ในแบบสอบถามย่อยและ MySQL จะเรียกใช้แบบสอบถามภายในก่อนและใช้ค่าเดียวกันสำหรับทุกแถว หากต้องการแก้ไขให้ลบคำถามย่อย:UPDATE sri_issued_quiz SET quiz_id=uuid();
Chris White

22

โซลูชันที่ได้รับการอนุมัติจะสร้าง ID ที่ไม่ซ้ำกัน แต่เมื่อมองแวบแรกจะมีลักษณะเหมือนกันมีเพียงอักขระไม่กี่ตัวแรกเท่านั้นที่แตกต่างกัน

หากคุณต้องการคีย์ที่แตกต่างอย่างเห็นได้ชัดให้ลองทำดังนี้:

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 Server เวอร์ชัน: 5.5.40-0 + wheezy1 (Debian)


6
ในกรณีของฉันฉันต้องการยัติภังค์ใน GUID ที่สร้างขึ้น ฉันใช้สิ่งนี้: SELECT INSERT(INSERT(INSERT(INSERT(MD5(UUID()), 9, 0, '-'), 14, 0, '-'), 19, 0, '-'), 24, 0, '-')ข้อความค้นหาไม่ค่อยสวย แต่ได้ผล
เดี่ยว

9
md5 ไม่ซ้ำกันน้อยกว่า UUID หรือไม่? ฉันกังวลเกี่ยวกับการชนกัน
อดัม


5

เป็นเพียงการเพิ่มเล็กน้อยที่จะทำให้เมื่อฉันได้ผลลัพธ์ที่แปลกประหลาดเมื่อพยายามแก้ไข UUID เมื่อสร้างขึ้น ฉันพบว่าคำตอบของRakeshเป็นคำตอบที่ง่ายที่สุดที่ใช้งานได้ดียกเว้นในกรณีที่คุณต้องการตัดขีดกลาง

สำหรับการอ้างอิง:

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

สิ่งนี้ทำงานได้อย่างสมบูรณ์แบบด้วยตัวมันเอง แต่เมื่อฉันลองสิ่งนี้:

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

จากนั้นค่าผลลัพธ์ทั้งหมดจะเหมือนกัน (ไม่แตกต่างกันเล็กน้อย - ฉันตรวจสอบสี่เท่าด้วยGROUP BY some_fieldแบบสอบถาม) ไม่สำคัญว่าฉันจะวางวงเล็บอย่างไรสิ่งเดียวกันก็เกิดขึ้น

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

ดูเหมือนว่าเมื่ออยู่รอบ ๆ ข้อความค้นหาย่อยเพื่อสร้าง UUID ด้วย REPLACE มันจะเรียกใช้แบบสอบถาม UUID เพียงครั้งเดียวซึ่งอาจเหมาะสมกับการเพิ่มประสิทธิภาพให้กับนักพัฒนาที่ฉลาดกว่าฉันมาก แต่ก็ไม่เหมาะกับฉัน

ในการแก้ไขปัญหานี้ฉันเพิ่งแยกออกเป็นสองคำถาม:

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

วิธีแก้ปัญหาง่ายๆเห็นได้ชัด แต่หวังว่านี่จะช่วยใครบางคนในเวลาที่ฉันเสียไป


4

ดูเหมือนพิมพ์ผิดง่ายๆ คุณไม่ได้หมายถึง "... โดยที่ columnId เป็นโมฆะ"?

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

1
ฉันมีความคิดเดียวกันเมื่ออ่านคำถาม แต่ฉันไม่คิดอย่างนั้น: ดูเหมือนว่าคอลัมน์ของเขาจะมีค่า แต่ไม่ใช่ค่าที่ไม่ซ้ำใคร คำตอบที่ให้มานานก่อนที่คำตอบของคุณจะแสดงสิ่งที่จำเป็นอยู่แล้ว ไม่ควรมีWHEREคำสั่ง และค่าที่สร้างขึ้นมีความคล้ายคลึงกันมากดังนั้นต้องดูอย่างใกล้ชิดเพื่อดูว่ามันแตกต่างกันแน่นอน
ToolmakerSteve

3

ฉันประสบปัญหาเดียวกันเป็นส่วนใหญ่ uuid กรณีของฉันถูกจัดเก็บเป็น BINARY (16) และไม่มีข้อ จำกัด NULL UNIQUE และฉันประสบกับปัญหาเมื่อสร้าง UUID เดียวกันสำหรับทุกแถวและข้อ จำกัด UNIQUE ไม่อนุญาตให้ทำเช่นนี้ ดังนั้นแบบสอบถามนี้ใช้ไม่ได้:

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

แต่สำหรับฉันมันได้ผลเมื่อฉันใช้แบบสอบถามดังกล่าวกับการเลือกภายในที่ซ้อนกัน:

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

จากนั้นจะสร้างผลลัพธ์ที่ไม่ซ้ำกันสำหรับทุกรายการ


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

2
โปรดเพิ่มคำอธิบายเกี่ยวกับการทำงานของโค้ดของคุณ รหัสที่ไม่มีความคิดเห็นไม่ใช่เรื่องง่ายที่จะเข้าใจสำหรับผู้ใช้ SO รายอื่น
Simas Joneliunas

หากคุณต้องการอัปเดต uuid ในข้อมูลที่มีอยู่ให้เรียกใช้แบบสอบถามข้างต้นด้วยเงื่อนไขของคุณ
Ashutosh Niranjan


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()));
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.