Thay thế so với khóa tự nhiên / doanh nghiệp [đã đóng]


173

Chúng ta lại đi, tranh luận cũ vẫn nảy sinh ...

Chúng ta nên có một khóa doanh nghiệp làm khóa chính hay chúng ta muốn có một id thay thế (tức là một danh tính SQL Server) với một ràng buộc duy nhất trên trường khóa doanh nghiệp?

Xin vui lòng, cung cấp các ví dụ hoặc bằng chứng để hỗ trợ lý thuyết của bạn.


24
@Joachim Sauer: Một cuộc tranh luận về việc liệu một sự vật có mang tính chủ quan hay không, có thể là chủ quan, không có điều này liên quan đến tính khách quan hay tính chủ quan của sự việc. Trừ khi bạn chuẩn bị để nêu các tiêu chí khách quan chính xác làm cho một cái gì đó khách quan. Có những thứ gọi là "khái niệm mở" như cần bao nhiêu sợi tóc để làm râu. Người ta có thể nói một cách khách quan rằng một người không có lông cằm không có râu và một người có 5.000 sợi tóc dài một inch có râu, nhưng đâu đó trong phán đoán chủ quan ở giữa là cần thiết để đưa ra quyết định khách quan.
ErikE

@Manrico: bạn chỉ cần tự hỏi mình điều này: nếu tôi không sử dụng khóa thay thế, liệu khóa chính của tôi có còn bất biến không? Nếu câu trả lời là không, thì bạn nên nghiêm túc xem xét sử dụng khóa thay thế. Ngoài ra, nếu khóa chính được tạo một phần thậm chí một phần từ đầu vào của người dùng, bạn nên xem xét sử dụng khóa thay thế. Tại sao? Bởi vì sự nguy hiểm của sự bất thường dữ liệu.
code4life

@TylerRick Nhưng đây không phải là một câu hỏi hoàn toàn tốt. Nó yêu cầu một giải pháp thường áp dụng cho mọi tình huống, khi rõ ràng không có một giải pháp nào, như đã được chứng minh bởi "cuộc chiến tôn giáo" mà người hỏi hoàn toàn nhận thức được (trích dẫn: "Ở đây chúng ta lại đi, lập luận cũ vẫn phát sinh. .. "). Thay vì tự hỏi liệu thế giới có thay đổi hay không và cuối cùng là một lý do thuyết phục để chọn một bên luôn được cung cấp, tốt hơn hết là bạn nên hỏi lại câu hỏi này cho từng tình huống cụ thể và gửi lên SO khi bạn không chắc chắn . Điều này chỉ gợi ra chủ nghĩa giáo điều.
MarioDS

Câu trả lời:


96

Cả hai. Có bánh của bạn và ăn nó.

Hãy nhớ rằng không có gì đặc biệt về khóa chính, ngoại trừ việc nó được dán nhãn như vậy. Nó không có gì khác hơn là một ràng buộc KHÔNG NULL UNIITE và một bảng có thể có nhiều hơn một.

Nếu bạn sử dụng khóa thay thế, bạn vẫn muốn khóa doanh nghiệp để đảm bảo tính duy nhất theo quy tắc kinh doanh.


7
Nếu bạn có nhiều khóa "ứng cử viên" (các trường hoặc bộ sưu tập các trường có cùng kích thước KHÔNG PHẢI LÀ ĐỘC ĐÁO) thì bạn có khả năng vi phạm Biểu mẫu bình thường Boyce-Codd. BCNF vượt quá 3NF, vì vậy không nhiều người lo lắng về nó. Tuy nhiên, có những tình huống khi ở trong BCNF là rất hữu ích.
Alan

2
Đã đồng ý. Câu hỏi thực sự là: Tôi có nên thêm khóa thay thế duy nhất vào các bảng của mình không? Một câu hỏi hoàn toàn khác là sử dụng gì cho khóa chính logic. Cả hai về cơ bản chỉ là các ràng buộc chỉ mục duy nhất không null.
dkretz

1
"Mọi vấn đề đều được giải quyết với một mức độ gián tiếp khác" ... Các khóa thay thế chỉ là: một mức độ không xác định khác
Steve Schnepp

5
Tôi thấy thật kỳ lạ khi nhiều ý kiến ​​dường như khẳng định rằng người ta không thể thiết lập mối quan hệ mà không có khóa thay thế. Trong nhiều trường hợp, khóa thay thế là không cần thiết. Tại sao thêm một cái gì đó không mang lại giá trị nhưng lại thêm nợ kỹ thuật (và trong một số trường hợp, gây ra một kết quả duy nhất khác đột nhiên trở thành không duy nhất).
Wil Moore III

2
Đó là nhiều hơn KHÔNG ràng buộc NULL UNIITE. Khóa chính được sử dụng như một chỉ mục được nhóm để xác định thứ tự vật lý của dữ liệu của bạn. Nói chung, Integer rất dễ cân bằng vì nó tăng dần theo tuần tự và dữ liệu của bạn sẽ nối vào EOF trên đĩa. Nếu bạn sử dụng ít dữ liệu tuần tự hơn như văn bản hoặc GUID (UUID), sẽ có nhiều IO hơn và nỗ lực để cân bằng chỉ số, tôi nghĩ đó là một sự khác biệt lớn
Jin

124

