Bạn thích khóa chính của mình như thế nào? [đóng cửa]


88

Trong một cuộc thảo luận khá sôi nổi trong nhóm của mình, tôi đã được đưa ra để nghĩ những gì hầu hết mọi người thích làm khóa chính. Chúng tôi có các nhóm sau-

  1. Int / BigInt mà tự động gia tăng là khóa chính đủ tốt.
  2. Phải có ít nhất 3 cột tạo thành khóa chính.
  3. Id, GUID và số nhận dạng hàng có thể đọc được của con người, tất cả phải được xử lý khác nhau.

Cách tiếp cận tốt nhất cho PK là gì? Sẽ thật tuyệt nếu bạn có thể biện minh cho ý kiến ​​của mình. Có một cách tiếp cận tốt hơn như trên không?

CHỈNH SỬA: Có ai có mẫu / thuật toán đơn giản để tạo số nhận dạng con người có thể đọc được cho các hàng có tỷ lệ tốt không?


1
Vì đây là chủ quan, nó phải là một cộng đồng wiki
John Sheehan

2
"Cần có ít nhất 3 cột tạo nên khóa chính"? Điều đó có nghĩa là gì? Bạn có thể cung cấp thêm định nghĩa? Hay đây là một phần của # 3?
S.Lott

@ PK(NEWID(),NEWID(),NEWID())

@pst: Tại sao đây là một yêu cầu? Tại sao phải có ba cột trong PK? Tại sao một hoặc bốn?
S.Lott

Tôi có thể thấy PK ba cột trông giống như ... LocalID (Số tự động tăng dần), GlobalID (GUID), ForeignId (khóa ngoại như RolesType), v.v. LocalID + ForiegnId có thể là một tổ hợp phím ghép. Hướng dẫn được sử dụng cho các trang web / dịch vụ khác. Cá nhân tôi sẽ không làm điều này, tôi chỉ sử dụng Guid + ForiegnId.
Jerad,

Câu trả lời:


76

Nếu bạn định thực hiện bất kỳ đồng bộ hóa nào giữa các cơ sở dữ liệu với các ứng dụng được kết nối đôi khi thì bạn nên sử dụng GUID cho các khóa chính của mình. Đó là một sự khó khăn cho việc gỡ lỗi, vì vậy ngoài trường hợp đó, tôi có xu hướng bám vào các ints tự động tăng.

Ints autoincrement nên mặc định của bạn, và không sử dụng chúng nên được xưng công bình.


3
GUID là không cần thiết, chỉ cần thay đổi bước thành 10 hoặc 20 hoặc nhiều máy chủ mà bạn sẽ cần có thể đồng bộ hóa trong tương lai.
Robert C. Barth,

43
Ít nhất 90% thời gian, GUID là không cần thiết và lãng phí dung lượng.
Jonathan Leffler

8
Tôi thực sự cảm thấy GUIDs là một sự quá mức cần thiết. Chưa bao giờ tôi cần phải có GUID làm khóa chính của mình.
Cyril Gupta

7
Hoặc, thay vì lãng phí dung lượng và có nguy cơ va chạm với GUID, hãy tạo một khóa tổng hợp của khóa chính ban đầu và một số nhận dạng nhỏ, trong đó số nhận dạng nhỏ khác nhau đối với mỗi nguồn đồng bộ.
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

5
Một cửa hàng mà tôi đã làm việc để cung cấp các GUID đã qua sử dụng cho mọi thứ, ngay cả khi có sẵn số nhận dạng công khai, như mã quốc gia hoặc mã ngôn ngữ ISO. Và ngay cả khi boolean hoặc CHAR(1)sẽ là đủ, như cho sex. Không cần phải nói, đó là một cơn ác mộng để làm việc với.
Lumi

56

Tôi không thấy câu trả lời chỉ ra (điều mà tôi coi là) điểm thực sự cơ bản - cụ thể là khóa chính là thứ đảm bảo rằng bạn sẽ không nhận được hai mục nhập trong bảng cho cùng một thực thể trong thế giới thực (như được mô hình hóa trong cơ sở dữ liệu). Quan sát này giúp xác định đâu là lựa chọn tốt và đâu là lựa chọn không tốt cho khóa chính.

