Khóa ngoại - liên kết sử dụng khóa thay thế hoặc khóa tự nhiên?


14

Có cách thực hành tốt nhất cho việc liệu khóa ngoại giữa các bảng nên liên kết với khóa tự nhiên hay khóa thay thế? Cuộc thảo luận duy nhất tôi thực sự tìm thấy (trừ khi google-fu của tôi thiếu) là câu trả lời của Jack Douglas trong câu hỏi này và lý luận của anh ấy có vẻ hợp với tôi. Tôi biết về các cuộc thảo luận ngoài quy tắc đó thay đổi, nhưng đây sẽ là điều cần được xem xét trong mọi tình huống.

Lý do chính để hỏi là tôi có một ứng dụng cũ sử dụng FK với các khóa tự nhiên, nhưng có một sự thúc đẩy mạnh mẽ từ các nhà phát triển để chuyển sang OR / M (NHibernate trong trường hợp của chúng tôi) và một ngã ba đã tạo ra một số phá vỡ các thay đổi, vì vậy tôi đang tìm cách đẩy chúng trở lại đúng hướng bằng cách sử dụng khóa tự nhiên hoặc di chuyển ứng dụng cũ để sử dụng các khóa thay thế cho FK. Chú ruột của tôi nói rằng sẽ khôi phục FK ban đầu, nhưng tôi thực sự không chắc liệu đây có thực sự là con đường đúng đắn để đi theo hay không.

Phần lớn các bảng của chúng tôi đã có cả khóa thay thế và khóa tự nhiên đã được xác định (mặc dù ràng buộc duy nhất và PK), do đó việc phải thêm các cột bổ sung là vấn đề không phải đối với chúng tôi trong trường hợp này. Chúng tôi đang sử dụng SQL Server 2008, nhưng tôi hy vọng điều này đủ chung cho bất kỳ DB nào.

Câu trả lời:


15

Cả SQL và mô hình quan hệ đều không bị xáo trộn bởi các khóa ngoại tham chiếu khóa tự nhiên. Trong thực tế, tham chiếu các phím tự nhiên thường cải thiện đáng kể hiệu suất. Bạn sẽ ngạc nhiên về mức độ thường xuyên thông tin bạn cần được chứa hoàn toàn trong một khóa tự nhiên; tham chiếu khóa đó giao dịch một phép nối cho một bảng rộng hơn (và do đó làm giảm số lượng hàng bạn có thể lưu trữ trong một trang).

Theo định nghĩa, thông tin bạn cần luôn được chứa hoàn toàn trong khóa tự nhiên của mỗi bảng "tra cứu". (Bảng tra cứu thuật ngữ là không chính thức. Trong mô hình quan hệ, tất cả các bảng chỉ là bảng. Một bảng mã bưu chính của Hoa Kỳ có thể có các hàng trông như thế này: {AK, Alaska}, {AL, Alabama}, {AZ, Arizona} , v.v ... Hầu hết mọi người sẽ gọi đó là bảng tra cứu.)

Trên các hệ thống lớn, không có gì lạ khi tìm thấy các bảng có nhiều hơn một khóa ứng cử viên. Cũng không có gì lạ khi các bảng phục vụ một bộ phận của doanh nghiệp tham chiếu một khóa ứng viên và các bảng phục vụ một phần khác của doanh nghiệp để tham chiếu một khóa ứng viên khác. Đây là một trong những điểm mạnh của mô hình quan hệ và nó là một phần của mô hình quan hệ mà SQL hỗ trợ khá tốt.

Bạn sẽ gặp hai vấn đề khi bạn tham chiếu các khóa tự nhiên trong các bảng cũng có khóa thay thế.

Đầu tiên, bạn sẽ làm mọi người ngạc nhiên. Mặc dù tôi thường vận động mạnh mẽ cho Nguyên tắc bất ngờ tối thiểu , đây là một tình huống mà tôi không làm mọi người ngạc nhiên. Khi vấn đề là các nhà phát triển ngạc nhiên về việc sử dụng hợp lý các khóa ngoại, giải pháp là giáo dục chứ không phải thiết kế lại.

Thứ hai, các ORM thường không được thiết kế xung quanh mô hình quan hệ và đôi khi chúng thể hiện các giả định không phản ánh thực tiễn tốt nhất. (Trên thực tế, chúng dường như thường được thiết kế mà không bao giờ có đầu vào từ một chuyên gia cơ sở dữ liệu.) Yêu cầu số ID trong mỗi bảng là một trong những giả định đó. Một người khác đang giả định rằng ứng dụng ORM "sở hữu" cơ sở dữ liệu. (Vì vậy, nó miễn phí để tạo, thả và đổi tên bảng và cột.)

Tôi đã làm việc trên một hệ thống cơ sở dữ liệu phục vụ dữ liệu cho hàng trăm chương trình ứng dụng được viết bằng ít nhất hai chục ngôn ngữ trong khoảng thời gian 30 năm. Cơ sở dữ liệu đó thuộc về doanh nghiệp, không thuộc ORM.

Một ngã ba giới thiệu các thay đổi phá vỡ nên là một điểm dừng hiển thị.