Chỉ một vài lý do để sử dụng khóa thay thế:

  1. Tính ổn định : Thay đổi khóa vì doanh nghiệp hoặc nhu cầu tự nhiên sẽ ảnh hưởng tiêu cực đến các bảng liên quan. Khóa thay thế hiếm khi, nếu có, cần phải được thay đổi bởi vì không có ý nghĩa gắn liền với giá trị.

  2. Quy ước : Cho phép bạn có một quy ước đặt tên cột Chính được tiêu chuẩn hóa thay vì phải suy nghĩ về cách tham gia các bảng với các tên khác nhau cho các PK của chúng.

  3. Tốc độ : Tùy thuộc vào giá trị và loại PK, khóa thay thế của một số nguyên có thể nhỏ hơn, nhanh hơn để lập chỉ mục và tìm kiếm.


2
Bây giờ, sau khi đọc rất nhiều về khóa thay thế và khóa tự nhiên, tôi nghĩ sử dụng khóa thay thế là tốt hơn. Nhưng, trên cơ sở dữ liệu của tôi, các khóa tự nhiên (một NVARCHAR (20)) phải là duy nhất. Tôi không hiểu làm thế nào tôi có thể tăng thêm tốc độ nếu tôi cần kiểm tra mọi dữ liệu trên cột đó để không lặp lại bất kỳ giá trị nào (sử dụng ràng buộc KHÔNG NULL UNIQUE) trên mỗi lần chèn.
VansFannel

70

Dường như chưa có ai nói bất cứ điều gì hỗ trợ cho các phím không thay thế (tôi ngần ngại nói các phím "tự nhiên"). Vì vậy, ở đây đi ...

Một nhược điểm của khóa thay thế là chúng vô nghĩa (được một số người coi là một lợi thế, nhưng ...). Điều này đôi khi buộc bạn phải tham gia nhiều bảng hơn vào truy vấn của mình hơn là thực sự cần thiết. Đối chiếu:

select sum(t.hours)
from timesheets t
where t.dept_code = 'HR'
and t.status = 'VALID'
and t.project_code = 'MYPROJECT'
and t.task = 'BUILD';

chống lại:

select sum(t.hours)
from timesheets t
     join departents d on d.dept_id = t.dept_id
     join timesheet_statuses s on s.status_id = t.status_id
     join projects p on p.project_id = t.project_id
     join tasks k on k.task_id = t.task_id
where d.dept_code = 'HR'
and s.status = 'VALID'
and p.project_code = 'MYPROJECT'
and k.task_code = 'BUILD';

Trừ khi bất cứ ai nghiêm túc nghĩ rằng sau đây là một ý tưởng tốt?:

select sum(t.hours)
from timesheets t
where t.dept_id = 34394
and t.status_id = 89    
and t.project_id = 1253
and t.task_id = 77;

"Nhưng" ai đó sẽ nói, "điều gì xảy ra khi mã cho MYPRO DỰ ÁN hoặc GIÁ TRỊ hoặc nhân sự thay đổi?" Câu trả lời của tôi sẽ là: "tại sao bạn cần thay đổi nó?" Đây không phải là các khóa "tự nhiên" theo nghĩa là một số cơ quan bên ngoài sẽ hợp pháp hóa từ đó 'GIÁ TRỊ' nên được mã hóa lại thành 'TỐT'. Chỉ một tỷ lệ nhỏ các khóa "tự nhiên" thực sự thuộc danh mục đó - mã SSN và Zip là các ví dụ thông thường. Tôi chắc chắn sẽ sử dụng một khóa số vô nghĩa cho các bảng như Người, Địa chỉ - nhưng không phải cho tất cả mọi thứ , vì một số lý do mà hầu hết mọi người ở đây dường như ủng hộ.

Xem thêm: câu trả lời của tôi cho một câu hỏi khác


14
-1 Các khóa tự nhiên làm khóa chính có một vấn đề là đối với mỗi bảng con, bạn phải thêm khóa của cha mẹ có thể được tạo bởi nhiều trường (thay vì chỉ một trường hợp là khóa thay thế) và cả khóa con Chìa khóa. Vì vậy, hãy tưởng tượng như sau khi bắt đầu từ TABLEA mối quan hệ là 1-0 .. *: TABLEA PK: ID_A TABLEB PK: ID_A ID_B TABLEC PK: ID_A ID_B ID_C TABLED PK: ID_A ID_B ID_C ID_D. Thấy vấn đề? Khóa cha được truyền trong các bảng con. Điều gì sẽ xảy ra nếu khóa chính của TABLEA thay đổi? Bây giờ bạn cũng sẽ phải cấu trúc lại tất cả các bảng con PK.
Alfredo Osorio

9
@Alfredo: tất nhiên là có sự đánh đổi. Tuy nhiên, trong hơn 20 năm kinh nghiệm của tôi, tôi hiếm khi thấy định nghĩa về thay đổi PK của bảng. Nếu nó xảy ra một cách thường xuyên, có lẽ tôi cũng sẽ tránh các phím tự nhiên. Trong thực tế, trong những dịp cực kỳ hiếm khi điều này xảy ra, tôi đã chuẩn bị sẵn sàng để nhận được tác động mở rộng.
Tony Andrew

10
Tôi không đồng ý. Nó thường là trường hợp một số cơ quan bên ngoài (khách hàng) quy định rằng một khóa tự nhiên cần phải được chỉnh sửa, và do đó được truyền bá trong toàn hệ thống. Tôi thấy điều này xảy ra thường xuyên. Cách duy nhất bạn có thể chắc chắn rằng khóa sẽ không bao giờ cần thay đổi là khi nó theo định nghĩa là vô nghĩa. Hơn nữa, các cơ sở dữ liệu hiện đại xử lý các phép nối bên trong cực kỳ hiệu quả, do đó, khả năng thu được không gian lớn từ việc sử dụng các chất thay thế thường vượt trội hơn lợi thế của việc không phải thực hiện nhiều liên kết bên trong.
TTT

