Ưu điểm và nhược điểm của khóa cơ sở dữ liệu GUID / UUID


222

Trước đây, tôi đã làm việc trên một số hệ thống cơ sở dữ liệu trong đó việc di chuyển các mục giữa các cơ sở dữ liệu sẽ trở nên dễ dàng hơn rất nhiều nếu tất cả các khóa cơ sở dữ liệu là giá trị GUID / UUID . Tôi đã xem xét việc đi xuống con đường này một vài lần, nhưng luôn có một chút không chắc chắn, đặc biệt là xung quanh hiệu suất và các URL không đọc được qua điện thoại.

Có ai đã làm việc rộng rãi với GUID trong cơ sở dữ liệu chưa? Những lợi thế nào tôi sẽ có được bằng cách đi theo cách đó, và những cạm bẫy có thể là gì?


1
Jeff có một bài viết về nó " Khóa chính: ID so với GUID ".
jfs

1
cũng có thể sử dụng Hi-Lo cho các máy khách từ xa: stackoverflow.com/questions/282099/whats-the-hi-lo-alacticm
Neil McGuigan


Vị trí được cập nhật cho bài đăng của Jeff Atwood về " Khóa chính: ID so với GUID ." Cảm ơn @jfs đã tham khảo.
Adam Katz

@jfs Liên kết đã thay đổi thành blog.codinghorror.com/primary-keys-ids-versus-guids
cr0ss

Câu trả lời:


229

Ưu điểm:

  • Có thể tạo chúng ngoại tuyến.
  • Làm cho việc nhân rộng trở nên tầm thường (trái ngược với int, điều này làm cho nó thực sự khó khăn)
  • ORM thường thích chúng
  • Độc đáo trên các ứng dụng. Vì vậy, chúng tôi có thể sử dụng PK từ CMS (hướng dẫn) trong ứng dụng của mình (cũng là hướng dẫn) và biết rằng chúng tôi KHÔNG BAO GIỜ bị đụng độ.

Nhược điểm:

  • Sử dụng không gian lớn hơn, nhưng không gian là giá rẻ (er)
  • Không thể đặt hàng bằng ID để có được thứ tự chèn.
  • Có thể trông xấu xí trong một URL, nhưng thực sự, WTF bạn đang đặt khóa REAL DB trong một URL!? (Điểm này gây tranh cãi trong các bình luận bên dưới)
  • Khó hơn để gỡ lỗi thủ công, nhưng không khó lắm.

Cá nhân, tôi sử dụng chúng cho hầu hết các PK trong bất kỳ hệ thống nào có kích thước khá, nhưng tôi đã được "đào tạo" trên một hệ thống được nhân rộng khắp mọi nơi, vì vậy chúng tôi phải có chúng. YMMV.

Tôi nghĩ rằng điều dữ liệu trùng lặp là rác - bạn có thể nhận được dữ liệu trùng lặp tuy nhiên bạn làm điều đó. Chìa khóa thay thế thường được tán thành ở nơi tôi từng làm việc. Chúng tôi sử dụng hệ thống giống như WordPress:

  • ID duy nhất cho hàng (GUID / bất cứ điều gì). Không bao giờ hiển thị cho người dùng.
  • ID công khai được tạo ONCE từ một số trường (ví dụ: tiêu đề - biến nó thành tiêu đề của bài viết)

CẬP NHẬT: Vì vậy, cái này được +1 rất nhiều và tôi nghĩ rằng tôi nên chỉ ra một nhược điểm lớn của GUID PK's: Clustered Indexes.

Nếu bạn có nhiều bản ghi và một chỉ mục được nhóm trên GUID, hiệu suất chèn của bạn sẽ SỐC, khi bạn nhận được các vị trí chèn ngẫu nhiên trong danh sách các mục (đó là điểm), không phải ở cuối (nhanh chóng)

Vì vậy, nếu bạn cần hiệu năng chèn, có thể sử dụng INT tự động và tạo GUID nếu bạn muốn chia sẻ nó với người khác (ví dụ: hiển thị nó cho người dùng trong URL)