Ví dụ: trong một bảng tên và mã tiểu bang (Hoa Kỳ), tên hoặc mã có thể là khóa chính - chúng tạo thành hai khóa ứng cử viên khác nhau và một trong số chúng (thường là ngắn hơn - mã) được chọn làm khóa chính. Trong lý thuyết về các phụ thuộc hàm (và các phụ thuộc nối - 1NF đến 5NF - thì các khóa ứng viên là quan trọng hơn là một khóa chính.

Ví dụ ngược lại, tên người thường là một lựa chọn không tốt cho khóa chính. Có nhiều người sử dụng tên "John Smith" hoặc một số tên tương tự khác; thậm chí tính đến tên đệm (hãy nhớ: không phải ai cũng có - ví dụ như tôi thì không), có rất nhiều phạm vi để trùng lặp. Do đó, mọi người không sử dụng tên làm khóa chính. Họ phát minh ra các khóa nhân tạo như Số An sinh Xã hội (SSN) hoặc Số Nhân viên và sử dụng chúng để chỉ định cá nhân.

Một khóa chính lý tưởng là ngắn gọn, duy nhất, dễ nhớ và tự nhiên. Trong số các đặc điểm này, tính duy nhất là bắt buộc; phần còn lại phải linh hoạt với các ràng buộc của dữ liệu thế giới thực.

Do đó, khi nói đến việc xác định khóa chính của một bảng nhất định, bạn phải xem bảng đó đại diện cho những gì. Tập hợp hoặc tập hợp các giá trị cột nào trong bảng xác định duy nhất mỗi hàng trong bảng? Đó là những chìa khóa ứng cử viên. Bây giờ, nếu mỗi khóa ứng viên bao gồm 4 hoặc 5 cột, thì bạn có thể quyết định rằng những cột đó quá vụng về để tạo ra một khóa chính tốt (chủ yếu là do ngắn). Trong những trường hợp đó, bạn có thể giới thiệu khóa thay thế - một số được tạo nhân tạo. Rất thường xuyên (nhưng không phải luôn luôn) một số nguyên 32 bit đơn giản là đủ cho khóa thay thế. Sau đó, bạn chỉ định khóa đại diện này làm khóa chính.

Tuy nhiên, bạn vẫn phải đảm bảo rằng các khóa ứng viên khác (đối với khóa thay thế cũng là khóa ứng viên, cũng như khóa chính đã chọn) đều được duy trì dưới dạng mã định danh duy nhất - thông thường bằng cách đặt một ràng buộc duy nhất trên các tập hợp cột đó.

Đôi khi, mọi người cảm thấy khó khăn để xác định điều gì làm cho một hàng trở nên độc đáo, nhưng cần phải có điều gì đó để làm điều đó, bởi vì chỉ lặp lại một phần thông tin sẽ không làm cho nó đúng hơn nữa. Và nếu bạn không cẩn thận và nhận được hai (hoặc nhiều) hàng có mục đích lưu trữ cùng một thông tin và sau đó bạn cần cập nhật thông tin, sẽ có nguy cơ (đặc biệt nếu bạn sử dụng con trỏ) rằng bạn sẽ chỉ cập nhật một hàng hơn là mọi hàng, vì vậy các hàng không đồng bộ và không ai biết hàng nào chứa thông tin chính xác.

Đây là một quan điểm khá cứng rắn, ở một số khía cạnh.

Tôi không có vấn đề gì đặc biệt với việc sử dụng GUID khi chúng cần thiết, nhưng chúng có xu hướng lớn (như trong 16-64 byte) và chúng được sử dụng quá thường xuyên. Thường thì giá trị 4 byte hoàn toàn tốt là đủ. Sử dụng GUID trong đó giá trị 4 byte sẽ đủ làm lãng phí dung lượng đĩa và làm chậm truy cập vào dữ liệu được lập chỉ mục ngay cả vì có ít giá trị hơn trên mỗi trang chỉ mục, vì vậy chỉ mục sẽ sâu hơn và nhiều trang hơn phải được đọc để truy cập thông tin.


10
Về mẫu của bạn có tên tiểu bang Hoa Kỳ, tôi muốn có một khóa thay thế riêng, đơn giản vì mã là thứ nằm ngoài tầm kiểm soát của bạn. Nếu họ nên thay đổi vì bất kỳ lý do gì bạn gặp sự cố.
Dirk Vollmar

(tiếp theo) Ví dụ, Đức đã thay thế hệ thống mã zip 4 chữ số bằng hệ thống 5 chữ số vào những năm 1990 sau khi tái thống nhất.
Dirk Vollmar

@divo: Tôi là một người ủng hộ mạnh mẽ các khóa nhân tạo / thay thế, nhưng ngay cả khi tôi không thấy sự thay đổi mã bưu chính 4 chữ số thành 5 chữ số là một ví dụ điển hình. Mã bưu điện thường không được sử dụng làm chìa khóa cho bất cứ thứ gì. (Lần cuối cùng bạn phải truy vấn bảng Mã Bưu điện để tìm hiểu điều gì đó về mã đó là khi nào? Không, nó hầu như chỉ được sử dụng như một phần của địa chỉ mà không được tham chiếu trong bất kỳ bảng nào khác. Tôi sẽ nói rằng đề xuất của bạn gần như ngang bằng với việc sử dụng thay thế khóa cho chính địa chỉ.)
ErikE

@Emtucifor: Vâng, có thể ZIP không phải là một ví dụ thực tế, nhưng quan điểm của tôi là nếu một phần của khóa thay thế nằm ngoài tầm kiểm soát của bạn và thay đổi vì bất kỳ lý do gì, bạn đang gặp rắc rối. Hãy nghĩ đến việc ai đó tạo ra một sơ đồ số an sinh xã hội mới, một sơ đồ ISSN mới hoặc - có thể thực tế hơn - một công ty quyết định tạo một hệ thống id sản phẩm mới sau khi hợp nhất, chỉ định số nhân viên mới cho nhân viên của họ để điều chỉnh mức tăng trưởng của họ, v.v. Đây là tất cả chỉ là những ví dụ hư cấu, nhưng, như ví dụ trước đây của tôi với ZIP cho thấy, đôi khi một hệ thống được thiết lập tốt có thể thay đổi.
Dirk Vollmar

2
Điểm đầu tiên của bạn là đúng. Có một tên cho ràng buộc này. Nó được gọi là "tính toàn vẹn của thực thể". EI yêu cầu mọi thực thể phải có một danh tính riêng. Các khóa chính thường đáp ứng yêu cầu này, ngoại trừ khi sử dụng tự động đánh số. Với số tự động, bạn có thể nhận được hai hàng giống nhau, ngoại trừ số tự động. Điều này thường vi phạm tính toàn vẹn của thực thể.
Walter Mitty

26

Đây chỉ là một vấn đề tôn giáo bởi vì mọi người tìm kiếm một câu trả lời đúng phổ quát. Thực tế là cả nhóm của bạn và chủ đề SO này cho thấy rất nhiều bất đồng nên là manh mối cho thấy có lý do chính đáng để sử dụng tất cả các giải pháp bạn mô tả, trong các trường hợp khác nhau.

  • Khóa thay thế hữu ích khi không có thuộc tính hoặc tập hợp thuộc tính nào khác trong bảng phù hợp để xác định duy nhất các hàng.
  • Các phím tự nhiên được ưu tiên, khi có thể, để làm cho bảng dễ đọc hơn. Khóa tự nhiên cũng cho phép khóa ngoại trong bảng phụ thuộc chứa giá trị thực thay vì id đại diện. Ví dụ: khi bạn cần lưu trữ state(CA, TX, NY), bạn cũng có thể sử dụng char(2)khóa tự nhiên thay vì int.
  • Sử dụng khóa chính ghép nếu thích hợp. Không thêm idkhóa thay thế "" một cách không cần thiết khi tồn tại một khóa ghép hoàn toàn tốt (điều này đặc biệt đúng trong nhiều bảng). Nhiệm vụ cho một khóa ba cột trong mọi bảng là hoàn toàn vô nghĩa.
  • GUID là một giải pháp khi bạn cần duy trì tính duy nhất trên nhiều trang web. Chúng cũng hữu ích nếu bạn cần các giá trị trong khóa chính là duy nhất, nhưng không được sắp xếp theo thứ tự hoặc liên tiếp.
  • INT so với BIGINT: không phổ biến khi một bảng yêu cầu phạm vi 64 bit cho các khóa chính, nhưng với sự sẵn có ngày càng tăng của phần cứng 64 bit, nó không phải là gánh nặng và đảm bảo hơn rằng bạn sẽ không bị tràn. INT tất nhiên là nhỏ hơn, vì vậy nếu không gian ở mức cao, nó có thể mang lại một chút lợi thế.

6
Tôi không đồng ý nhiều như một người có thể làm như vậy. Phím tự nhiên thật kinh khủng. Nếu một người muốn thay đổi dữ liệu thì sao? Ồ, bạn không thể. Viết các phép nối trên các phím tự nhiên tổng hợp là một điều khó khăn. Mang theo khóa tổng hợp đó cho tất cả các bảng liên quan của bạn là một sự lãng phí.
Robert C. Barth,

2
@Robert: đọc về "CẬP NHẬT CASCADE". Nhưng tôi hiểu những gì bạn đang nói và tôi đồng ý rằng tốt nhất bạn nên sử dụng khóa thay thế hầu hết thời gian, vì các thuộc tính có thể thay đổi và không phải là duy nhất.
Bill Karwin

1
Các khóa chính phải là bất biến. Trong trường hợp này, các bản cập nhật Cascade chỉ là một bản hack xấu xí cho một quyết định thiết kế tồi. Các phím tự nhiên KHÔNG BAO GIỜ được ưa thích. Tương tự với các khóa tổng hợp, chúng tự lây lan như một bệnh dịch. Bất kỳ ai có hơn 3 tháng kinh nghiệm phát triển cơ sở dữ liệu sẽ biết điều này.
FDCastel

7
@FD: Tôi không đồng ý với tuyên bố rõ ràng của bạn và tôi đã phát triển với cơ sở dữ liệu SQL từ năm 1992. Nhưng chắc chắn đúng là khóa thay thế tốt nhất có thể không thay đổi.
Bill Karwin

20

Tôi thích blog Lập trình cơ sở dữ liệu như một nguồn cho loại thông tin này.

3 cột cho một khóa chính? Tôi sẽ nói rằng các cột phải có các ràng buộc duy nhất thích hợp theo yêu cầu của các quy tắc nghiệp vụ, nhưng tôi vẫn có một khóa đại diện riêng. Khóa ghép có nghĩa là logic nghiệp vụ nhập vào khóa. Nếu logic thay đổi, toàn bộ lược đồ của bạn đã bị hỏng.


2
Họ thay đổi liên kết của họ, đây là dấu Cập nhật: database-programmer.blogspot.com/2008/09/...
Bryan Rehbein

Chỉ được thừa hưởng một dự án như thế này. Và điều đầu tiên họ muốn làm là làm nổ tung lược đồ. Phím thay thế FTW. Logic kinh doanh trong DB FTL của bạn.
Jason


11

Hơi lạc đề, nhưng tôi cảm thấy bắt buộc phải hòa vào ...

Nếu khóa chính của bạn là một GUID, đừng đặt nó thành một chỉ mục nhóm . Vì các GUID không tuần tự, dữ liệu sẽ được sắp xếp lại trên đĩa trong hầu hết mọi lần chèn. (Yuck.) Nếu sử dụng GUID làm khóa chính, chúng phải là các chỉ mục không phân biệt.


1
Điểm rất tốt - người ta cần phân biệt giữa khái niệm LOGICAL của khóa chính (có thể hợp lệ để sử dụng GUID cho điều đó, đặc biệt nếu có liên quan đến sao chép) và khái niệm VẬT LÝ của khóa phân cụm - mà KHÔNG BAO GIỜ phải là GUID vì nó dẫn đến sự phân mảnh chỉ số quá mức
marc_s

3
Điều này trong thực tế là không chính xác. Dữ liệu sẽ được chèn theo thứ tự, do tính chất ngẫu nhiên của GUID có thể cuối cùng ở bất kỳ đâu trên bảng. Nếu không có chỗ trống, chia trang sẽ xảy ra, nhưng chắc chắn không "sắp xếp lại trên đĩa trong mỗi lần chèn" thậm chí không đóng.
Ralph Shillington

@Ralph, bạn nói đúng, không phải MỌI lần chèn, nhưng đủ để gây ra hiệu suất gấp 20 lần. sql-server-performance.com/articles/per/…
Portman

Hàm newsequentialid () của SQL Server giải quyết vấn đề phân mảnh chỉ mục với GUID (mặc dù 24 byte vẫn là quá nhiều nếu bạn không thực sự cần tính duy nhất toàn cục). Xem msdn.microsoft.com/en-us/library/ms189786.aspx.
ErikE

10

Tôi luôn sử dụng chìa khóa thay thế. Khóa thay thế (thường là cột nhận dạng, tự động gia tăng hoặc GUID) là khóa trong đó khóa không có trong chính dữ liệu. Mặt khác, khóa tự nhiên là khóa tự nó xác định hàng duy nhất. Gần như tôi có thể nói trong cuộc sống, hầu như không có bất kỳ chìa khóa tự nhiên thực sự nào . Thậm chí không phải những thứ như SSN ở Hoa Kỳ là một chìa khóa tự nhiên. Khóa chính tổng hợp là một thảm họa đang chực chờ xảy ra. Bạn không thể chỉnh sửa bất kỳ dữ liệu nào trong số đó (đó là nhược điểm chính của bất kỳ khóa tự nhiên nào, tổ hợp hay không), nhưng tệ hơn là với khóa tổng hợp, bây giờ bạn phải lưu trữ dữ liệu chính đó vào mọi bảng liên quan. Thật là một sự lãng phí khổng lồ.

Bây giờ, để lựa chọn khóa thay thế, tôi gắn bó với các cột nhận dạng (tôi chủ yếu làm việc trong MS SQL Server). Của GUID là quá lớn và Microsoft khuyến cáo chống lại việc sử dụng chúng như một PK. Nếu bạn có nhiều máy chủ, tất cả những gì bạn cần làm là tăng 10 hoặc 20 hoặc bất cứ điều gì bạn nghĩ là số lượng máy chủ tối đa bạn sẽ cần để đồng bộ hóa / mở rộng và chỉ cần nhập hạt giống cho mỗi bảng trên mỗi máy chủ tiếp theo và bạn sẽ không bao giờ có xung đột dữ liệu.

Tất nhiên, vì số gia tăng, tôi đặt cột nhận dạng là BigInt (hay còn gọi là [64 bit] dài).

Thực hiện một chút phép toán, ngay cả khi bạn tăng thêm 100, bạn vẫn có thể có 92,233,720,368,547,758 (> 92 phần tư) hàng trong bảng của mình.


9

Tôi nghĩ rằng việc sử dụng từ "Chính", trong cụm từ "Chính" theo nghĩa thực tế, gây hiểu lầm.

Trước tiên, hãy sử dụng định nghĩa rằng "khóa" là một thuộc tính hoặc tập hợp các thuộc tính phải là duy nhất trong bảng,

Sau đó, có bất kỳ khóa nào phục vụ một số mục đích thường không nhất quán lẫn nhau.

  1. Để sử dụng như nối các điều kiện với một hoặc nhiều bản ghi trong bảng con có mối quan hệ với bảng mẹ này. (Xác định rõ ràng hoặc ngầm định Khóa ngoại trong các bảng con đó)
  2. (liên quan) Đảm bảo rằng các bản ghi con phải có bản ghi mẹ trong tab mẹ; e (Bảng con FK phải tồn tại dưới dạng Khóa trong bảng mẹ)
  3. Để tăng lưu lượng truy vấn cần xác định nhanh một bản ghi / hàng cụ thể trong bảng.

  4. Để đảm bảo tính nhất quán của dữ liệu bằng cách ngăn các hàng trùng lặp đại diện cho cùng một thực thể logic không được chèn vào bên trong bảng. (Đây thường được gọi là khóa "tự nhiên" và phải bao gồm các thuộc tính bảng (thực thể) tương đối bất biến.)

Rõ ràng, bất kỳ khóa nào không có nghĩa, không phải tự nhiên (như GUID hoặc một số nguyên được tạo tự động hoàn toàn không có khả năng đáp ứng # 4.

Nhưng thông thường, với nhiều (hầu hết) bảng, một khóa hoàn toàn tự nhiên có thể cung cấp số 4 thường sẽ bao gồm nhiều thuộc tính và quá rộng hoặc quá rộng đến mức việc sử dụng nó cho các mục đích # 1, # 2 hoặc # 3 sẽ không được chấp nhận hệ quả hiệu suất.

Đáp án đơn giản. Sử dụng cả hai. Sử dụng khóa tích phân Tự động tạo đơn giản cho tất cả các Tham gia và FK trong các bảng con khác, nhưng đảm bảo rằng mọi bảng yêu cầu tính nhất quán dữ liệu (rất ít bảng không có) có một khóa duy nhất tự nhiên thay thế sẽ ngăn chặn việc chèn các hàng dữ liệu không nhất quán. .. Thêm vào đó, nếu bạn luôn có cả hai, thì tất cả những phản đối chống lại việc sử dụng khóa tự nhiên (nếu nó thay đổi thì sao? Tôi phải thay đổi mọi nơi mà nó được tham chiếu là FK) trở thành tranh luận, vì bạn không sử dụng nó cho việc đó. .. Bạn chỉ sử dụng nó trong một bảng nơi nó là PK, để tránh dữ liệu ghép đôi không nhất quán ...

Đối với GUID, hãy hết sức cẩn thận khi sử dụng chúng, vì việc sử dụng guids trong một chỉ mục có thể làm phân mảnh chỉ mục. Các thuật toán phổ biến nhất được sử dụng để tạo chúng đặt phần "ngẫu nhiên" của hướng dẫn ở các vị trí bit quan trọng nhất ... Điều này làm tăng yêu cầu chống phân mảnh chỉ mục / Lập chỉ mục lại khi các hàng mới được thêm vào.


Hàm newsequentialid () của SQL Server giải quyết vấn đề phân mảnh chỉ mục của các GUID (mặc dù 24 byte vẫn là quá nhiều nếu bạn không thực sự cần tính duy nhất toàn cầu). Xem msdn.microsoft.com/en-us/library/ms189786.aspx.
ErikE

rất tiếc, tôi định nói 16 byte.
ErikE

8

Một điều bạn không bao giờ nên làm là sử dụng chìa khóa thông minh. Đó là một khóa mà thông tin về bản ghi được mã hóa trong chính khóa và cuối cùng nó sẽ cắn bạn.

Tôi đã làm việc ở một nơi, nơi khóa chính là ID tài khoản, là sự kết hợp của các chữ cái và số. Tôi không nhớ bất kỳ chi tiết cụ thể nào, nhưng, ví dụ: những tài khoản thuộc một loại nhất định, sẽ nằm trong phạm vi 600 và một loại khác, bắt đầu bằng 400. Điều đó thật tuyệt, cho đến khi khách hàng đó quyết định yêu cầu cả hai các loại công việc. Hoặc thay đổi loại công việc họ đã làm.

Một nơi khác, đã sử dụng vị trí trong cây làm khóa chính cho các bản ghi. Vì vậy, sẽ có các bản ghi như sau.

Cat1.subcatA.record1
Cat1.subcatA.record2
Cat1.subcatB.record1
Cat2.subcatA.record1

Tất nhiên, điều đầu tiên khách hàng muốn là một cách để di chuyển các mặt hàng trên cây xung quanh. Toàn bộ bộ phần mềm đã chết trước khi điều đó xảy ra.

Làm ơn, làm ơn, làm ơn, nếu bạn đang viết mã mà tôi phải bảo trì, vui lòng không sử dụng chìa khóa thông minh!


Tôi đồng ý hết lòng. Smartkeys = ngu ngốc.
Robert C. Barth,

2
Điều này không có nghĩa là các phím tự nhiên bị câm. Nhưng điểm tốt.

4

Tôi là người yêu thích tính năng tự động tăng làm khóa chính. Tôi biết sâu trong trái tim mình rằng đây là một sự sao chép, nhưng nó làm cho việc sắp xếp dữ liệu trở nên dễ dàng theo thời điểm được thêm vào (ORDER BY ID DESC, f'r instance).

3 cột âm thanh khủng khiếp đối với phân tích cú pháp của con người.

Và đó là sự đánh đổi - bạn cần bao nhiêu khả năng quan hệ, so với việc đặt QUYỀN BẢNG NÀY TẠI ĐÂY có thể hiểu được đối với con người đang thẩm vấn nó (so với quy trình lưu trữ hoặc giao diện lập trình).

tự động gia tăng dành cho con người chúng ta. :-(


4

Nói chung, nó phụ thuộc.

Cá nhân, tôi thích ints autoincrement.

Tuy nhiên, một điều tôi có thể nói với bạn là đừng bao giờ tin tưởng dữ liệu từ các nguồn khác làm chìa khóa của bạn. Tôi thề, mỗi khi tôi làm vậy, nó lại quay lại cắn tôi. Chà, không bao giờ nữa!


3

Ít nhất phải có 3 cột tạo nên khóa chính.

Tôi không hiểu điều này.

Bạn đang nói về một "khóa tự nhiên", ví dụ: "tên và ngày sinh"? Khóa tự nhiên có thể là lý tưởng nếu nó tồn tại, nhưng hầu hết các ứng cử viên cho khóa tự nhiên hoặc không phải là duy nhất (nhiều người có cùng tên) hoặc không phải là hằng số (ai đó có thể thay đổi tên của họ).

Int / BigInt mà tự động gia tăng là khóa chính đủ tốt.

Tôi thích hướng dẫn hơn. Một vấn đề tiềm ẩn với tự động gia tăng là giá trị (ví dụ: "id đơn hàng") được gán bởi phiên bản cơ sở dữ liệu (ví dụ: "cơ sở dữ liệu bán hàng") ... sẽ không hoàn toàn hoạt động (thay vào đó bạn bắt đầu cần khóa ghép) nếu bạn cần hợp nhất dữ liệu được tạo bởi nhiều phiên bản cơ sở dữ liệu (ví dụ: từ một số văn phòng bán hàng, mỗi văn phòng có cơ sở dữ liệu riêng của họ).


Các khóa chính được yêu cầu là duy nhất, nhưng không bắt buộc phải không đổi. Do đó các khóa ngoại được khai báo bằng "ON UPDATE CASCADE". Nhưng giả định rằng các khóa chính là không đổi sẽ giúp đơn giản hóa nhiều ứng dụng. Đây là một lợi ích của khóa thay thế.
Bill Karwin

3

RE GUID's

Hãy để ý xem liệu đây có phải là một cơ sở dữ liệu lớn thực sự THỰC SỰ THỰC SỰ THỰC TẾ , nhiều tải và truy cập nhanh hay không.

Tại công việc cuối cùng của tôi, nơi chúng tôi có cơ sở dữ liệu từ 100 đến 500 triệu bản ghi, các nhân viên cơ sở dữ liệu của chúng tôi đã phản đối mạnh mẽ GUID và cho một số thập phân có kích thước phù hợp. Họ cảm thấy rằng (theo Oracle), sự khác biệt về kích thước trong bộ nhớ trong đối với một chuỗi Guid - so với giá trị thập phân sẽ tạo ra sự khác biệt rất đáng chú ý trong việc tra cứu. (Phím lớn hơn = cây sâu hơn để đi qua)

Bản chất ngẫu nhiên của GUID cũng làm giảm đáng kể hệ số lấp đầy cho các trang chỉ mục - điều này làm tăng đáng kể hiện tượng xé và I / O đĩa.


"Giảm hệ số lấp đầy"? Không chắc điều đó có nghĩa là gì Hệ số lấp đầy là thỏa thuận một lần, được định nghĩa là phần trăm không gian trống được yêu cầu ở cấp độ lá của chỉ mục tại thời điểm chỉ mục được tạo. Các giá trị GUID bằng cách phân phối bản chất ngẫu nhiên của chúng trên bề rộng của cấp độ lá khi chèn vào không gian trống mà hệ số lấp đầy cung cấp.
Ralph Shillington

1
Vì khi nào thì một GUID là một chuỗi? Các GUID nên được lưu trữ nội bộ dưới dạng 16 byte bởi bất kỳ DBMS đáng kính nào. Lưu trữ dưới dạng 32 byte trong biểu diễn hex sẽ là vô lương tâm! (hoặc 36 với dấu gạch ngang hoặc 38 với dấu ngoặc nhọn)
ErikE

2

Cột tăng tự động. Tôi có thể làm cho mã của mình hoạt động liền mạch với SQL Server hoặc Oracle, một mã sử dụng danh tính, mã kia sử dụng trình tự thông qua DAL của tôi và tôi không thể hạnh phúc hơn. Tôi đồng ý, GUID đôi khi cần thiết nếu bạn đang thực hiện sao chép hoặc gửi dữ liệu đi để nhận nó sau khi xử lý chậm hơn.


2

Tôi luôn sử dụng một khóa thay thế - một số nguyên tự động cộng dồn có tên là 'id'. Tôi có thể thấy rất nhiều lý do để làm điều này ngay cả khi một lựa chọn khác là rõ ràng:

  • Tính nhất quán
  • Dữ liệu độc lập (duy nhất, không bị phá hủy bởi các thay đổi đối với định dạng)
  • Con người có thể đọc được

... và không có lý do hợp lý nào để không:

  • Sự mơ hồ khi tham gia? - Đặt tên bảng là một phương pháp hay hơn, IMHO
  • Bảng tối ưu? - Loại bỏ một byte cho mỗi mục nhập là tối ưu hóa sớm, IMHO
  • Quyết định mỗi bàn? - Không còn nhất quán
  • Vấn đề về tỷ lệ? - Hở? Tại sao?
  • Cấu trúc dữ liệu phân cấp? - Đó là sự bất bình thường, một chủ đề hoàn toàn khác của tôn giáo. Đủ để nói rằng tôi là một fan hâm mộ trong một vài trường hợp trên lý thuyết, nhưng không bao giờ trong thực tế :)

những lý do hợp lý chống lại mà tôi chưa nghĩ ra hoặc chưa tìm ra luôn được hoan nghênh ...


1

Đây là một kinh điển "nó phụ thuộc". Không có câu trả lời đúng cho mọi dự án. Tôi thích những thứ khác nhau cho những tình huống khác nhau. Nó phụ thuộc vào việc tôi có đang sử dụng ORM hay không và nó hỗ trợ những gì. Nó phụ thuộc vào kiến ​​trúc tổng thể (phân phối hay không, v.v.). Chỉ cần chọn một cái mà bạn nghĩ sẽ hiệu quả và chuyển sang tranh luận về các tab và khoảng trắng.


Anh ấy vẫn muốn biết nó phụ thuộc như thế nào; chỉ với ý thức của những ai có thể đến tự tin tưởng của một người để lựa chọn ...
Nicholas Leonard

1

Tôi có xu hướng sử dụng tùy chọn # 1 hoặc # 3 tùy thuộc vào quy mô, số lượng người kết nối và liệu đó có phải là tình huống nhiều máy chủ cơ sở dữ liệu hay không.

Lựa chọn số 2 không có nhiều ý nghĩa đối với tôi. Nếu bất kỳ một trong ba bản ghi không đủ để xác định một bản ghi duy nhất, thì có thể (mà không cần trải qua các công đoạn bổ sung) hai bản ghi có hai bản ghi hiển thị với cùng giá trị trong cả ba cột. Nếu bạn muốn thực thi tính duy nhất trên bất kỳ kết hợp nào của cả ba, thì chỉ cần thêm chỉ mục cho chúng.


1

Tôi chỉ sử dụng int tự động tăng dần hoặc GUID. 99% thời gian tôi sử dụng int tự động tăng dần. Đó chỉ là những gì tôi được dạy để sử dụng khi tôi lần đầu tiên học về cơ sở dữ liệu và chưa bao giờ gặp phải lý do để không sử dụng chúng (mặc dù tôi biết lý do tại sao GUID sẽ tốt hơn).

Tôi thích số int tăng tự động vì nó giúp dễ đọc. Ví dụ, tôi có thể nói "hãy xem hồ sơ 129383" và ai đó khá dễ dàng truy cập và tìm thấy nó. Với một GUID, điều đó gần như không thể làm được.


2
tại sao bạn nói như vậy? Có vẻ như nhiều người sử dụng một số nguyên tăng tự động. Nó không thể tệ như vậy nếu nó hoạt động và hoạt động tốt cho những gì bạn cần.
dtc

1

Trước một câu trả lời định nghĩa cơ bản, điều gì tạo nên một khóa chính tốt phần lớn được để lại cho tôn giáo và phá vỡ các tranh luận. Nếu bạn có thứ gì đó đang và sẽ luôn ánh xạ duy nhất đến một hàng riêng lẻ, thì nó sẽ hoạt động tốt như một khóa chính. Sau thời điểm đó, có những cân nhắc khác:

  • Định nghĩa khóa chính không quá phức tạp phải không? Nó có tránh được sự phức tạp không cần thiết vì lợi ích của việc tuân theo "phương pháp hay nhất" không?
  • Có khóa chính nào tốt hơn có thể yêu cầu ít chi phí hơn để cơ sở dữ liệu xử lý (tức là INTEGER so với VARCHAR, v.v.) không?
  • Tôi có TUYỆT ĐỐI chắc chắn rằng tính duy nhất và tính bất biến được xác định của khóa chính của tôi sẽ không thay đổi không?

Điều cuối cùng này có thể là thứ thu hút hầu hết mọi người sử dụng những thứ như GUID hoặc cột số nguyên tự tăng, bởi vì dựa vào những thứ như địa chỉ, số điện thoại, họ / tên, v.v., chỉ cần không cắt nó. Điều bất biến duy nhất về những người mà tôi có thể nghĩ đến là SSN, nhưng tôi thậm chí không chắc chắn 100% về những người còn lại mãi mãi là duy nhất.

Hy vọng rằng điều này sẽ giúp thêm một số rõ ràng ...


Có một số trường hợp lịch sử mà SSN không phải là duy nhất.
Bill Karwin,

1

Cách tôi tiếp cận khóa chính (và tôi cảm thấy là tốt nhất) là tránh có cách tiếp cận "mặc định". Điều này có nghĩa là thay vì chỉ gõ vào một số nguyên tự động tăng dần và gọi nó là một ngày, tôi xem xét vấn đề và nói "có cột hoặc nhóm cột nào sẽ luôn không có giá trị và sẽ không thay đổi không?" Nếu câu trả lời là có thì tôi thực hiện cách tiếp cận đó.


Điều đó có nghĩa là bạn 'tránh tự động tăng số nguyên bất cứ khi nào bạn có thể'? Sự hiểu biết của tôi là các chuyên gia trong ngành cho rằng hiệu suất tốt nhất trên cơ sở dữ liệu quy mô lớn đến từ các PK đơn cột có chữ ký tối thiểu, được lập chỉ mục, tăng dần.
Hardryv

1
Tôi luôn luôn nghĩ rằng các chuyên gia sử dụng công cụ tốt nhất cho công việc
Andrew G. Johnson

1

Hầu như luôn luôn là số nguyên.

Chúng có những lý do chính đáng khác ngoài việc xử lý nhỏ hơn / nhanh hơn. Bạn muốn viết ra - "404040" hay "3463b5a2-a02b-4fd4-aa0f-1d3c0450026c"?


Giá trị thứ hai có thể là một số nguyên, có thêm dấu gạch ngang và trong cơ số 16. Nhưng có, 404040 xử lý nhanh hơn GUID dài. Sau đó, một lần nữa, 0 thậm chí còn nhanh hơn để xử lý vì nó không yêu cầu một bit dữ liệu nào!
strager

1

Chỉ có một chút liên quan, nhưng một điều tôi đã bắt đầu làm gần đây khi tôi có các bảng phân loại nhỏ (về cơ bản là những bảng đại diện cho ENUM trong mã) là tôi sẽ đặt khóa chính thành char (3) hoặc char (4). Sau đó, tôi làm cho các khóa chính đó đại diện cho giá trị tra cứu.

Ví dụ: tôi có một hệ thống báo giá cho các Đại lý bán hàng nội bộ của chúng tôi. Chúng tôi có "Danh mục chi phí" mà mỗi mục hàng báo giá được chỉ định một trong ... Vì vậy, tôi có một bảng tra cứu loại được gọi là 'tCostCategories', trong đó khóa chính là 'MTL', 'SVC', 'TRV', 'TAX', 'ODC'. Các cột khác trong bảng tra cứu lưu trữ thêm thông tin chi tiết, chẳng hạn như nghĩa tiếng Anh thông thường của các mã, "Vật liệu", "Dịch vụ", "Du lịch", "Thuế", "Chi phí Trực tiếp khác", v.v.

Điều này thực sự tốt vì nó không sử dụng nhiều không gian hơn int và khi bạn đang xem dữ liệu nguồn, bạn không cần phải liên kết bảng tra cứu để biết giá trị là bao nhiêu. Ví dụ: một hàng trích dẫn có thể giống như sau:

1 PhầnSố $ 40 MTL
2 Phần khácSố $ 29,99 SVC
3 PhầnSố2 $ 150 TRV

Việc sử dụng int để đại diện cho các danh mục và sau đó liên kết 1, 2, 3 trên tất cả các dòng sẽ dễ dàng hơn nhiều - bạn có dữ liệu ngay trước mặt mình và hiệu suất dường như không bị ảnh hưởng (không phải vậy. đã được thử nghiệm thực sự.)

Theo như câu hỏi thực sự đi ... Tôi thích các bộ bảo mật độc đáo RowGUID. Tôi không phải 100% về điều này, nhưng không phải tất cả các hàng đều có RowGuid nội bộ ?? Nếu vậy, thì việc sử dụng RowGuid sẽ thực sự chiếm ít không gian hơn int (hoặc bất kỳ thứ gì khác cho vấn đề đó.) Tất cả những gì tôi biết là nếu nó đủ tốt để M $ sử dụng trong GreatPlains thì nó đủ tốt cho tôi. (Tôi có nên vịt không ??)


1

Ồ, một lý do nữa khiến tôi sử dụng GUID - tôi sử dụng cấu trúc dữ liệu phân cấp. Đó là, tôi có một bảng "Công ty" và một bảng "Nhà cung cấp" mà các Khóa chính khớp với nhau. Nhưng tôi cũng có một bảng 'Nhà sản xuất' cũng 'kế thừa' từ Công ty. Các trường chung cho Nhà cung cấp và Nhà sản xuất không xuất hiện trong các bảng đó - chúng xuất hiện trong Công ty. Trong thiết lập này, sử dụng int sẽ khó hơn nhiều so với Guids. Ít nhất, bạn không thể sử dụng khóa chính danh tính.


1
Có, bạn có thể, bạn chỉ không làm cho các bảng kiểu con có thuộc tính nhận dạng, thay vào đó, chúng nhận được các phần chèn rõ ràng của giá trị bảng siêu kiểu. Vui lòng xem stackoverflow.com/questions/2112882/…
ErikE

1

Tôi thích những phím tự nhiên, bất cứ khi nào tôi có thể tin tưởng chúng. Tôi sẵn sàng trả một mức giá hiệu suất nhỏ để sử dụng các phím có ý nghĩa đối với các chuyên gia về vấn đề này.

Đối với các bảng mô tả các thực thể, cần có một khóa tự nhiên đơn giản xác định các trường hợp riêng lẻ giống như cách mà mọi người làm. Nếu chủ đề không có số nhận dạng đáng tin cậy cho một trong các thực thể, thì tôi sẽ sử dụng khóa thay thế.

Đối với các bảng mô tả mối quan hệ, tôi sử dụng một khóa ghép, trong đó mỗi thành phần tham chiếu đến một thực thể tham gia vào mối quan hệ và do đó là một hàng trong bảng thực thể. Một lần nữa, hiệu suất đạt được khi sử dụng phím ghép thường là tối thiểu.

Như những người khác đã chỉ ra, thuật ngữ "khóa chính" hơi gây hiểu nhầm. Trong Mô hình dữ liệu quan hệ, thuật ngữ được sử dụng là "khóa ứng viên". Có thể có một số khóa ứng viên cho một bảng. Về mặt logic, mỗi cái cũng tốt như cái khác. Chọn một trong số chúng làm "chính" và tạo tất cả các tham chiếu thông qua khóa đó chỉ đơn giản là một lựa chọn mà nhà thiết kế có thể thực hiện.


Hãy mô tả một số mẫu khóa tự nhiên đáng tin cậy?
ErikE

1
"đáng tin cậy" không phải là thuộc tính của một chìa khóa. Thay vào đó, nó liên quan đến chìa khóa trong bối cảnh của những người cung cấp dữ liệu. Nếu bạn đang viết một ứng dụng để bán cho ai đó thực sự sẽ quản lý dữ liệu, bạn phải đoán xem khóa nào sẽ đáng tin cậy đối với khách hàng hay không. Với sự đa dạng của khách hàng, bạn gần như chắc chắn sẽ đoán sai đối với một số khách hàng của mình.
Walter Mitty

Đã nói ở trên, đây là một ví dụ về một chìa khóa mà chúng tôi đã tin tưởng vào thời điểm đó. Chúng tôi đã có một cơ sở dữ liệu về các khóa học. Nó bao gồm sách giáo khoa và các tài liệu khóa học khác về các khóa học, chương trình cung cấp khóa học theo lịch trình, những người hướng dẫn đủ điều kiện để giảng dạy khóa học, điều kiện tiên quyết của khóa học, học phí, v.v. Khi phát triển khóa học tạo ra một khóa học mới, một trong những điều đầu tiên họ làm là gán mã khóa học. Họ chịu trách nhiệm đảm bảo rằng mã khóa học là duy nhất và các khóa học không bao giờ thay đổi mã của họ, một khi đã được chỉ định. Đó là một phần của dữ liệu được cung cấp cho chúng tôi.
Walter Mitty

Một ví dụ điển hình khác về khóa tự nhiên đáng tin cậy là VIN (Số nhận dạng xe). Trong nhiều năm qua, mọi chiếc xe được bán như mới đều có số VIN gắn trên đó. Chúng có thể được tin tưởng là duy nhất và không thay đổi.
Walter Mitty

1

Guids.period.

Trong trường hợp bạn cần mở rộng quy mô hoặc bạn cần chỉ định khóa chính bằng cách thay thế, họ sẽ là bạn của bạn. Bạn có thể thêm chỉ mục cho mọi thứ khác.


cập nhật để làm rõ tuyên bố của tôi.

Tôi đã làm việc trên rất nhiều loại trang web khác nhau. Từ các giao dịch máy chủ đơn lẻ nhỏ đến các giao dịch lớn được hỗ trợ với nhiều máy chủ DB và web. Chắc chắn đã có những ứng dụng hoạt động tốt với việc tự động tăng int làm khóa chính. Tuy nhiên, những điều đó không phù hợp với mô hình cách tôi làm mọi việc.

Khi sử dụng GUID, bạn có thể tạo ID ở bất kỳ đâu. Nó có thể được tạo bởi một máy chủ từ xa, ứng dụng web của bạn, trong chính cơ sở dữ liệu hoặc thậm chí trong nhiều cơ sở dữ liệu trong tình huống đa quản trị viên.

Mặt khác, INT tự động tăng dần chỉ có thể được tạo một cách an toàn trong cơ sở dữ liệu chính. Một lần nữa, điều này thể ổn nếu bạn có một ứng dụng sẽ được liên kết mật thiết với một máy chủ DB hỗ trợ và việc mở rộng quy mô không phải là điều bạn lo lắng.

Chắc chắn, việc sử dụng GUID có nghĩa là bạn phải có quy trình lập chỉ mục hàng đêm. Tuy nhiên, nếu bạn đang sử dụng bất kỳ thứ gì khác ngoài INT tăng tự động, bạn nên làm điều đó. Rất tiếc, ngay cả với INT là chính, có khả năng bạn có các chỉ mục khác cần được tạo lại để đối phó với sự phân mảnh. Do đó, việc sử dụng GUID không chính xác thêm một vấn đề khác vì những tác vụ đó cần được thực hiện bất kể.

Nếu bạn nhìn vào các ứng dụng lớn hơn hiện có, bạn sẽ nhận thấy một điều quan trọng: tất cả chúng đều sử dụng GUID được mã hóa Base64 làm chìa khóa. Lý do cho điều này là đơn giản, sử dụng GUID cho phép bạn mở rộng ra một cách dễ dàng trong khi có thể có rất nhiều hoops để nhảy qua khi cố gắng mở rộng ra INTs.

Ứng dụng mới nhất của chúng tôi trải qua giai đoạn chèn nặng kéo dài khoảng một tháng. Sau đó, 90 +% số truy vấn được chọn để báo cáo. Để tăng dung lượng, tôi có thể cung cấp thêm các máy chủ DB trong khoảng thời gian chèn lớn này; và sau đó dễ dàng hợp nhất chúng thành một DB duy nhất để báo cáo. Cố gắng làm điều đó với INTs sẽ là một cơn ác mộng tuyệt đối.

Thành thật mà nói, bất cứ khi nào bạn phân cụm cơ sở dữ liệu hoặc thiết lập sao chép, máy chủ DB sẽ yêu cầu bạn có các GUID trên bảng. Vì vậy, nếu bạn nghĩ rằng hệ thống của mình có thể cần phải phát triển thì hãy chọn cái tốt.


Bạn đã bao giờ kiểm tra hệ số lấp đầy của các chỉ số của mình chưa? Bản chất ngẫu nhiên của GUID làm phô mai Thụy Sĩ - làm giảm đáng kể hiệu quả của chúng.
stephbu

2
"Guids.period": Điều đó thật sai lầm. GUID nên được sử dụng khi thích hợp. Như người bình luận khác đã chỉ ra, nó có thể giúp cuộc sống của một lập trình viên trở nên dễ dàng, nhưng ảnh hưởng đến kích thước và hiệu suất tổng thể của DB.
Mitch Wheat

Vào cuối ngày, tôi có thể mở rộng ứng dụng của mình trên nhiều máy chủ cơ sở dữ liệu mà không gặp vấn đề gì. Nhưng tôi đoán các bạn làm việc trên các trang web nhỏ.
NotMe

3
GUID có thể được ok cho khóa chính hợp lý, nhưng không bao giờ bao giờ bao giờ sử dụng một cột GUID như chìa khóa Clustering của bạn - bạn sẽ được chìm đắm trong sự phân mảnh chỉ số dẫn đến hiệu suất kém .....
marc_s

Tôi chắc chắn sẽ không công bố "Guids.period." về chủ đề này - trên thực tế, ngay cả trong một ngành có đầy rẫy những 'phương pháp hay nhất' mà loại tuyên bố đó khiến bạn rơi vào tình trạng lung lay theo mặc định (đặc biệt là với tuyên bố đó). Bất cứ điều gì khó khăn như GUID đều cần một số lời biện minh cứng rắn và như JL nói, tôi nghĩ hầu hết chúng ta sẽ coi đó là phương sách cuối cùng. Nó như thể bạn đã đăng mà không đọc phần còn lại của chủ đề.
Hardryv

0

Đây là một chủ đề phức tạp cho dù bạn có nhận ra hay không. Có thể nằm trong phần trên Câu hỏi thường gặp về StackOverflow này.

Những loại câu hỏi tôi không nên hỏi ở đây?

Tránh đặt những câu hỏi mang tính chủ quan, tranh luận hoặc yêu cầu thảo luận mở rộng. Đây là nơi dành cho những câu hỏi có thể được trả lời!

Điều này đã được tranh luận trong nhiều năm và sẽ tiếp tục được tranh luận trong nhiều năm. Các gợi ý đồng thuận duy nhất mà tôi đã thấy là các câu trả lời có thể đoán được phần nào tùy thuộc vào việc bạn có đang hỏi một anh chàng OO hay không (GUID là cách duy nhất để đi!), Một người lập mô hình dữ liệu (Khóa tự nhiên là cách duy nhất để đi!), hoặc DBA định hướng hiệu suất (INT là cách duy nhất để thực hiện!).


Tôi sẽ không để cuộc thảo luận kéo dài. Tôi chỉ tò mò muốn xem sự đồng thuận chung.
Perpetualcoder,

1
Tôi nói hãy hỏi bất cứ câu hỏi nào bạn muốn! Nếu không, cộng đồng này sẽ trở nên tĩnh và bị kiểm soát quá mức như wikipedia dường như đã trở thành. Đối với tôi, có vẻ như đôi khi bạn cần để mọi người hỏi bất cứ điều gì hãy chọn để hỏi. Hãy tin tưởng họ, và họ có thể tin tưởng chính mình!
Nicholas Leonard
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.