8
@TTT: Sau đó, thiết kế đã yếu. Một lần nữa, đó là nơi đàn ông tách biệt với các chàng trai: đưa ra lựa chọn đúng đắn khi nào nên sử dụng chìa khóa tự nhiên và khi nào nên sử dụng thay thế. Bạn quyết định rằng trên cơ sở mỗi bàn, không phải là một giáo điều chung.
DanMan

7
Tôi cũng có hơn 20 năm kinh nghiệm và tôi tán thành ý kiến ​​của bạn. Tôi đã từng tạo ra một kho dữ liệu tiên tri với các khóa thay thế và bảo trì dữ liệu giống như địa ngục. Bạn chỉ đơn giản là không bao giờ có thể truy cập trực tiếp dữ liệu của bạn. bạn luôn cần phải viết các truy vấn cho tất cả mọi thứ và điều đó làm cho các khóa thay thế chỉ đơn giản là khủng khiếp để xử lý.
Cảnh sát SQL

31

Khóa thay thế sẽ KHÔNG BAO GIỜ có lý do để thay đổi. Tôi không thể nói như vậy về các phím tự nhiên. Họ, email, nubmer - tất cả đều có thể thay đổi một ngày.


31

Khóa thay thế (thường là số nguyên) có giá trị gia tăng giúp quan hệ bảng của bạn nhanh hơn và tiết kiệm hơn về tốc độ lưu trữ và cập nhật (thậm chí tốt hơn, không cần cập nhật khóa ngoại khi sử dụng khóa thay thế, trái ngược với trường khóa doanh nghiệp, điều đó thay đổi ngay bây giờ và sau đó).

Khóa chính của bảng nên được sử dụng để xác định duy nhất hàng, chủ yếu cho mục đích nối. Hãy nghĩ về bảng Người: tên có thể thay đổi và chúng không được bảo đảm là duy nhất.

Hãy nghĩ về các công ty: bạn là một công ty Merkin hạnh phúc khi làm việc với các công ty khác ở Merkia. Bạn đủ thông minh để không sử dụng tên công ty làm khóa chính, vì vậy bạn sử dụng ID công ty duy nhất của chính phủ Merkia trong toàn bộ 10 ký tự chữ và số. Sau đó Merkia thay đổi ID công ty vì họ nghĩ rằng đó sẽ là một ý tưởng tốt. Không sao, bạn sử dụng tính năng cập nhật xếp tầng của công cụ db của bạn, để thay đổi không liên quan đến bạn ngay từ đầu. Sau đó, doanh nghiệp của bạn mở rộng và bây giờ bạn làm việc với một công ty ở Freedonia. Id công ty Freedonia lên đến 16 ký tự. Bạn cần phóng to khóa chính id công ty (cũng là các trường khóa ngoại trong Đơn hàng, Sự cố, MoneyTransifts, v.v.), thêm trường Quốc gia vào khóa chính (cũng trong khóa ngoại). Ôi! Nội chiến ở Freedonia, nó ' S chia thành ba quốc gia. Tên quốc gia của cộng sự của bạn nên được đổi thành tên mới; xếp tầng cập nhật để giải cứu. BTW, khóa chính của bạn là gì? (Quốc gia, CompanyID) hoặc (CompanyID, Quốc gia)? Cái sau giúp tham gia, cái trước tránh một chỉ mục khác (hoặc có lẽ nhiều, nếu bạn muốn Đơn hàng của mình được nhóm theo quốc gia).

Tất cả những điều này không phải là bằng chứng, nhưng một dấu hiệu cho thấy khóa thay thế để xác định duy nhất một hàng cho tất cả các mục đích sử dụng, bao gồm cả hoạt động tham gia, thích hợp hơn là khóa doanh nghiệp.


Bạn giành được tất cả các internets với tên người dùng tuyệt vời nhất!
Người giữ Iain

1
Đó là khá nhiều những gì một downvote là: "Tôi không đồng ý với điều này."
jcollum

5
Chú giải công cụ của mũi tên xuống nói "Câu trả lời này không hữu ích", không phải "Tôi không đồng ý với điều này". Có lẽ trong câu trả lời cụ thể này, ý nghĩa rất gần gũi, nhưng chúng không giống nhau.
tzot

1
Nếu ai đó nghĩ rằng câu trả lời của bạn là sai, thì anh ấy / cô ấy cũng sẽ nghĩ rằng nó dẫn người hỏi đi sai hướng (ngược lại với hướng đúng), và do đó sẽ đánh giá câu trả lời của bạn thậm chí còn tệ hơn "vô ích", biện minh trong tâm trí của anh ấy / cô ấy một downvote.
Erwin Smout

1
Yup, chìa khóa thay thế là một căn bệnh. Một rò rỉ vào tự nhiên và bạn sử dụng nó như một con chìa khóa, vì vậy bây giờ bạn cần khóa thay thế của riêng bạn. Sau đó, khóa của bạn bị rò rỉ vào tự nhiên (nói thông qua một url) và bệnh lây lan.
Samuel Danielson

25

Tôi ghét khóa thay thế nói chung. Chúng chỉ nên được sử dụng khi không có khóa tự nhiên chất lượng có sẵn. Thật là vô lý khi bạn nghĩ về nó, để nghĩ rằng thêm dữ liệu vô nghĩa vào bảng của bạn có thể làm cho mọi thứ tốt hơn.

