Tạo GUID trong MySQL cho Dữ liệu hiện có?


100

Tôi vừa nhập một loạt dữ liệu vào bảng MySQL và tôi có một cột "GUID" mà tôi muốn điền về cơ bản tất cả các hàng hiện có bằng GUID ngẫu nhiên mới và duy nhất.

Làm cách nào để thực hiện việc này trong MySQL?

Tôi đã thử

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

Và chỉ lấy mọi trường giống nhau


2
? Bạn thực sự chắc chắn, họ đang cùng tôi đã cố gắng, hầu hết các nhân vật đều giống nhau, nhưng có một vài sự khác biệt trong tạo uuid
xiaoyifang

Vâng, tôi xác nhận, nó giống nhau!
Cyril N.

Nó hoạt động với tôi - sự khác biệt là nhỏ, nhưng vẫn có. Cách nhanh nhất để kiểm tra là thêm ràng buộc DUY NHẤT vào cột.
PSU

Câu trả lời:


88

Tôi không chắc đó có phải là cách dễ nhất hay không, nhưng nó hoạt động. Ý tưởng là tạo một trình kích hoạt phù hợp với bạn, sau đó, thực hiện một truy vấn cập nhật bảng của bạn và cuối cùng là bỏ trình kích hoạt này:

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

Sau đó thực hiện

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

DROP TRIGGER beforeYourTableUpdate;

CẬP NHẬT Một giải pháp khác không sử dụng trình kích hoạt, nhưng yêu cầu khóa chính hoặc chỉ mục duy nhất:

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

CẬP NHẬT một lần nữa: Có vẻ như truy vấn ban đầu của bạn cũng sẽ hoạt động (có thể bạn không cần WHERE columnID is not null, vì vậy tất cả mã ưa thích của tôi là không cần thiết.


vâng, nó sẽ hoạt động ngay cả trong 5.0. Nhưng đừng quên thả cò súng!
a1ex07

yeah chắc chắn :) chỉ tự hỏi liệu tôi có cần kiểm tra các bản sao sau hay không hay liệu điều này sẽ tạo ra các giá trị duy nhất cho mọi hàng trong cột?
Tom

Nếu UUIDđược triển khai đúng cách (và tôi tin là như vậy), bạn sẽ có thể tạo chỉ mục duy nhất mà không cần kiểm tra các bản sao.
a1ex07

Tôi đã cập nhật câu trả lời của mình bằng một cách tiếp cận khác cũng có thể hữu ích.
a1ex07

2
mã ban đầu của bạn sẽ hoạt động, chỉ cần thay đổi columnId = UUID () thành columnId = (SELECT UUID ()). Làm việc rất tốt cho tôi. tất cả các giá trị được tạo đều rất gần giống nhau nhưng mỗi giá trị là duy nhất.
EJay

111

Tôi có nhu cầu thêm cột khóa chính hướng dẫn trong bảng hiện có và điền nó bằng GUID duy nhất và truy vấn cập nhật này với lựa chọn bên trong phù hợp với tôi:

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

Quá đơn giản :-)


35
Lúc đầu, tôi nghĩ rằng điều này đã chèn các UUID trùng lặp vì chúng đều bắt đầu và kết thúc giống nhau, nhưng thực tế chúng hơi khác nhau.
Sam Barnum

3
@SamBarnum vì UUIDđược tạo dựa trên máy và dấu thời gian . Là một truy vấn mất mili giây để chạy, chúng thực sự phải rất gần nhau ... nhưng không bao giờ giống nhau ... một điều tốt để đảm bảo với bạn, là thêm một UNIQUEchỉ mục vào cột đó.
balexandre

2
Câu trả lời được chấp nhận dường như là quá mức cần thiết so với điều này!
Xtreme Biker

4
Ít nhất là trong mariadb (10.1.26), điều này dường như không hoạt động, cho kết quả giống nhau cho mọi bản ghi.
johanvdw

4
Điều này tạo ra cùng một UUID trên mọi bản ghi đối với tôi, có lẽ vì nó nằm trong một truy vấn con và MySQL sẽ thực thi truy vấn bên trong trước tiên và sử dụng cùng một giá trị cho tất cả các hàng. Để giải quyết vấn đề đó, hãy xóa truy vấn phụ:UPDATE sri_issued_quiz SET quiz_id=uuid();
Chris White,

22

