Những hạn chế khi sử dụng UUID hoặc GUID làm khóa chính là gì?


60

Tôi muốn xây dựng một hệ thống phân tán. Tôi cần lưu trữ dữ liệu trong cơ sở dữ liệu và sẽ hữu ích khi sử dụng UUID hoặc GUID làm khóa chính trên một số bảng. Tôi cho rằng đó là một nhược điểm với thiết kế này vì UUID / GUID khá lớn và chúng gần như ngẫu nhiên. Cách khác là sử dụng INT hoặc LONG tăng tự động.

Những hạn chế khi sử dụng UUID hoặc GUID làm khóa chính cho các bảng của tôi là gì?

Tôi có thể sẽ sử dụng Derby / JavaDB (trên máy khách) và PostgreSQL (trên máy chủ) làm DBMS.


Tại sao nó sẽ hữu ích? Những nhược điểm nào bạn tập trung nhất vào? Câu trả lời cho mọi câu hỏi DB mơ hồ này là "nó phụ thuộc". Bạn có thể cho chúng tôi biết thêm chi tiết? Bạn có quan tâm nhất đến hiệu suất đọc hoặc viết? chúng ta đang nói về mức độ phân phối nào?
Brian Ballsun-Stanton

@Brian: UUID trong các hệ thống phân tán rất hữu ích vì bạn có thể tạo khóa chính trên máy khách và sau đó tải dữ liệu không đồng bộ lên máy chủ. Tôi chủ yếu nghĩ về những hạn chế về hiệu suất đọc. Sử dụng nhiều THAM GIA trên UUID có thể không tốt? Ví dụ, khách hàng thêm một mục (UUID, tên, nhà cung cấp, người tạo) vào hệ thống kiểm kê và sau đó cơ sở dữ liệu cục bộ được đồng bộ hóa với cơ sở dữ liệu trung tâm trên máy chủ.
Jonas

1
Tôi nghĩ rằng nếu không có một số ý kiến ​​rõ ràng hơn về điều này thì nó sẽ trở thành "nó phụ thuộc". Không có những thứ đó, tôi sẽ đi VtC.
jcolebrand

Có một bài viết nói về GUID so với không phải GUID ảnh hưởng đến các chỉ mục được nhóm trong SQL Server mà bạn có thể thấy thú vị mặc dù nó liên quan đến một sản phẩm SQL khác: x.co/Twpp
Jeff

Tôi nhận thấy rằng tài liệu Derby không liệt kê UUID dưới dạng kiểu dữ liệu. Bạn có thể muốn xem xét một giải pháp thay thế, chẳng hạn như Công cụ cơ sở dữ liệu H2 (cơ sở dữ liệu thuần Java như Derby) liệt kê loại dữ liệu UUID . Tất nhiên Postgres có hỗ trợ tuyệt vời để lưu trữ , lập chỉ mục và tạo các giá trị UUID một cách hiệu quả .
Basil Bourque

Câu trả lời:


29

Nó phụ thuộc vào chức năng tạo và kích thước của các bảng cuối cùng của bạn

GUID được dự định là định danh duy nhất trên toàn cầu . Như đã thảo luận trong tài liệu Postgres 8.3 , không có phương pháp nào phù hợp với toàn cầu để tạo ra các định danh này, nhưng postgreQuery thực hiện với một vài ứng cử viên hữu ích hơn.

Từ phạm vi vấn đề của bạn và nhu cầu viết ngoại tuyến , bạn đã sắp xếp khá gọn gàng việc sử dụng bất cứ thứ gì ngoại trừ GUID, và do đó không có lợi thế bù trừ nào cho các kế hoạch khác.

Từ quan điểm chức năng, độ dài khóa thường không phải là vấn đề đối với bất kỳ loại hệ thống hiện đại nào, tùy thuộc vào số lần đọc và kích thước của bảng. Là một phương pháp thay thế, khách hàng ngoại tuyến có thể bó các bản ghi mới mà không cần khóa chính và chỉ cần chèn chúng khi kết nối lại. Vì postgreSQL cung cấp kiểu dữ liệu "Nối tiếp", khách hàng sẽ không bao giờ cần xác định ID nếu họ có thể thực hiện ghi đơn giản vào cơ sở dữ liệu.


3
Chết tiệt, bạn đã đi và để Brian trả lời câu hỏi. Có, yêu cầu "cập nhật ngoại tuyến" đã thay đổi hoàn toàn toàn bộ khái niệm ở đó.
jcolebrand

Muahahahaah! :: twirls ria mép evilly ::
Brian Ballsun-Stanton

1
Ngay cả với ghi ngoại tuyến, vẫn có thể sử dụng INTs. Ví dụ: sử dụng hai cột {Node_ID, Item_ID}trong đó mỗi nút có một Node_IDvà một cột Item_IDđược tự động tăng lên trên mỗi nút.
Jonas

@Jonas ~ Vâng, điều đó là khả thi. Tuy nhiên, một trong những lý do hầu hết mọi người thậm chí dự tính GUID là để sao chép nội dung được phân tách trên toàn cầu sang các cơ sở dữ liệu khác. Tôi có nghĩa là thuật ngữ chính nó là QED ở đó.
jcolebrand