Đây là lý do của tôi:

  1. Khi sử dụng các khóa tự nhiên, các bảng được nhóm theo cách mà chúng thường được tìm kiếm nhất do đó làm cho các truy vấn nhanh hơn.

  2. Khi sử dụng các khóa thay thế, bạn phải thêm các chỉ mục duy nhất vào các cột khóa logic. Bạn vẫn cần ngăn chặn dữ liệu trùng lặp hợp lý. Ví dụ: bạn không thể cho phép hai Tổ chức có cùng tên trong bảng Tổ chức của mình mặc dù pk là cột id thay thế.

  3. Khi các khóa thay thế được sử dụng làm khóa chính, thì rõ ràng các khóa chính tự nhiên là gì. Khi phát triển bạn muốn biết tập hợp cột nào làm cho bảng trở nên độc đáo.

  4. Trong một đến nhiều chuỗi mối quan hệ, chuỗi khóa logic. Vì vậy, ví dụ: Tổ chức có nhiều Tài khoản và Tài khoản có nhiều Hóa đơn. Vì vậy, khóa logic của Tổ chức là OrgName. Khóa logic của Tài khoản là OrgName, AccountID. Khóa logic của Hóa đơn là OrgName, AccountID, InvoiceNumber.

    Khi các khóa thay thế được sử dụng, các chuỗi khóa bị cắt ngắn chỉ bằng cách có một khóa ngoại cho cha mẹ ngay lập tức. Ví dụ: bảng Hóa đơn không có cột OrgName. Nó chỉ có một cột cho AccountID. Nếu bạn muốn tìm kiếm hóa đơn cho một tổ chức nhất định, thì bạn sẽ cần tham gia các bảng Tổ chức, Tài khoản và Hóa đơn. Nếu bạn sử dụng các khóa logic, thì bạn có thể Truy vấn bảng Tổ chức trực tiếp.

  5. Lưu trữ các giá trị khóa thay thế của các bảng tra cứu làm cho các bảng chứa đầy các số nguyên vô nghĩa. Để xem dữ liệu, các chế độ xem phức tạp phải được tạo để nối với tất cả các bảng tra cứu. Bảng tra cứu có nghĩa là giữ một tập hợp các giá trị được chấp nhận cho một cột. Nó không nên được mã hóa bằng cách lưu trữ khóa thay thế số nguyên thay thế. Không có gì trong các quy tắc chuẩn hóa cho thấy rằng bạn nên lưu trữ một số nguyên thay thế thay vì chính giá trị đó.

  6. Tôi có ba cuốn sách cơ sở dữ liệu khác nhau. Không phải một trong số họ hiển thị bằng cách sử dụng các khóa thay thế.


7
Tôi ghét chìa khóa thay thế, trừ khi chúng là cần thiết. Chúng là cần thiết khi doanh nghiệp sử dụng khóa tự nhiên có nhiều lỗi và không sẵn sàng chấp nhận cơ sở dữ liệu bị ảnh hưởng bởi các lỗi đó.
Walter Mitty

26
-1: Tôi đã viết và duy trì hàng tá ứng dụng. Những người có vấn đề liên quan đến dữ liệu nhất là những người sử dụng khóa tự nhiên.
Falcon

6
Một số điểm của bạn cho rằng khóa thay thế phải là PK hoặc phải là cột được nhóm - không đúng. Điểm 1 và 5 của bạn bỏ qua thực tế là số nguyên là 4 byte và các khóa tự nhiên hầu như luôn luôn là nhiều, nhiều byte hơn. Và, mỗi chỉ mục không được bao gồm phải lặp lại các byte của các khóa tự nhiên đó trong chỉ mục được nhóm, do đó các bảng và chỉ mục trong cơ sở dữ liệu khóa tự nhiên của bạn sẽ có rất nhiều hàng trên mỗi trang, điều này dẫn đến hiệu suất đọc kém hơn nhiều , làm cho các truy vấn chậm hơn , không nhanh hơn.
ErikE

3
Một lý do khác chống lại các khóa tự nhiên (ví dụ: Số nguyên tử, số VIN, v.v.), logic nghiệp vụ có thể thay đổi làm tăng loại dữ liệu. Ví dụ: Trước: Theo dõi phí của nguyên tử, Sau: Theo dõi phí của nguyên tử và hợp chất. Trước: Theo dõi xe cơ giới cho khả năng tải. Sau: Thêm máy bay, thuyền, xe đạp và người cho khả năng mang tải.
trước

3
Tôi đoán bạn không có bất kỳ bảng nào trong đó khóa chính được tạo một phần từ 1) bất kỳ thuộc tính nào có thể và sẽ thay đổi) hoặc 2) từ đầu vào của người dùng (ví dụ: danh sách tra cứu được tạo động). Nếu bạn không thể đảm bảo tính bất biến của khóa, thì bạn sẽ phải cập nhật tất cả các mối quan hệ thực thể này bằng mã hoặc bằng các tập lệnh "sửa lỗi" thủ công. Nếu bạn không bao giờ phải làm điều đó ... Tôi đoán cơ sở dữ liệu của bạn vừa thay thế khóa vừa ... không bình thường.
code4life

18

Tôi muốn chia sẻ kinh nghiệm của tôi với bạn về cuộc chiến bất tận này: D về vấn đề nan giải tự nhiên và thay thế. Tôi nghĩ rằng cả khóa thay thế (khóa được tạo tự động nhân tạo) và khóa tự nhiên (bao gồm (các) cột có ý nghĩa miền) đều có ưunhược điểm . Vì vậy, tùy thuộc vào tình huống của bạn, có thể phù hợp hơn khi chọn phương pháp này hay phương pháp khác.