184
[WTF bạn đang đặt khóa DB THỰC SỰ trong URL!?] Không chắc tại sao điều đó làm phiền bạn. Bạn sẽ sử dụng cái gì khác? Nhìn vào Stack Overflow ... Nó có các giá trị IDENTITY trong URL ở mọi nơi và nó hoạt động rất tốt. Sử dụng khóa DB trong URL không ngăn bạn thực thi bảo mật.
Euro Micelli

20
Không, không, nhưng những thứ như SEO thường tốt hơn nếu không có chìa khóa trong đó - đặc biệt là thứ gì đó miễn là HƯỚNG DẪN. Tất nhiên, nó có thể được xử lý một cách dễ dàng, vì vậy tôi đoán rằng đó là một chút của một tuyên bố quá sức
Nic Wise

7
Câu trả lời hay, thật tuyệt nếu bạn cũng thêm thông tin về những bất lợi về hiệu suất của việc sử dụng GUID; ví dụ: tham gia, sắp xếp và lập chỉ mục bởi tất cả chúng sẽ chậm hơn so với sử dụng số nguyên. Các hướng dẫn là tuyệt vời, nhưng chúng có chi phí có thể là một nỗi đau khi hiệu suất là rất quan trọng.
Bác sĩ Jones

26
Hãy ghi nhớ một điều, mọi người thường thay đổi trang, câu hỏi, tiêu đề diễn đàn. Đối với SEO, thật tốt khi có một cái gì đó giống như một ID nhỏ trong URL để nếu tiêu đề thay đổi, bạn vẫn biết nơi chuyển tiếp mọi người đến từ URL OLD. example.com/35/old-and-bustedvừa trở thành example.com/35/new-hotnessvà ứng dụng của bạn chỉ có thể kiểm tra tiêu đề và chuyển tiếp người dùng bằng 301.
Xeoncross

9
Lập chỉ mục GUID là tốn kém và chậm, điều này khiến họ thực sự là ứng cử viên kém cho các khóa chính.
Matthew James Davis

14

@Matt Sheppard:

Nói rằng bạn có một bảng của khách hàng. Chắc chắn bạn không muốn khách hàng tồn tại trong bảng nhiều lần, hoặc nhiều sự nhầm lẫn sẽ xảy ra trong toàn bộ bộ phận bán hàng và hậu cần của bạn (đặc biệt là nếu nhiều hàng về khách hàng chứa thông tin khác nhau).

Vì vậy, bạn có một mã định danh khách hàng xác định duy nhất khách hàng và bạn chắc chắn rằng số nhận dạng đó được khách hàng biết (trong hóa đơn), để khách hàng và nhân viên dịch vụ khách hàng có một tài liệu tham khảo chung trong trường hợp họ cần liên lạc. Để đảm bảo không có hồ sơ khách hàng trùng lặp, bạn thêm một ràng buộc duy nhất vào bảng, thông qua khóa chính trên mã định danh khách hàng hoặc thông qua ràng buộc KHÔNG NULL + UNIQUE trên cột số nhận dạng khách hàng.

Tiếp theo, vì một số lý do (mà tôi không thể nghĩ ra), bạn được yêu cầu thêm một cột GUID vào bảng khách hàng và biến nó thành khóa chính. Nếu cột số nhận dạng khách hàng hiện không còn đảm bảo duy nhất, bạn sẽ yêu cầu sự cố trong tương lai trong toàn tổ chức vì GUID sẽ luôn là duy nhất.

Một số "kiến trúc sư" có thể nói với bạn rằng "ồ, nhưng chúng tôi xử lý các ràng buộc về tính duy nhất của khách hàng thực sự trong tầng ứng dụng của chúng tôi!". Đúng. Thời trang liên quan đến ngôn ngữ lập trình mục đích chung đó và (đặc biệt) các khung trung cấp thay đổi mọi lúc, và nói chung sẽ không bao giờ tồn tại ngoài cơ sở dữ liệu của bạn. Và có một cơ hội rất tốt là một lúc nào đó bạn sẽ cần truy cập vào cơ sở dữ liệu mà không cần thông qua ứng dụng hiện tại. == Rắc rối. (Nhưng may mắn thay, bạn và "kiến trúc sư" đã qua lâu, vì vậy bạn sẽ không ở đó để dọn dẹp mớ hỗn độn.) Nói cách khác: Đừng duy trì các ràng buộc rõ ràng trong cơ sở dữ liệu (và trong các tầng khác, nếu bạn có thời gian).