Liên quan đến kiến ​​trúc chính / nô lệ hoặc máy khách kết nối thưa thớt + kiến ​​trúc máy chủ chính, có thể sử dụng global_id (SERIAL) trên master và global_id (BIGINT) + local_id (SERIAL) trên nô lệ. Các nô lệ thực hiện công việc cục bộ của họ bằng local_id và cam kết khi họ có thể về phía chủ, chủ nhận được dữ liệu và cấp cho nó một global_id mà nó trả về cho nô lệ, nô lệ cập nhật trường global_id (để sử dụng tham chiếu khi nói chuyện với máy chủ hoặc với người khác nô lệ).
Mihai Stancu

22

Thêm một lời khuyên - không bao giờ sử dụng GUID như một phần của chỉ mục được nhóm. GUID không tuần tự, do đó, nếu chúng là một phần của chỉ mục được phân cụm, mỗi khi bạn chèn bản ghi mới, cơ sở dữ liệu sẽ cần sắp xếp lại tất cả các trang bộ nhớ của nó để tìm vị trí phù hợp để chèn, trong trường hợp tự động tăng (intint) sẽ chỉ là trang cuối cùng.

Bây giờ nếu chúng ta tìm đến một số nhận thức db: 1.) MySQL - các khóa chính được phân cụm, không có tùy chọn để thay đổi hành vi - việc giới thiệu là không sử dụng GUID ở đây 2.) Postgres, MS-SQL - bạn có thể tạo GUID như khóa chính không được bao gồm và sử dụng một trường khác làm chỉ mục được nhóm, ví dụ như autoincrement int.


Những gì bạn đề xuất cho Postgres cũng có thể được thực hiện trong MySQL, với cấu trúc hơi khác nhau - auto_increment PK (khóa cụm), GUID với chỉ mục duy nhất (không bao gồm).
ypercubeᵀᴹ

Điều này không phải lúc nào cũng đúng. Tùy thuộc vào thông lượng hệ thống đĩa, đồng bộ hóa quyền truy cập vào trang cuối cùng đó có thể là nút cổ chai của bạn. blog.kejser.org/2011/10/05/ Từ
mwilson

2
"Không giống như Microsoft SQL Server, phân cụm trên một chỉ mục trong PostgreSQL không duy trì thứ tự đó. Bạn phải áp dụng lại quy trình CLUSTER để duy trì thứ tự." Làm thế nào để CLUSTER ON cải thiện hiệu suất chỉ mục
bartolo-otrit

Một phiên bản cô đọng hơn của thông tin @ bartolo-otrit được liên kết đến: stackoverflow.com/a/4796685/1394393 . Câu trả lời này thực sự không phù hợp với tôi, vì câu hỏi này là về PG và dường như nó cho rằng sự tương đồng với SQL Server và MySQL không tồn tại.
jpmc26

database would need to rearrange all its memory pages to find the right place for insertion=> Tôi không nghĩ đó là trường hợp của Postgres, vì phân cụm là tùy chọn và các hàng mới được lưu trữ không theo thứ tự.
Flavien 17/03/2016

3

Nó phụ thuộc.

Nghiêm túc mà nói, với tất cả những gì bạn đã cho đến nay, đây là khoảng cách bạn có thể đi.

Tại sao nó sẽ hữu ích khi sử dụng UUID? Tại sao bạn không sử dụng INTs? Tại sao bạn không thể lập chỉ mục trên UUID sau này? Bạn có hiểu ý nghĩa của việc có một danh sách được sắp xếp với khóa của UUID và chèn UUID ngẫu nhiên (không tuần tự) sau vài triệu hàng không?

Nền tảng này sẽ chạy trên nền tảng nào? Có bao nhiêu đĩa? Có bao nhiêu người dùng? Có bao nhiêu hồ sơ?


7
Như tôi đã viết trong nhận xét của mình, nếu tôi sử dụng UUID, khách hàng có thể thêm hàng vào cơ sở dữ liệu mà không cần kết nối với máy chủ và sau đó đồng bộ hóa với máy chủ. Tôi không thể làm điều đó nếu tôi sử dụng INT cho khóa chính, vì nhiều khách hàng có thể sử dụng cùng một khóa chính cho các mục khác nhau. Chà, thật vô ích khi sắp xếp danh sách trên cột UUID, việc sắp xếp nó trên cột dấu thời gian sẽ hữu ích hơn. Không, tôi không biết ý nghĩa của việc chèn một UUID không tuần tự ngẫu nhiên sau vài triệu hàng, đó là lý do tại sao tôi hỏi câu hỏi này.
Jonas

Ứng dụng này sẽ được viết bằng Java và các máy khách mà tôi sử dụng Windows, Mac hoặc Linux. Các máy khách sẽ sử dụng các máy tính để bàn thông thường thường có một đĩa. Số lượng người dùng và hồ sơ tùy thuộc vào số lượng khách hàng tôi nhận được, nhưng sẽ có khoảng 5000 mỗi khách hàng và khách hàng.
Jonas

1
Các bình luận ngoại tuyến đã thay đổi mọi thứ. Xem những gì chi tiết hơn?
jcolebrand
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.