Vì dường như nhiều người trình bày các khóa thay thế là giải pháp gần như hoàn hảo và các khóa tự nhiên là bệnh dịch, tôi sẽ tập trung vào các quan điểm khác của quan điểm:

Nhược điểm của khóa thay thế

Các khóa thay thế là:

  1. Nguồn gốc của vấn đề hiệu suất:
    • Chúng thường được thực hiện bằng các cột tăng tự động có nghĩa là:
      • Một chuyến đi khứ hồi tới cơ sở dữ liệu mỗi khi bạn muốn nhận Id mới (tôi biết rằng điều này có thể được cải thiện bằng cách sử dụng bộ nhớ đệm hoặc thuật toán [seq] hilo nhưng các phương thức đó vẫn có nhược điểm riêng).
      • Nếu một ngày bạn cần di chuyển dữ liệu của mình từ lược đồ này sang lược đồ khác (ít nhất nó xảy ra khá thường xuyên trong công ty của tôi) thì bạn có thể gặp phải sự cố va chạm Id. Và Có, tôi biết rằng bạn có thể sử dụng UUID nhưng những lần kéo dài đó đòi hỏi 32 chữ số thập lục phân! (Nếu bạn quan tâm đến kích thước cơ sở dữ liệu thì đó có thể là một vấn đề).
      • Nếu bạn đang sử dụng một chuỗi cho tất cả các khóa thay thế của mình thì - chắc chắn - bạn sẽ kết thúc với sự tranh chấp trên cơ sở dữ liệu của mình.
  2. Dễ bị lỗi. Chuỗi có giới hạn max_value vì vậy - với tư cách là nhà phát triển - bạn phải chú ý đến các điểm sau:
    • Bạn phải quay vòng chuỗi của mình (khi đạt đến giá trị tối đa, nó sẽ quay trở lại 1,2, ...).
    • Nếu bạn đang sử dụng chuỗi theo thứ tự (theo thời gian) dữ liệu của mình thì bạn phải xử lý trường hợp đi xe đạp (cột có Id 1 có thể mới hơn hàng có giá trị tối đa Id - 1).
    • Đảm bảo rằng mã của bạn (và thậm chí các giao diện máy khách của bạn không nên xảy ra vì nó là Id nội bộ) hỗ trợ các số nguyên 32b / 64b mà bạn đã sử dụng để lưu trữ các giá trị chuỗi của mình.
  3. Họ không đảm bảo dữ liệu không trùng lặp. Bạn luôn có thể có 2 hàng với tất cả các giá trị cột giống nhau nhưng với giá trị được tạo khác nhau. Đối với tôi đây là THE vấn đề các phím thay thế từ một điểm thiết kế cơ sở dữ liệu của view.
  4. Thêm trong Wikipedia ...

Huyền thoại về chìa khóa tự nhiên

  1. Khóa tổng hợp ít hiệu quả hơn so với khóa thay thế. Không! Nó phụ thuộc vào công cụ cơ sở dữ liệu được sử dụng:
  2. Chìa khóa tự nhiên không tồn tại trong cuộc sống thực. Xin lỗi nhưng chúng tồn tại! Ví dụ, trong ngành hàng không, bộ dữ liệu sau đây sẽ luôn là duy nhất liên quan đến một chuyến bay theo lịch trình nhất định (hãng hàng không, khởi hành, chuyến bay số, hoạt độngSuffix). Tổng quát hơn, khi một tập hợp dữ liệu kinh doanh được đảm bảo là duy nhất theo một tiêu chuẩn nhất định thì bộ dữ liệu này là một ứng cử viên tự nhiên [tốt].
  3. Các khóa tự nhiên "gây ô nhiễm lược đồ" của các bảng con. Đối với tôi đây là một cảm giác nhiều hơn là một vấn đề thực sự. Có khóa chính gồm 4 cột gồm 2 byte, mỗi cột có thể hiệu quả hơn một cột 11 byte. Ngoài ra, 4 cột có thể được sử dụng để truy vấn trực tiếp bảng con (bằng cách sử dụng 4 cột trong mệnh đề where) mà không cần nối với bảng cha.

Phần kết luận

Sử dụng các khóa tự nhiên khi có liên quan để làm như vậy và sử dụng các khóa thay thế khi sử dụng chúng tốt hơn.

Hy vọng rằng điều này đã giúp ai đó!


3
Điều gì xảy ra khi chuyến bay khởi hành theo lịch trình được lên lịch lại? Bạn có phải theo dõi tất cả các thực thể liên quan và xóa các khóa, hoặc bạn thực sự cập nhật tất cả các khóa trong các thực thể liên quan? Hoặc bạn đang xử lý một bảng đơn giản (thậm chí có thể không phải 3NF)?
code4life

Điểm Excelent @ code4life
bắt buộc

@ code4life: Đó là nơi mà operSuffix nhảy vào. Để giữ cùng một chuyến baySố để chúng tôi tránh sự nhầm lẫn của khách hàng, chúng tôi chỉ thêm một hậu tố (ví dụ 'D').
mwnsiri

"Bạn luôn có thể có 2 hàng với tất cả các giá trị cột giống nhau nhưng với giá trị được tạo khác nhau", vì vậy chỉ cần đặt một ràng buộc duy nhất hoặc tổng hợp duy nhất trên các cột của bạn.
bất cứ lúc nào

15

Dù sao sử dụng một chìa khóa không có ý nghĩa kinh doanh. Đó chỉ là thực hành tốt.