Nói cách khác: Có thể có lý do chính đáng để thêm các cột GUID vào các bảng, nhưng vui lòng không bị cám dỗ để làm giảm tham vọng của bạn về tính nhất quán trong thông tin thực (== không phải GUID).


1
Nghe nghe! Yêu trang so sánh SQL của bạn btw. Vô cùng hữu ích. Điều duy nhất tôi nhớ là một thay đổi.
Henrik Gustafsson

3
Tôi nghĩ rằng câu trả lời này cần một số giải thích rõ ràng: điều này giả định rằng UUID không bao giờ được sử dụng làm khóa chính. Tôi không biết giả định này đến từ đâu, nhưng tôi chưa thấy một hệ thống nào không cho phép bạn sử dụng chúng như vậy. Tôi biết đó là một câu trả lời cũ, tôi cho rằng những lợi ích của việc sử dụng UUID trong các hệ thống phân tán không được hiểu rộng rãi vào thời điểm đó (?).
tne

12

Tại sao không ai đề cập đến hiệu suất? Khi bạn có nhiều lần tham gia, tất cả dựa trên những GUID khó chịu này, hiệu suất sẽ đi qua sàn, đã ở đó :(


1
Bạn có thể giải thích vấn đề này như trong tình huống tôi cần giới thiệu UUID (hoặc tương tự) không, nhưng lo ngại về việc sử dụng chúng làm Khóa chính.
JoeTidee

1
UUID chỉ có kích thước gấp 4 lần số nguyên ... (nếu cơ sở dữ liệu của bạn có loại UUID)
Jasen

11

GUID có thể gây ra cho bạn rất nhiều rắc rối trong tương lai nếu chúng được sử dụng làm "bộ giải mã", cho phép dữ liệu trùng lặp vào bảng của bạn. Nếu bạn muốn sử dụng GUID, vui lòng xem xét vẫn duy trì các ràng buộc KHÔNG GIỚI HẠN trên (các) cột khác.


11
Đây là cốt lõi của vấn đề: Giới thiệu GUID làm cho bất kỳ hàng nào trở nên độc đáo. Nhưng các phần phi nhân tạo của các hàng có thể đột nhiên chứa các bản sao (một số phiên bản của sự thật).
Quân đội Arvin

8
+1 để bù lại. Tôi hiểu ý của bạn, nhưng nó thể hiện rất tệ.
Stefano Borini

11

Ưu điểm chính là bạn có thể tạo id duy nhất mà không cần kết nối với cơ sở dữ liệu. Và id là duy nhất trên toàn cầu để bạn có thể dễ dàng kết hợp dữ liệu từ các cơ sở dữ liệu khác nhau. Đây có vẻ như là những lợi thế nhỏ nhưng đã giúp tôi tiết kiệm rất nhiều công việc trong quá khứ.

Nhược điểm chính là cần thêm một chút dung lượng (không phải là vấn đề trên các hệ thống hiện đại) và id không thực sự có thể đọc được. Đây có thể là một vấn đề khi gỡ lỗi.

Có một số vấn đề về hiệu suất như phân mảnh chỉ số. Nhưng đó là những giá trị có thể giải quyết được (các hướng dẫn kết hợp của jimmy nillson: http://www.informit.com/articles/article.aspx?p=25862 )

Chỉnh sửa hợp nhất hai câu trả lời của tôi cho câu hỏi này

@Matt Sheppard Tôi nghĩ rằng anh ta có nghĩa là bạn có thể nhân đôi các hàng với các GUID khác nhau làm khóa chính. Đây là một vấn đề với bất kỳ loại khóa thay thế nào, không chỉ GUID. Và như ông nói, nó được giải quyết dễ dàng bằng cách thêm các ràng buộc duy nhất có ý nghĩa vào các cột không quan trọng. Cách khác là sử dụng khóa tự nhiên và những người có vấn đề thực sự ..


Tôi biết về các hướng dẫn lược và những trợ giúp giải quyết vấn đề lập chỉ mục (hiệu suất INSERT). " nhược điểm chính là cần thêm một chút dung lượng lưu trữ " Điều này có ảnh hưởng đến hiệu suất do kích thước tệp cơ sở dữ liệu lớn không?
Amit Joshi

8

Một vấn đề nhỏ khác cần xem xét khi sử dụng GUIDS làm khóa chính nếu bạn cũng đang sử dụng cột đó làm chỉ mục cụm (một thực tế tương đối phổ biến). Bạn sẽ thực hiện một cú nhấn khi chèn vì bản chất của một hướng dẫn không bắt đầu tuần tự trong bất kỳ cách nào, do đó chúng sẽ được chia trang, vv khi bạn chèn. Chỉ cần một cái gì đó để xem xét nếu hệ thống sẽ có IO cao ...


6

khóa chính-ids so với hướng dẫn

Chi phí của GUID làm khóa chính (SQL Server 2000)

Huyền thoại, GUID so với Autoincrement (MySQL 5)

Đây thực sự là những gì bạn muốn.

Ưu điểm của UID

  • Duy nhất trên mọi bảng, mọi cơ sở dữ liệu, mọi máy chủ
  • Cho phép dễ dàng hợp nhất các bản ghi từ các cơ sở dữ liệu khác nhau
  • Cho phép dễ dàng phân phối cơ sở dữ liệu trên nhiều máy chủ
  • Bạn có thể tạo ID ở bất cứ đâu, thay vì phải làm tròn đến cơ sở dữ liệu
  • Hầu hết các kịch bản sao chép đều yêu cầu các cột GUID

Nhược điểm

  • Nó lớn hơn gấp 4 lần so với giá trị chỉ số 4 byte truyền thống; điều này có thể có tác động nghiêm trọng đến hiệu suất và lưu trữ nếu bạn không cẩn thận
  • Rườm rà để gỡ lỗi (trong đó userid = '{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • Các GUID được tạo phải được tuần tự một phần để có hiệu suất tốt nhất (ví dụ: new resultentialid () trên SQL 2005) và để cho phép sử dụng các chỉ mục được nhóm

1

Có một điều không thực sự được giải quyết, đó là sử dụng ID ngẫu nhiên (UUIDv4) làm khóa chính sẽ gây hại cho hiệu suất của chỉ mục khóa chính . Nó sẽ xảy ra cho dù bảng của bạn có được nhóm xung quanh khóa hay không.

Các RDBM thường đảm bảo tính duy nhất của các khóa chính và đảm bảo tra cứu bằng một khóa, trong cấu trúc có tên BTree, là cây tìm kiếm có hệ số phân nhánh lớn (cây tìm kiếm nhị phân có hệ số phân nhánh là 2). Bây giờ, ID số nguyên tuần tự sẽ khiến các lần chèn chỉ xảy ra một bên của cây, khiến hầu hết các nút lá không bị ảnh hưởng. Thêm các UUID ngẫu nhiên sẽ khiến các phần chèn thêm tách các nút lá trên toàn bộ chỉ mục.

Tương tự như vậy nếu dữ liệu được lưu trữ chủ yếu là tạm thời, thường thì dữ liệu gần đây nhất cần được truy cập và tham gia chống lại nhiều nhất. Với các UUID ngẫu nhiên, các mẫu sẽ không được hưởng lợi từ điều này và sẽ đạt được nhiều hàng chỉ mục hơn, do đó cần nhiều trang chỉ mục hơn trong bộ nhớ. Với ID tuần tự nếu cần dữ liệu gần đây nhất, các trang chỉ mục nóng sẽ cần ít RAM hơn.

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.