Tôi đo hiệu suất với cả khóa tự nhiên và khóa thay thế tại một công ty tôi từng làm việc. Có một điểm bùng phát tại đó các khóa thay thế bắt đầu tốt hơn các khóa tự nhiên. (Giả sử không có nỗ lực bổ sung nào để duy trì hiệu suất khóa tự nhiên cao, như phân vùng, chỉ mục một phần, chỉ mục dựa trên chức năng, không gian bảng bổ sung, sử dụng đĩa trạng thái rắn, v.v.) Theo ước tính của tôi cho công ty đó, họ sẽ đạt đến điểm tới hạn đó khoảng năm 2045. Trong khi đó, chúng có hiệu suất tốt hơn với các phím tự nhiên.

Các câu trả lời có liên quan khác: Trong Cơ sở dữ liệu Lược đồ khó hiểu


5

Lý do chính tôi hỗ trợ các khóa thay thế là các khóa tự nhiên thường có thể thay đổi và điều đó có nghĩa là tất cả các bảng có liên quan phải được cập nhật, có thể tải khá nhiều trên máy chủ.

Hơn nữa trong 30 năm tôi đã sử dụng nhiều loại cơ sở dữ liệu về nhiều chủ đề, khóa tự nhiên thực sự thường khá hiếm. Những thứ được cho là duy nhất (SSN) thì không, những thứ duy nhất tại một thời điểm cụ thể có thể trở thành không độc đáo sau đó và một số thứ như địa chỉ email và số điện thoại có thể là duy nhất, nhưng chúng có thể được sử dụng lại cho những người khác sau ngày. Tất nhiên một số thứ đơn giản là không có một định danh duy nhất tốt như tên của mọi người và các công ty.

Để tránh tham gia bằng cách sử dụng một khóa tự nhiên. Có, điều đó có thể tăng tốc các câu lệnh chọn không cần các phép nối, nhưng nó sẽ khiến các vị trí mà bạn vẫn cần các phép nối chậm hơn vì các phép nối int thường nhanh hơn. Nó cũng có thể sẽ làm chậm việc chèn và xóa và sẽ gây ra vấn đề về hiệu suất trên các bản cập nhật khi khóa thay đổi. Các truy vấn phức tạp (dù sao cũng chậm hơn) sẽ còn chậm hơn. Vì vậy, các truy vấn đơn giản nhanh hơn nhưng báo cáo và truy vấn phức tạp và nhiều hành động chống lại cơ sở dữ liệu có thể chậm hơn. Đó là một hành động cân bằng, có thể tip theo cách này hay cách khác tùy thuộc vào cách cơ sở dữ liệu của bạn được truy vấn.

Vì vậy, không có một kích thước phù hợp với tất cả các câu trả lời. Nó phụ thuộc vào cơ sở dữ liệu của bạn và cách nó sẽ được truy vấn và loại thông tin được lưu trữ trong đó. Bạn có thể cần thực hiện một số thử nghiệm để tìm ra những gì hoạt động tốt nhất trong môi trường của riêng bạn.


1
"Khóa tự nhiên thường có thể thay đổi" - thì đó không phải là khóa tốt! Nếu một thuộc tính thay đổi thường xuyên thì dĩ nhiên không sử dụng nó làm khóa (đối với các định nghĩa khác nhau về "thường"). Fabian Pascal lập luận rằng có bốn tiêu chí để chọn một khóa: quen thuộc, không thể sửa chữa, ổn định và đơn giản. Đôi khi bạn đánh đổi những thứ này vì sự đơn giản của khóa thay thế. Như HLGEM nói, "Vì vậy, không có câu trả lời nào phù hợp với tất cả câu trả lời."
Greenstone Walker

1
@GreenstoneWalker, tôi đồng ý rằng bạn không nên lấy nó làm chìa khóa, nhưng thường thì bạn không có khóa phù hợp với cả bốn tiêu chí và bạn phải đi theo những gì độc đáo. Và khi tính duy nhất là một khóa copmposeite, thì vấn đề có thể còn lớn hơn về mặt hiệu suất khi bạn phải có các phép nối.
HLGEM

-4

Nếu bạn không biết câu trả lời, hãy đi với Surrogate. Đây là lý do - nếu các giả định được đưa ra về các quy tắc kinh doanh và các giả định đó là sai hoặc các quy tắc thay đổi, dữ liệu của bạn là rác. Đây là một ví dụ:

Người, Vai trò, PersonRole

quy tắc kinh doanh hiện tại quy định rằng một Người có một Vai trò. Bạn tạo một bảng liên kết Person và Vai trò trong đó PersonRole (PersonName, PersonBirthDate, PersonMotherMaidenName, ..., RoleCode)

Bây giờ bạn là một người theo chủ nghĩa thuần túy thực sự khi nói đến Khóa tự nhiên! Nhưng nghiêm túc, điều gì sẽ xảy ra nếu org quyết định rằng một người bây giờ có thể đảm nhận nhiều vai trò? Những tác động hạ nguồn của việc hỗ trợ thay đổi nhu cầu kinh doanh là gì?


2
Và bạn không có những vấn đề này với khóa thay thế? Hãy chỉ cho chúng tôi làm thế nào.
Colin 't Hart

4
Ví dụ đưa ra dường như không thể hiện bất cứ điều gì liên quan đến cuộc thảo luận.
mustaccio
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.