EDIT: Tôi đã cố gắng tìm một liên kết đến nó trực tuyến, nhưng tôi không thể. Tuy nhiên, trong 'Các mô hình kiến ​​trúc doanh nghiệp' [Fowler], nó có một lời giải thích tốt về lý do tại sao bạn không nên sử dụng bất cứ thứ gì ngoài một khóa không có ý nghĩa gì ngoài việc là một khóa. Thực tế là nó chỉ nên có một công việc và một công việc duy nhất.


22
Martin Fowler có thể có nhiều thứ, nhưng anh ta không phải là người có thẩm quyền trong thiết kế cơ sở dữ liệu.
Tony Andrew

Tôi nghĩ bạn nên cung cấp một số lý do trước khi đi đến kết luận.
Arne Evertsson

4
@ArneEiftsoon Lý do là ở đó. 'Nó hiểu rõ rằng nó chỉ nên có một công việc và một công việc duy nhất.' Độc thân chịu trách nhiệm.
Người giữ Iain

10

Khóa thay thế khá tiện dụng nếu bạn định sử dụng công cụ ORM để xử lý / tạo các lớp dữ liệu của mình. Mặc dù bạn có thể sử dụng các khóa tổng hợp với một số trình ánh xạ nâng cao hơn (đọc: hibernate), nhưng nó sẽ thêm một số phức tạp vào mã của bạn.

(Tất nhiên, những người theo chủ nghĩa cơ sở dữ liệu sẽ lập luận rằng ngay cả khái niệm khóa thay thế cũng là một sự gớm ghiếc.)

Tôi là một fan hâm mộ của việc sử dụng uids cho các phím thay thế khi thích hợp. Chiến thắng chính với họ là bạn biết trước khóa, ví dụ: bạn có thể tạo một thể hiện của một lớp với ID đã được đặt và được đảm bảo là duy nhất trong khi với, một khóa số nguyên bạn sẽ cần mặc định là 0 hoặc - 1 và cập nhật thành giá trị phù hợp khi bạn lưu / cập nhật.

Mặc dù vậy, UID có hình phạt về mặt tra cứu và tốc độ tham gia vì vậy nó phụ thuộc vào ứng dụng được đề cập đến việc liệu chúng có mong muốn hay không.


6

Theo tôi, sử dụng khóa thay thế sẽ tốt hơn vì không có cơ hội thay đổi. Hầu như bất cứ điều gì tôi có thể nghĩ về cái mà bạn có thể sử dụng như một khóa tự nhiên đều có thể thay đổi (từ chối trách nhiệm: không phải lúc nào cũng đúng, nhưng thông thường).

Một ví dụ có thể là DB của ô tô - thoạt nhìn, bạn có thể nghĩ rằng biển số xe có thể được sử dụng làm chìa khóa. Nhưng những điều này có thể được thay đổi để đó là một ý tưởng tồi. Bạn sẽ không thực sự muốn tìm ra điều đó sau khi phát hành ứng dụng, khi ai đó đến với bạn muốn biết lý do tại sao họ không thể thay đổi biển số của họ thành một cái mới được cá nhân hóa sáng bóng của họ.


1
Thật không may, những chiếc xe hơi có một chìa khóa tự nhiên không thay đổi: số VIN (ít nhất là ở Mỹ ...)
jcollum

@jcollum Vâng, đó là một điểm công bằng. Ý kiến ​​của tôi vẫn đứng vững, ví dụ của tôi không nhất thiết phải tốt như nó có thể.
Mark Emble

2
Một danh sách các ngôn ngữ sẽ là một ví dụ cho khóa tự nhiên, khi bạn dựa trên mã ISO. Vì vậy, nếu sau đó bạn muốn tải nội dung từ một bảng bằng một ngôn ngữ nhất định, bạn sẽ không cần phải tham gia vào languagesbảng vì mã ngôn ngữ (ID) đã có trong textsbảng.
DanMan

@DanMan Tôi phải đồng ý với bạn ở đó. Luôn luôn có một số ví dụ hoạt động tốt hơn với khóa tự nhiên. Các quy tắc hoặc cách tiếp cận phổ biến không bao giờ là tuyệt đối và đó là một ví dụ tôi sẽ thực hiện 100% với cách tiếp cận của bạn :-)
Đánh dấu vào

5

Luôn luôn sử dụng một cột duy nhất, thay thế khóa nếu có thể. Điều này làm cho các phép nối cũng như chèn / cập nhật / xóa sạch hơn nhiều vì bạn chỉ chịu trách nhiệm theo dõi một mẩu thông tin duy nhất để duy trì hồ sơ.

Sau đó, khi cần thiết, xếp các khóa kinh doanh của bạn dưới dạng các chỉ số hoặc chỉ mục duy nhất. Điều này sẽ giữ cho bạn toàn vẹn dữ liệu.

Logic nghiệp vụ / khóa tự nhiên có thể thay đổi, nhưng khóa phisical của bảng KHÔNG BAO GIỜ thay đổi.


4

Trên một kịch bản trung tâm dữ liệu, tôi tin rằng tốt hơn là đi theo con đường chính thay thế. Hai lý do:

  • Bạn độc lập với hệ thống nguồn và các thay đổi ở đó - như thay đổi kiểu dữ liệu-- sẽ không ảnh hưởng đến bạn.
  • DW của bạn sẽ cần ít không gian vật lý hơn vì bạn sẽ chỉ sử dụng các loại dữ liệu số nguyên cho các khóa thay thế của mình. Ngoài ra các chỉ số của bạn sẽ làm việc tốt hơn.

2