Giải pháp đã được phê duyệt tạo ra các ID duy nhất nhưng nhìn sơ qua thì chúng trông giống hệt nhau, chỉ khác một vài ký tự đầu tiên.

Nếu bạn muốn các phím khác nhau rõ ràng, hãy thử cách này:

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

Tôi đang sử dụng phiên bản MySQL Server: 5.5.40-0 + wheezy1 (Debian)


5
Trong trường hợp của tôi, tôi cần dấu gạch ngang trong GUID được tạo. Tôi đã sử dụng cái này: SELECT INSERT(INSERT(INSERT(INSERT(MD5(UUID()), 9, 0, '-'), 14, 0, '-'), 19, 0, '-'), 24, 0, '-')Truy vấn không đẹp lắm nhưng nó hoạt động tốt.
solo

9
Không phải md5 ít duy nhất so với UUID? Tôi lo lắng về va chạm.
Adam

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

1
hoàn hảo hoàn hảo hoàn hảo !! điều nhỏ như vậy có thể có tác động rất lớn !!
thekosmix

5

Chỉ là một bổ sung nhỏ để thực hiện vì tôi đã nhận được một kết quả kỳ lạ khi cố gắng sửa đổi các UUID khi chúng được tạo. Tôi thấy câu trả lời của Rakeshcâu trả lời đơn giản nhất hoạt động tốt, ngoại trừ trường hợp bạn muốn loại bỏ dấu gạch ngang.

Để tham khảo:

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

Điều này đã hoạt động hoàn hảo của riêng nó. Nhưng khi tôi thử điều này:

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

Sau đó, tất cả các giá trị kết quả đều giống nhau (không khác biệt một cách tinh tế - tôi đã kiểm tra bốn lần bằng một GROUP BY some_fieldtruy vấn). Không quan trọng cách tôi định vị các dấu ngoặc đơn, điều tương tự cũng xảy ra.

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

Có vẻ như khi xoay quanh truy vấn con để tạo UUID với REPLACE, nó chỉ chạy truy vấn UUID một lần, điều này có thể có ý nghĩa hoàn hảo như một sự tối ưu hóa cho các nhà phát triển thông minh hơn tôi, nhưng với tôi thì không.

Để giải quyết vấn đề này, tôi chỉ cần chia nó thành hai truy vấn:

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

Giải pháp đơn giản, rõ ràng, nhưng hy vọng điều này sẽ tiết kiệm cho ai đó thời gian mà tôi vừa mất.


4

Trông giống như một lỗi đánh máy đơn giản. Không phải ý bạn là "... nơi columnId null"?

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

1
Tôi đã có cùng suy nghĩ khi đọc câu hỏi, nhưng tôi không nghĩ vậy: nghe có vẻ như các cột của anh ấy chứa các giá trị, nhưng không phải giá trị DUY NHẤT. Các câu trả lời được đưa ra rất lâu trước khi câu trả lời của bạn đã hiển thị những gì cần thiết. Không nên có một WHEREmệnh đề. Và các giá trị được tạo ra rất giống nhau, vì vậy phải xem xét chúng thật kỹ để thấy rằng chúng thực sự khác nhau.
ToolmakerSteve

3

Tôi đã phải đối mặt với cùng một vấn đề. Tôi uuid trường hợp của tôi được lưu trữ dưới dạng BINARY (16) và không có ràng buộc KHÔNG ĐẦY ĐỦ. Và tôi đã gặp phải vấn đề khi cùng một UUID được tạo cho mọi hàng và ràng buộc UNIQUE không cho phép điều này. Vì vậy, truy vấn này không hoạt động:

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

Nhưng đối với tôi, nó đã hoạt động, khi tôi sử dụng một truy vấn như vậy với lựa chọn bên trong lồng nhau:

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

Sau đó được tạo ra kết quả duy nhất cho mọi mục nhập.


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

2
Vui lòng thêm một số giải thích về cách mã của bạn hoạt động. Mã không có bình luận không phải lúc nào cũng dễ hiểu đối với những người dùng SO khác
Simas Joneliunas

nếu bạn muốn cập nhật uuid trong dữ liệu hiện có, hãy chạy truy vấn như trên với điều kiện của bạn.
Ashutosh Niranjan

0

MYsql UPDATE tên bảng SET columnName = UUID ()

oracle UPDATE tên bảng SET columnName = SYS_GUID ();

CẬP NHẬT SQLSERVER tên bảng 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()));
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.