Khóa thay thế có thể hữu ích khi thông tin doanh nghiệp có thể thay đổi hoặc giống hệt nhau. Rốt cuộc, tên doanh nghiệp không phải là duy nhất trên toàn quốc. Giả sử bạn giao dịch với hai doanh nghiệp tên Smith Electronics, một ở Kansas và một ở Michigan. Bạn có thể phân biệt chúng theo địa chỉ, nhưng điều đó sẽ thay đổi. Ngay cả nhà nước cũng có thể thay đổi; Điều gì xảy ra nếu Smith Electronics ở Kansas City, Kansas di chuyển qua sông đến Thành phố Kansas, Missouri? Không có cách rõ ràng nào để giữ cho các doanh nghiệp này khác biệt với thông tin khóa tự nhiên, vì vậy khóa thay thế là rất hữu ích.

Hãy nghĩ về khóa thay thế giống như một số ISBN. Thông thường, bạn xác định một cuốn sách theo tiêu đề và tác giả. Tuy nhiên, tôi đã có hai cuốn sách có tựa đề "Trân Châu Cảng" của HP Willmott và chúng chắc chắn là những cuốn sách khác nhau, không chỉ là các phiên bản khác nhau. Trong trường hợp như vậy, tôi có thể đề cập đến vẻ ngoài của những cuốn sách, hoặc sớm hơn so với sau này, nhưng tôi cũng có thể sử dụng lại số ISBN.


1
Tôi nghĩ rằng tôi phải không đồng ý với ví dụ của bạn ở đây. Số ISBN là một thuộc tính của một cuốn sách. Khóa thay thế độc lập với phần còn lại của dữ liệu hàng, do đó, vị trí này sẽ ủng hộ sử dụng khóa thay thế riêng cho bảng sách, ngay cả khi ISBN đã xác định duy nhất mỗi cuốn sách.
Christopher Cashell

Thay phiên, hãy nghĩ về ISBN như một khóa thay thế. Đó là một định danh không có ý nghĩa, chỉ là một mã được áp dụng cho một cuốn sách cụ thể. Nếu bạn đang tạo một bảng sách, thì đó cũng có thể là khóa chính (giả sử bạn có và luôn có một cuốn sách mỗi hàng).
David Thornley

@Christopher Cashell - Đã xem qua bài đăng này từ một năm trước nhưng tôi nghĩ thêm một cái gì đó. Các mã số không được đảm bảo là duy nhất và có thể có các bản sao. Tôi có một người bạn đã làm việc tại một thư viện trong nhiều năm và họ thường chạy qua các cuốn sách có các mã trùng lặp. Vấn đề là sự độc đáo của ISBN là đương nhiên với nhà xuất bản chứ không phải là một cơ quan đảm bảo rằng tất cả các số cho tất cả các ấn phẩm là duy nhất và những nhà xuất bản không phải lúc nào cũng có hành động của họ với nhau.
Thomas

2
Đã xem qua bài đăng này từ một năm trước và muốn đề cập rằng trên thực tế, đó là các khóa tự nhiên. Có ý nghĩa nướng vào chính giá trị khóa không giống như khóa thay thế. Ví dụ: một phần của khóa xác định nhà xuất bản. Ngoài ra, như tôi đã đề cập ở trên, chúng không được đảm bảo là duy nhất. Chúng được cho là độc nhất nhưng sự độc đáo đó đến từ các nhà xuất bản và chúng không phải lúc nào cũng hoàn hảo.
Thomas

Về mặt kỹ thuật, các tập đoàn không thể di chuyển giữa các quốc gia; những gì xảy ra là một công ty mới được tạo ra ở trạng thái mới và tài sản được chuyển giao. Điều đó làm việc cho thông tin cơ sở dữ liệu quá.
Warren Dew

2

Xin nhắc lại, không nên đặt các chỉ số được nhóm trên các khóa thay thế ngẫu nhiên, ví dụ như GUID đọc XY8D7-DFD8S, vì SQL Server không có khả năng sắp xếp vật lý các dữ liệu này. Thay vào đó, bạn nên đặt các chỉ mục duy nhất trên các dữ liệu này, mặc dù cũng có thể có ích khi chỉ cần chạy trình lược tả SQL cho các hoạt động của bảng chính và sau đó đặt các dữ liệu đó vào Trình cố vấn điều chỉnh công cụ cơ sở dữ liệu.

Xem chủ đề @ http://social.msdn.microsoft.com/Forums/en-us/sqlgetstarted/thread/27bd9c77-ec31-44f1-ab7f-bd2cb13129be


Tôi khá chắc chắn rằng SQL Server có thể sắp xếp GUID.
Michael Green

Điều này không chính xác, trong khi họ có thể đánh giá GUID, loại kết quả không phải là vô nghĩa đối với con người. stackoverflow.com/questions/7810602/ trộm
Bryan Swan

1
Một tuyên bố đúng, nhưng hoàn toàn khác với "SQL Server không có khả năng sắp xếp vật lý những thứ này".
Michael Green

2

Trường hợp 1: Bảng của bạn là bảng tra cứu có ít hơn 50 loại (chèn)

Sử dụng khóa kinh doanh / tự nhiên . Ví dụ:

Table: JOB with 50 inserts
CODE (primary key)       NAME               DESCRIPTION
PRG                      PROGRAMMER         A programmer is writing code
MNG                      MANAGER            A manager is doing whatever
CLN                      CLEANER            A cleaner cleans
...............
joined with
Table: PEOPLE with 100000 inserts

foreign key JOBCODE in table PEOPLE
looks at
primary key CODE in table JOB

Trường hợp 2: Bảng của bạn là một bảng có hàng ngàn chèn

Sử dụng các phím thay thế / tự động . Ví dụ:

Table: ASSIGNMENT with 1000000 inserts
joined with
Table: PEOPLE with 100000 inserts

foreign key PEOPLEID in table ASSIGNMENT
looks at
primary key ID in table PEOPLE (autoincrement)

Trong trường hợp đầu tiên:

  • Bạn có thể chọn tất cả các lập trình viên trong bảng NHÂN DÂN mà không cần sử dụng phép nối với bảng JOB, nhưng chỉ với: "CHỌN * TỪ NHÂN DÂN WHERE JOBCODE = 'PRG'"

Trong trường hợp thứ hai:

  • Truy vấn cơ sở dữ liệu của bạn nhanh hơn vì khóa chính của bạn là một số nguyên
  • Bạn không cần bận tâm đến việc tìm khóa duy nhất tiếp theo vì chính cơ sở dữ liệu sẽ cung cấp cho bạn sự tự động tiếp theo.

2

Đây là một trong những trường hợp khóa thay thế khá nhiều luôn có ý nghĩa. Có những trường hợp bạn chọn cái gì tốt nhất cho cơ sở dữ liệu hoặc cái gì tốt nhất cho mô hình đối tượng của bạn, nhưng trong cả hai trường hợp, sử dụng khóa vô nghĩa hoặc GUID là một ý tưởng tốt hơn. Nó làm cho việc lập chỉ mục dễ dàng hơn và nhanh hơn và đó là một danh tính cho đối tượng của bạn không thay đổi.


1

Ngựa cho các khóa học. Để nói rõ sự thiên vị của tôi; Trước tiên tôi là nhà phát triển, vì vậy tôi chủ yếu quan tâm đến việc cung cấp cho người dùng một ứng dụng hoạt động.

Tôi đã làm việc trên các hệ thống có khóa tự nhiên và phải mất nhiều thời gian để đảm bảo rằng các thay đổi giá trị sẽ gợn qua.

Tôi đã làm việc trên các hệ thống chỉ có các khóa thay thế và nhược điểm duy nhất là thiếu dữ liệu không chuẩn hóa để phân vùng.

Hầu hết các nhà phát triển PL / SQL truyền thống mà tôi đã làm việc không thích khóa thay thế vì số lượng bảng trên mỗi lần tham gia, nhưng cơ sở dữ liệu thử nghiệm và sản xuất của chúng tôi không bao giờ đổ mồ hôi; các kết nối thêm không ảnh hưởng đến hiệu suất ứng dụng. Với các phương ngữ cơ sở dữ liệu không hỗ trợ các mệnh đề như "X bên trong tham gia Y trên Xa = Yb" hoặc các nhà phát triển không sử dụng cú pháp đó, các phép nối thêm cho các khóa thay thế làm cho các truy vấn khó đọc hơn và lâu hơn để nhập và kiểm tra: xem bài đăng @Tony Andrew. Nhưng nếu bạn sử dụng ORM hoặc bất kỳ khung công tác tạo SQL nào khác, bạn sẽ không nhận thấy nó. Gõ cảm ứng cũng giảm nhẹ.


Cũng thế; nếu bạn muốn thực sự lái xe về nhà rằng các khóa thay thế chỉ là vậy, hãy khởi động chúng với số lượng lớn ngẫu nhiên và tăng các chuỗi lên 3+ thay vì 1. Hoặc sử dụng cùng một chuỗi để tạo giá trị cho nhiều hơn một khóa.
WillC

1

Có thể không hoàn toàn liên quan đến chủ đề này, nhưng tôi đau đầu với các khóa thay thế. Các phân tích được phân phối trước của Oracle tạo ra các SK được tạo tự động trên tất cả các bảng kích thước của nó trong kho và nó cũng lưu trữ các phân tích trên thực tế. Vì vậy, bất cứ khi nào chúng (kích thước) cần được tải lại khi các cột mới được thêm vào hoặc cần được điền cho tất cả các mục trong thứ nguyên, các SK được chỉ định trong quá trình cập nhật làm cho các SK không đồng bộ với các giá trị ban đầu được lưu trữ trên thực tế, buộc tải lại hoàn toàn tất cả các bảng thực tế tham gia vào nó. Tôi muốn rằng ngay cả khi SK là một con số vô nghĩa, sẽ có một số cách mà nó không thể thay đổi cho các hồ sơ gốc / cũ. Như nhiều người biết, ngoài luồng hiếm khi phục vụ nhu cầu của tổ chức và chúng tôi phải tùy chỉnh liên tục. Chúng tôi hiện có 3yrs dữ liệu trong kho của chúng tôi, và tải lại hoàn toàn từ các hệ thống tài chính của Oracle là rất lớn. Vì vậy, trong trường hợp của tôi, chúng không được tạo từ mục nhập dữ liệu, mà được thêm vào một kho để giúp báo cáo hiệu suất. Tôi hiểu rồi, nhưng chúng ta thay đổi, và đó là một cơn ác mộng.


0

Trong trường hợp cơ sở dữ liệu thời gian, tốt nhất nên có sự kết hợp của khóa thay thế và khóa tự nhiên. ví dụ: bạn cần theo dõi thông tin thành viên cho một câu lạc bộ. Một số thuộc tính của một thành viên không bao giờ thay đổi. ví dụ: Ngày sinh nhưng tên có thể thay đổi. Vì vậy, hãy tạo một bảng Thành viên với khóa thay thế thành viên_id và có một cột cho DOB. Tạo một bảng khác được gọi tên người và có các cột cho thành viên_id, thành viên_fname, thành viên_lname, date_updated. Trong bảng này, khóa tự nhiên sẽ là Member_id + date_updated.

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.