Có gì sai với khóa ngoại?


259

Tôi nhớ đã nghe Joel Spolsky đề cập trong podcast 014 rằng anh ấy hầu như không bao giờ sử dụng khóa ngoại (nếu tôi nhớ chính xác). Tuy nhiên, với tôi chúng có vẻ khá quan trọng để tránh trùng lặp và các vấn đề toàn vẹn dữ liệu tiếp theo trong toàn bộ cơ sở dữ liệu của bạn.

Mọi người có một số lý do chắc chắn là tại sao (để tránh một cuộc thảo luận trong các dòng với các nguyên tắc Stack Overflow) không?

Chỉnh sửa: "Tôi chưa có lý do để tạo khóa ngoại, vì vậy đây có thể là lý do đầu tiên của tôi để thực sự thiết lập một khóa."


9
Tôi không nghĩ Joel không sử dụng FK, chỉ là anh ấy không làm cho cơ sở dữ liệu thực thi chúng. Theo logic, họ vẫn là FK!
Daren Thomas

6
Anh ta nói rằng anh ta không sử dụng khóa ngoại, nhưng tôi đồng ý với Daren rằng điều anh ta muốn nói là anh ta không sử dụng khóa ngoại quốc. Một cột trong một bảng có giá trị được cho là được lấy từ khóa chính / duy nhất của bảng khác là khóa ngoại, cho dù bạn có thêm ràng buộc hay không.
Tony Andrew

22
... Nói chung, thật ngu ngốc khi không thêm các ràng buộc: nó luôn đảm bảo tính toàn vẹn, ngay cả khi có lỗi trong mã ứng dụng hoặc nếu bạn đang làm việc trong hậu trường khi thực hiện "sửa lỗi" dữ liệu.
Tony Andrew

2
+1 Cho nhận xét của Tony. Có quá nhiều nhầm lẫn giữa tính năng và khái niệm logic của khóa ngoại ngoài kia.
JohnFx

4
@DanMan, không biết bạn đã đạt được ấn tượng ở đâu tôi nghĩ thế. Tôi thực sự đã nói ở trên "Nói chung thật ngu ngốc khi không thêm các ràng buộc: nó bảo đảm tính toàn vẹn mọi lúc"
Tony Andrew

Câu trả lời:


352

Lý do nên sử dụng Khóa ngoại:

  • bạn sẽ không nhận được hàng mồ côi
  • bạn có thể có hành vi "xóa tầng" đẹp, tự động dọn dẹp các bảng
  • hiểu biết về các mối quan hệ giữa các bảng trong cơ sở dữ liệu giúp Trình tối ưu hóa lập kế hoạch truy vấn của bạn để thực hiện hiệu quả nhất, vì nó có thể có được ước tính tốt hơn về tính chính xác của việc tham gia.
  • Các FK đưa ra một gợi ý khá lớn về những thống kê nào là quan trọng nhất để thu thập trên cơ sở dữ liệu, từ đó dẫn đến hiệu suất tốt hơn
  • chúng cho phép tất cả các loại hỗ trợ được tạo tự động - ORM có thể tự tạo, các công cụ trực quan sẽ có thể tạo bố cục lược đồ đẹp cho bạn, v.v.
  • ai đó mới tham gia dự án sẽ hòa nhập vào mọi thứ nhanh hơn vì các mối quan hệ ngầm được ghi lại rõ ràng

Lý do không sử dụng Khóa ngoại:

  • bạn đang làm cho DB hoạt động thêm trên mỗi CRUD hoạt động vì nó phải kiểm tra tính nhất quán của FK. Đây có thể là một chi phí lớn nếu bạn có nhiều tiền
  • bằng cách thực thi các mối quan hệ, các FK chỉ định một thứ tự mà bạn phải thêm / xóa mọi thứ, điều này có thể dẫn đến việc DB từ chối thực hiện những gì bạn muốn. (Được cấp, trong những trường hợp như vậy, những gì bạn đang cố gắng làm là tạo ra một Hàng mồ côi và đó thường không phải là một điều tốt). Điều này đặc biệt đau đớn khi bạn đang thực hiện cập nhật hàng loạt lớn và bạn tải lên một bảng trước một bảng khác, với bảng thứ hai tạo trạng thái nhất quán (nhưng bạn nên thực hiện loại điều đó nếu có khả năng tải thứ hai không thành công và cơ sở dữ liệu bây giờ không nhất quán?).
  • đôi khi bạn biết trước dữ liệu của mình sẽ bị bẩn, bạn chấp nhận điều đó và bạn muốn DB chấp nhận nó
  • bạn chỉ lười biếng :-)

Tôi nghĩ (tôi không chắc chắn!) Rằng hầu hết các cơ sở dữ liệu được thiết lập đều cung cấp một cách để chỉ định khóa ngoại không được thi hành và chỉ đơn giản là một chút siêu dữ liệu. Vì việc không thực thi xóa sạch mọi lý do không sử dụng FK, nên có lẽ bạn nên đi theo lộ trình đó nếu có bất kỳ lý do nào trong phần thứ hai được áp dụng.


12
Danh sách tốt! Các DBM sẽ không kiểm tra tính nhất quán đối với phần "R" của CRUD, vì vậy tôi sẽ loại bỏ phần đó. Ngoài ra, đây có thể là một lỗi vì trong ứng dụng của bạn, bạn cũng làm điều tương tự DBMS: bạn sẽ kiểm tra và đảm bảo ID cha hợp lệ trước CRD và điều đó thực sự chậm hơn so với DBM làm điều đó!
Matt Rogish

6
Điều gì xảy ra nếu ai đó xóa cha mẹ trong khi bạn đang chèn con? Ngay bây giờ khi tôi gửi "thêm bình luận" - nếu bạn đã xóa câu trả lời của mình, bình luận này bây giờ là một đứa trẻ mồ côi. FK sẽ ngăn chặn nó. Ngoài ra, tôi chỉ có thể thay đổi ParentID thành bất cứ điều gì tôi muốn. Có người cần kiểm tra. :)
Matt Rogish

7
Chính xác - đó phải là công việc của DB, vì đó là công việc duy nhất có thể đảm bảo tính giao dịch khi đối mặt với nhiều khách hàng đồng thời.
SquareCog

3
+1 Câu trả lời tuyệt vời - lý do thứ hai không sử dụng các ràng buộc FK có thể được nghĩ đến là "làm cho khó phá vỡ tính nhất quán" mà thực sự nghe có vẻ là một điều tốt !
Bill Karwin

9
Theo tôi, lợi ích của việc sử dụng khóa ngoại FAR vượt trội hơn bất kỳ lợi ích nào của việc không sử dụng chúng theo quan điểm của tôi.
Nick Bedford

80

Đây là một vấn đề của giáo dục. Nếu ở đâu đó trong sự nghiệp giáo dục hoặc nghề nghiệp của bạn mà bạn dành thời gian cho ăn và chăm sóc cơ sở dữ liệu (hoặc làm việc chặt chẽ với những người tài năng đã làm), thì các nguyên lý cơ bản của các thực thể và mối quan hệ đã ăn sâu vào quá trình suy nghĩ của bạn. Trong số những sơ suất đó là cách thức / thời gian / lý do để chỉ định các khóa trong cơ sở dữ liệu của bạn (chính, nước ngoài và có lẽ thay thế). Đó là bản chất thứ hai.

Tuy nhiên, nếu bạn chưa có trải nghiệm kỹ lưỡng hoặc tích cực như vậy trong quá khứ với các nỗ lực liên quan đến RDBMS, thì có khả năng bạn chưa tiếp xúc với thông tin đó. Hoặc có lẽ quá khứ của bạn bao gồm cả việc chìm đắm trong một môi trường chống lại cơ sở dữ liệu rõ ràng (ví dụ: "những DBA đó là những kẻ ngốc - chúng tôi rất ít, chúng tôi đã chọn một vài trình điều khiển mã java / c # sẽ cứu ngày"), trong trường hợp đó bạn có thể phản đối kịch liệt với những tiếng bập bẹ phức tạp của một số người ngu ngốc nói với bạn rằng FK (và các ràng buộc mà họ có thể ám chỉ) thực sự quan trọng nếu bạn chỉ lắng nghe.

Hầu hết mọi người đều được dạy khi họ còn nhỏ rằng đánh răng là quan trọng. Bạn có thể nhận được mà không có nó? Chắc chắn, nhưng ở đâu đó, bạn sẽ có ít răng hơn nếu bạn chải răng sau mỗi bữa ăn. Nếu các ông bố bà mẹ có trách nhiệm đủ để trang trải thiết kế cơ sở dữ liệu cũng như vệ sinh răng miệng, chúng ta sẽ không có cuộc trò chuyện này. :-)


61
Tôi sẽ sử dụng chưng cất "chìa khóa nước ngoài giống như đánh răng: đi trước, làm mà không cần, nhưng cẩn thận khi bạn cười"
Mark Sowul

5
Cá nhân tôi thấy rằng các nguyên tắc của RDBMS 'đơn giản và được xác định rõ ràng hơn nhiều so với các nguyên tắc vệ sinh răng miệng
Ali Gangji

10 năm nữa, tôi chắc chắn sẽ có cuộc nói chuyện về thiết kế cơ sở dữ liệu này với con trai / con gái của tôi để nó không gây rối và cuối cùng là lý do cho vụ tai nạn đường phố tiếp theo vì vấn đề cơ sở dữ liệu.
VarunAgw

52

Tôi chắc chắn có rất nhiều ứng dụng mà bạn có thể thoát khỏi nó, nhưng đó không phải là ý tưởng tốt nhất. Bạn không thể luôn tin tưởng vào ứng dụng của mình để quản lý cơ sở dữ liệu của mình một cách chính xác và việc quản lý cơ sở dữ liệu một cách thẳng thắn không phải là mối quan tâm lớn đối với ứng dụng của bạn.

Nếu bạn đang sử dụng một cơ sở dữ liệu quan hệ thì có vẻ như bạn nên có một số mối quan hệ được xác định trong đó. Thật không may, thái độ này (bạn không cần khóa ngoại) dường như được chấp nhận bởi rất nhiều nhà phát triển ứng dụng, những người không muốn bị làm phiền với những thứ ngớ ngẩn như tính toàn vẹn dữ liệu (nhưng cần vì công ty của họ không có nhà phát triển cơ sở dữ liệu chuyên dụng). Thông thường trong các cơ sở dữ liệu được kết hợp bởi các loại này, bạn may mắn chỉ có khóa chính;)


26
Tôi thực sự không nhận được những người không có FK trong cơ sở dữ liệu của họ. Lần cuối cùng tôi làm việc với một người không có nó, anh ta nói "không, chúng tôi thi hành điều đó trong ứng dụng". Ngoại trừ tôi đã làm một cuộc khảo sát tất cả các cơ sở dữ liệu khách hàng và thấy hầu hết trong số họ đã có trẻ mồ côi ...
ErikE

1
Đó thường là trường hợp. Tôi nghĩ rằng bạn có thể thoát khỏi việc thực thi CHỈ trong cơ sở dữ liệu (miễn là người dùng của bạn không bận tâm đến ngoại lệ thời gian chạy) nhưng để có cả hai thực sự là cách duy nhất để đi.
AlexCuse

Tất cả nằm trong bảng điểm / câu trả lời của Atwood "Atwood: ... dựa trên các khóa ngoại mà bạn đặt trong các chỉ mục, họ tìm ra nó ... Spolsky: [cười] Giả sử rằng bạn làm điều đó. Atwood: Chà, giả sử rằng bạn thiết lập cơ sở dữ liệu của mình đúng cách ... "
MemeDeveloper 22/03/13

4
Cơ sở dữ liệu không được gọi là quan hệ vì các mối quan hệ giữa các bảng (MỌI loại cơ sở dữ liệu có một số loại mối quan hệ giữa các thực thể!), Nhưng vì bản thân các bảng là quan hệ , theo thuật ngữ toán học. Xem Wikipedia .
Massimiliano Kraus

41

Khóa ngoại là cần thiết cho bất kỳ mô hình cơ sở dữ liệu quan hệ.


54
Các mô hình, có. Việc thực hiện, không cần thiết, chỉ có thể hữu ích.
dkretz

4
Xin lỗi, nhưng lý do chính khiến các nhà phát triển ứng dụng không sử dụng các hệ thống quản lý cơ sở dữ liệu đối tượng (còn gọi là cơ sở dữ liệu NoQuery!) Là vì ​​đầu tư vào RDBMS. Hầu hết thời gian cơ sở dữ liệu (không phải hệ thống quản lý cơ sở dữ liệu) là một mô hình đối tượng trung cấp thường liên quan đến bộ nhớ cache phân tán. Đây là nơi xóa tầng, quyền sở hữu và đồng bộ hóa các thay đổi phải xảy ra bằng mọi cách. RDBMS được sử dụng chủ yếu cho sự kiên trì của mô hình đối tượng này và thường sau một bài tập ORM siêng năng và thực tế không có giá trị. Mô hình quan hệ là hầu hết thời gian không cần thiết!
Sentinel

2
không, khóa ngoại không bắt buộc phải biểu thị "quan hệ"
Silver Moon

Điều này không thực sự giải thích nhiều.
Nae

29

Tôi luôn sử dụng chúng, nhưng sau đó tôi tạo cơ sở dữ liệu cho các hệ thống tài chính. Cơ sở dữ liệu là phần quan trọng của ứng dụng. Nếu dữ liệu trong cơ sở dữ liệu tài chính không hoàn toàn chính xác thì thực sự không quan trọng bạn bỏ bao nhiêu công sức vào thiết kế mã / thiết bị đầu cuối của mình. Bạn đang lãng phí thời gian của bạn.

Ngoài ra còn có một thực tế là nhiều hệ thống thường cần giao tiếp trực tiếp với cơ sở dữ liệu - từ các hệ thống khác chỉ đọc dữ liệu (Báo cáo tinh thể) đến các hệ thống chèn dữ liệu (không nhất thiết phải sử dụng API tôi đã thiết kế; có thể được viết bởi một người quản lý buồn tẻ, người vừa phát hiện ra VBScript và có mật khẩu SA cho hộp SQL). Nếu cơ sở dữ liệu không phải là bằng chứng ngu ngốc như nó có thể, thì tạm biệt cơ sở dữ liệu.

Nếu dữ liệu của bạn là quan trọng, thì có, sử dụng khóa ngoại, tạo một bộ thủ tục được lưu trữ để tương tác với dữ liệu và tạo DB khó nhất mà bạn có thể. Nếu dữ liệu của bạn không quan trọng, tại sao bạn bắt đầu tạo cơ sở dữ liệu?


2
Cái nhìn sâu sắc tốt đẹp. Tôi cho rằng dữ liệu này rất quan trọng đối với mọi ứng dụng thực sự được sử dụng. Điều duy nhất khác biệt là hậu quả của dữ liệu bị hỏng. Chúng rất cao cho loại ứng dụng của bạn ...
Jay Godse

20

Cập nhật : Tôi luôn sử dụng khóa ngoại bây giờ. Câu trả lời của tôi cho sự phản đối "họ kiểm tra phức tạp" là "viết bài kiểm tra đơn vị của bạn để họ không cần cơ sở dữ liệu. Mọi bài kiểm tra sử dụng cơ sở dữ liệu nên sử dụng đúng cách và bao gồm các khóa ngoại. tìm một cách ít đau đớn hơn để thực hiện thiết lập. "


Khóa ngoại làm phức tạp kiểm tra tự động

Giả sử bạn đang sử dụng khóa ngoại. Bạn đang viết một bài kiểm tra tự động có nội dung "khi tôi cập nhật tài khoản tài chính, nó sẽ lưu bản ghi giao dịch." Trong thử nghiệm này, bạn chỉ quan tâm đến hai bảng: accountstransactions.

Tuy nhiên, accountscó khóa ngoại contracts, và contractscó fk clients, và clientscó fk cities, và citiescó fk states.

Bây giờ cơ sở dữ liệu sẽ không cho phép bạn chạy thử nghiệm mà không thiết lập dữ liệu trong bốn bảng không liên quan đến thử nghiệm của bạn .

Có ít nhất hai quan điểm có thể về điều này:

  • "Đó là một điều tốt: thử nghiệm của bạn phải thực tế và những hạn chế dữ liệu đó sẽ tồn tại trong sản xuất."
  • "Đó là một điều tồi tệ: bạn sẽ có thể đơn vị kiểm tra các phần của hệ thống mà không liên quan đến các phần khác. Bạn có thể thêm các bài kiểm tra tích hợp cho toàn bộ hệ thống."

Cũng có thể tạm thời tắt kiểm tra khóa ngoại trong khi chạy kiểm tra. MySQL, ít nhất, hỗ trợ này .


Tôi thấy mình thường đi theo đường giữa ở đây: Tôi sử dụng FK, sau đó tôi viết các phương thức trợ giúp kiểm tra đơn vị thiết lập DB để hỗ trợ các kịch bản thử nghiệm khác nhau, ví dụ: phương thức trợ giúp để đưa vào "thành phố" và "trạng thái" cho bất kỳ thử nghiệm nào cần những bảng đó.
tham gia

Có lẽ bạn nên sử dụng các bảng liên kết giữa các thực thể không liên quan. Hoặc đi xa hơn - DBS riêng biệt: xem xét tình huống trong Kiến trúc hướng dịch vụ hoặc microservice, trong đó mỗi phần tử (máy khách, tài khoản, giao dịch) là các hệ thống khác nhau, với các DB khác nhau. Không có FK giữa chúng là tất cả. Trong trường hợp này, FK nên được sử dụng để ngăn chặn dữ liệu mồ côi trong các phụ đề cho từng loại dữ liệu.
JeeBee

3
Ngoài ra còn có DBMS cho phép ràng buộc để hoãn lại để chúng chỉ được kiểm tra khi bạn thực hiện toàn bộ giao dịch, vì vậy thứ tự chèn, cập nhật, xóa không thành vấn đề
a_horse_with_no_name

2
Nếu bạn đang kiểm tra bản cập nhật từ lớp doanh nghiệp, môi trường phát triển của bạn sẽ có FK hiện tại. Khi bạn cập nhật hồ sơ của mình, bạn sẽ có các giá trị cột bạn cần để cập nhật thành công. Nếu không, IMHO bài kiểm tra của bạn không hợp lệ.
KeyOfJ

3
Cơ sở dữ liệu của bạn thậm chí không nên tham gia vào các bài kiểm tra đơn vị của bạn, bạn nên chế giễu chúng. Khi kiểm tra tích hợp, họ sẽ tham gia nhưng bất kỳ vấn đề nào do khóa ngoại là điều mà người dùng của bạn cũng sẽ gặp phải trừ khi bạn sửa nó.
Andreas Bergström

16

"Họ có thể làm cho việc xóa các bản ghi trở nên cồng kềnh hơn - bạn không thể xóa bản ghi" chính "trong đó có các bản ghi trong các bảng khác nơi các khóa ngoại sẽ vi phạm ràng buộc đó."

Điều quan trọng cần nhớ là tiêu chuẩn SQL xác định các hành động được thực hiện khi khóa ngoại bị xóa hoặc cập nhật. Những cái tôi biết là:

  • ON DELETE RESTRICT- Ngăn chặn bất kỳ hàng nào trong bảng khác có khóa trong cột này bị xóa. Đây là những gì Ken Ray đã mô tả ở trên.
  • ON DELETE CASCADE - Nếu một hàng trong bảng khác bị xóa, hãy xóa bất kỳ hàng nào trong bảng này tham chiếu đến nó.
  • ON DELETE SET DEFAULT - Nếu một hàng trong bảng khác bị xóa, hãy đặt bất kỳ khóa ngoại nào tham chiếu đến mặc định của cột.
  • ON DELETE SET NULL - Nếu một hàng trong bảng khác bị xóa, hãy đặt bất kỳ khóa ngoại nào tham chiếu nó trong bảng này thành null.
  • ON DELETE NO ACTION- Khóa ngoại này chỉ đánh dấu rằng đó là khóa ngoại; cụ thể là để sử dụng trong OR mapper.

Những hành động tương tự cũng được áp dụng cho ON UPDATE .

Mặc định dường như phụ thuộc vào máy chủ bạn đang sử dụng.


14

@imphasing - đây chính xác là kiểu suy nghĩ gây ra ác mộng bảo trì.

Tại sao oh tại sao bạn lại bỏ qua tính toàn vẹn tham chiếu khai báo, trong đó dữ liệu có thể được đảm bảo ít nhất là nhất quán, có lợi cho cái gọi là "thực thi phần mềm", đây là biện pháp phòng ngừa yếu nhất.


Bởi vì các nhà phát triển liên quan chưa bao giờ giải quyết một vấn đề đòi hỏi một mô hình quan hệ không tầm thường, bình thường hóa. Nhiều vấn đề không, đặc biệt là loại có rất nhiều trong lập trình loại web / "phương tiện truyền thông xã hội" đang là cơn sốt hiện nay. Nếu bất cứ điều gì rê bóng ở mặt sau của khung ORM đều thỏa mãn vấn đề ở dạng alpha, thì khó có ai có thể nghĩ nhiều hơn về mô hình hóa dữ liệu. Nhiều vấn đề như vậy dễ dàng được xử lý bởi các cửa hàng K / V, cơ sở dữ liệu tài liệu hoặc tuần tự hóa đối tượng thẳng.
zxq9

12

Có một lý do chính đáng để không sử dụng chúng: Nếu bạn không hiểu vai trò của họ hoặc cách sử dụng chúng.

Trong các tình huống sai, các ràng buộc khóa ngoại có thể dẫn đến sự nhân rộng của thác nước. Nếu ai đó loại bỏ hồ sơ sai, hoàn tác nó có thể trở thành một nhiệm vụ voi ma mút.

Ngoài ra, ngược lại, khi bạn cần loại bỏ một cái gì đó, nếu được thiết kế kém, các ràng buộc có thể gây ra tất cả các loại khóa ngăn cản bạn.


8
Xóa một hàng trong sản xuất mà không sao lưu không phải là một đối số hợp lệ. Nếu bạn không hiểu họ, bạn nên xem xét việc tìm hiểu về nó thay vì bỏ qua nó.
Guillaume

2
@Guillaume Tôi nghĩ rằng câu trả lời của anh ấy hơi mỉa mai, không được hiểu theo nghĩa đen: nếu bạn không hiểu chúng, thì đừng sử dụng chúng. Nhưng tất nhiên bạn nên hiểu và sử dụng chúng.
Benjamin

^ Cái này Chúng là những công cụ hữu ích, nhưng trong tay của một người mới, chúng là những công cụ nguy hiểm.
Kent Fredric

11

Không có tốt lý do không sử dụng chúng ... trừ khi hàng mồ côi không phải là một vấn đề lớn đối với bạn tôi đoán.


11
Tại sao các hàng mồ côi là một vấn đề lớn?
Seun Osewa

2
Còn đa luồng thì sao? Chúng có thể gây ra cơn ác mộng đa luồng trong những tình huống nhất định. Trong một ứng dụng phức tạp có nhiều luồng ghi cơ sở dữ liệu có thể gặp các đối tượng cần tham chiếu lẫn nhau, tốt hơn là kiểm soát tính toàn vẹn tham chiếu trong logic nghiệp vụ --- đặc biệt nếu các bảng sẽ chuyển sang tĩnh sau đó.
Keith Pinson

Tôi đồng ý. Ngoài ra, tôi thích có các hàng ophan mà tôi có thể phục hồi sau này, hơn là loại bỏ chúng không thương tiếc.
PedroD

4

Câu hỏi lớn hơn là: bạn có lái xe bịt mắt không? Đó là như thế nào nếu bạn phát triển một hệ thống mà không có ràng buộc tham chiếu. Hãy nhớ rằng các yêu cầu nghiệp vụ thay đổi, thay đổi thiết kế ứng dụng, các giả định logic tương ứng trong các thay đổi mã, bản thân logic có thể được cấu trúc lại, v.v. Nói chung, các ràng buộc trong cơ sở dữ liệu được đặt theo các giả định logic hiện đại, dường như chính xác cho các xác nhận và giả định logic cụ thể.

Thông qua vòng đời của một ứng dụng, tham chiếu và kiểm tra dữ liệu ràng buộc việc thu thập dữ liệu của cảnh sát thông qua ứng dụng, đặc biệt là khi các yêu cầu mới thúc đẩy ứng dụng logic thay đổi.

Đối với chủ đề của danh sách này - một khóa ngoại không tự nó "cải thiện hiệu suất", cũng không "làm giảm hiệu suất" đáng kể từ quan điểm của hệ thống xử lý giao dịch thời gian thực. Tuy nhiên, có một chi phí tổng hợp để kiểm tra ràng buộc trong hệ thống "lô" khối lượng CAO. Vì vậy, đây là sự khác biệt, thời gian thực so với quy trình giao dịch hàng loạt; xử lý hàng loạt - trong đó chi phí được xử lý, được đảm bảo bằng các kiểm tra ràng buộc, của một lô được xử lý tuần tự đặt ra một cú đánh hiệu suất.

Trong một hệ thống được thiết kế tốt, kiểm tra tính nhất quán dữ liệu sẽ được thực hiện "trước khi" xử lý một lô thông qua (tuy nhiên, cũng có một chi phí liên quan ở đây); do đó, kiểm tra ràng buộc khóa ngoại không được yêu cầu trong thời gian tải. Trong thực tế, tất cả các ràng buộc, bao gồm cả khóa ngoại, nên tạm thời bị vô hiệu hóa cho đến khi lô được xử lý.

HIỆU SUẤT QUAY - nếu các bảng được nối trên các khóa ngoại, hãy nhận thức được thực tế rằng các cột khóa ngoại không bị CHỈ ĐỊNH (mặc dù khóa chính tương ứng được lập chỉ mục theo định nghĩa). Bằng cách lập chỉ mục một khóa ngoại, đối với vấn đề đó, bằng cách lập chỉ mục cho bất kỳ khóa nào và tham gia các bảng trên chỉ mục sẽ giúp thực hiện tốt hơn, chứ không phải bằng cách tham gia vào khóa không được lập chỉ mục với ràng buộc khóa ngoại đối với nó.

Thay đổi chủ đề , nếu cơ sở dữ liệu chỉ hỗ trợ hiển thị / hiển thị nội dung trang web / vv và ghi lại các lần nhấp, thì cơ sở dữ liệu có đầy đủ các ràng buộc trên tất cả các bảng sẽ bị hủy vì các mục đích đó. Hãy suy nghĩ về nó. Hầu hết các trang web thậm chí không sử dụng cơ sở dữ liệu cho việc đó. Đối với các yêu cầu tương tự, khi dữ liệu chỉ được ghi lại và không được tham chiếu mỗi lần nói, hãy sử dụng cơ sở dữ liệu trong bộ nhớ, không có ràng buộc. Điều này không có nghĩa là không có mô hình dữ liệu, có mô hình logic, nhưng không có mô hình dữ liệu vật lý.


Chà, tôi không biết tại sao chèn 3 dòng mới vào chỗ trống và thay đổi hai từ được tính là '67% là Jonathan Leffler ', nhưng tôi không nghĩ rằng tôi đã làm bất cứ điều gì tương tự như vậy. Văn bản chính được đóng góp bởi @jay (người dùng 183837).
Jonathan Leffler

Tôi chỉ cho rằng paragrahps sẽ không hoạt động ở đây như trường hợp của hầu hết các trang web khác. Vì vậy, tôi đặt tất cả làm một, sử dụng chữ in đậm để thay đổi dòng chảy.
jasbir L

3

Lý do bổ sung để sử dụng Khóa ngoài: - Cho phép sử dụng lại cơ sở dữ liệu nhiều hơn

Lý do bổ sung để KHÔNG sử dụng Khóa ngoại: - Bạn đang cố gắng khóa khách hàng vào công cụ của mình bằng cách giảm sử dụng lại.


3

Theo kinh nghiệm của tôi, tốt hơn hết là tránh sử dụng FK trong các ứng dụng quan trọng của cơ sở dữ liệu. Tôi sẽ không đồng ý với những người ở đây nói rằng FK là một cách thực hành tốt nhưng nó không thực tế khi cơ sở dữ liệu rất lớn và có các hoạt động CRUD / giây rất lớn. Tôi có thể chia sẻ mà không cần đặt tên ... một trong những ngân hàng đầu tư lớn nhất không có FK duy nhất trong cơ sở dữ liệu. Các ràng buộc này được xử lý bởi các lập trình viên trong khi tạo các ứng dụng liên quan đến DB. Lý do cơ bản là khi CRUD mới được thực hiện, nó phải tạo ra nhiều bảng và xác minh cho mỗi lần chèn / cập nhật, mặc dù điều này sẽ không phải là vấn đề lớn đối với các truy vấn ảnh hưởng đến các hàng đơn lẻ nhưng nó tạo ra độ trễ rất lớn khi bạn xử lý xử lý hàng loạt mà bất kỳ ngân hàng lớn nào phải làm như nhiệm vụ hàng ngày.

Tốt hơn hết là tránh FK nhưng rủi ro của nó phải được xử lý bởi các lập trình viên.


8
Tôi không nghĩ các hoạt động phát triển tại các ngân hàng lớn đặt ra tiêu chuẩn vàng.
Adriaan Koster

3

"Trước khi thêm bản ghi, hãy kiểm tra xem bản ghi tương ứng có tồn tại trong bảng khác không" là logic nghiệp vụ.

Dưới đây là một số lý do bạn không muốn điều này trong cơ sở dữ liệu:

  1. Nếu quy tắc kinh doanh thay đổi, bạn phải thay đổi cơ sở dữ liệu. Cơ sở dữ liệu sẽ cần phải tạo lại chỉ mục trong rất nhiều trường hợp và điều này chậm trên các bảng lớn. (Thay đổi quy tắc bao gồm: cho phép khách đăng tin nhắn hoặc cho phép người dùng xóa tài khoản của họ mặc dù đã đăng bình luận, v.v.).

  2. Thay đổi cơ sở dữ liệu không dễ như triển khai sửa lỗi phần mềm bằng cách đẩy các thay đổi vào kho lưu trữ sản xuất. Chúng tôi muốn tránh thay đổi cấu trúc cơ sở dữ liệu càng nhiều càng tốt. Càng có nhiều logic kinh doanh trong cơ sở dữ liệu, bạn càng tăng cơ hội cần thay đổi databae (và kích hoạt lập chỉ mục lại).

  3. TDD. Trong các bài kiểm tra đơn vị, bạn có thể thay thế cơ sở dữ liệu cho các giả và kiểm tra chức năng. Nếu bạn có bất kỳ logic nghiệp vụ nào trong cơ sở dữ liệu của mình, bạn không thực hiện các kiểm tra hoàn chỉnh và sẽ cần kiểm tra với cơ sở dữ liệu hoặc sao chép logic nghiệp vụ trong mã cho mục đích thử nghiệm, sao chép logic và tăng khả năng logic không hoạt động trong cùng một cách

  4. Sử dụng lại logic của bạn với các nguồn dữ liệu khác nhau. Nếu không có logic trong cơ sở dữ liệu, ứng dụng của tôi có thể tạo các đối tượng từ các bản ghi từ cơ sở dữ liệu, tạo chúng từ một dịch vụ web, tệp json hoặc bất kỳ nguồn nào khác. Tôi chỉ cần trao đổi việc thực hiện ánh xạ dữ liệu và có thể sử dụng tất cả logic kinh doanh của mình với bất kỳ nguồn nào. Nếu có logic trong cơ sở dữ liệu, điều này là không thể và bạn phải triển khai logic ở lớp trình ánh xạ dữ liệu hoặc trong logic nghiệp vụ. Dù bằng cách nào, bạn cần những kiểm tra trong mã của bạn. Nếu không có logic trong cơ sở dữ liệu, tôi có thể triển khai ứng dụng ở các vị trí khác nhau bằng cách sử dụng các cơ sở dữ liệu hoặc tệp phẳng khác nhau.


2

Tôi đồng ý với các câu trả lời trước đó ở chỗ chúng rất hữu ích để duy trì tính nhất quán của dữ liệu. Tuy nhiên, có một bài viết thú vị của Jeff Atwood vài tuần trước đã thảo luận về những ưu và nhược điểm của dữ liệu được chuẩn hóa và nhất quán.

Nói cách khác, một cơ sở dữ liệu không chuẩn hóa có thể nhanh hơn khi xử lý lượng dữ liệu khổng lồ; và bạn có thể không quan tâm đến tính nhất quán chính xác tùy thuộc vào ứng dụng, nhưng điều đó buộc bạn phải cẩn thận hơn nhiều khi xử lý dữ liệu, vì DB sẽ không như vậy.


Jeff làm cho một số điểm tốt. Tuy nhiên, Dan Chak trong "Enterprise Rails" cho thấy một cách để thiết kế các bảng bộ đệm về cơ bản là một bản sao dữ liệu không chuẩn hóa. Các truy vấn chạy nhanh và nếu bảng không phải được làm mới, nó hoạt động tốt. Tôi thấy rằng nếu dữ liệu của bạn điều khiển hành vi (ví dụ trạng thái ứng dụng) của ứng dụng, bạn cần dữ liệu được chuẩn hóa càng nhiều càng tốt vì nếu không dữ liệu không nhất quán sẽ dẫn đến hành vi ứng dụng không nhất quán.
Jay Godse

Kho dữ liệu không chuẩn hóa có thể được sử dụng khi đọc khối lượng dữ liệu lớn trên các đường dẫn truy cập nhất quán, được dự đoán trước . Trong tất cả các kịch bản khác, đây là một ngụy biện nguy hiểm.
Peter Wone

2

Cơ sở dữ liệu Clarify là một ví dụ về cơ sở dữ liệu thương mại không có khóa chính hoặc khóa ngoài.

http://www.geekinterview.com/question_details/18869

Điều buồn cười là, tài liệu kỹ thuật có độ dài lớn để giải thích các bảng có liên quan như thế nào, sử dụng cột nào để tham gia chúng, v.v.

Nói cách khác, họ có thể đã tham gia các bảng với khai báo rõ ràng (DRI) nhưng họ đã chọn không .

Do đó, cơ sở dữ liệu Clarify chứa đầy sự không nhất quán và nó hoạt động kém.

Nhưng tôi cho rằng nó làm cho các nhà phát triển làm việc dễ dàng hơn, không phải viết mã để xử lý tính toàn vẹn tham chiếu như kiểm tra các hàng liên quan trước khi xóa, thêm.

Và điều đó, tôi nghĩ, là lợi ích chính của việc không có các ràng buộc khóa ngoài trong cơ sở dữ liệu quan hệ. Nó làm cho nó dễ dàng hơn để phát triển, ít nhất đó là từ quan điểm có thể quan tâm đến ma quỷ.


Mã để xử lý kiểm tra tính toàn vẹn tham chiếu không thành công nhỏ hơn rất nhiều so với mã để xử lý dữ liệu không nhất quán.
Jay Godse

@Jay đồng ý! Đừng nghĩ rằng tôi ủng hộ cách tiếp cận này.
Ed Guiness

2

Tôi chỉ biết cơ sở dữ liệu Oracle, không có cơ sở dữ liệu nào khác và tôi có thể nói rằng Khóa ngoài là điều cần thiết để duy trì tính toàn vẹn dữ liệu. Trước khi chèn dữ liệu, cấu trúc dữ liệu cần được thực hiện và được thực hiện chính xác. Khi điều đó được thực hiện - và do đó, tất cả các khóa chính VÀ khóa ngoài được tạo - công việc đã hoàn tất!

Ý nghĩa: hàng mồ côi? Không bao giờ thấy điều đó trong cuộc sống của tôi. Trừ khi một lập trình viên tồi quên khóa ngoại, hoặc nếu anh ta thực hiện nó ở cấp độ khác. Cả hai - trong bối cảnh của Oracle - những sai lầm lớn, sẽ dẫn đến sao chép dữ liệu, dữ liệu mồ côi và do đó: tham nhũng dữ liệu. Tôi không thể tưởng tượng một cơ sở dữ liệu mà không có FK thi hành. Có vẻ như hỗn loạn với tôi. Nó hơi giống với hệ thống cấp phép Unix: hãy tưởng tượng rằng mọi người đều đã root. Hãy nghĩ về sự hỗn loạn.

Khóa ngoại là rất cần thiết, giống như Khóa chính. Nó giống như nói: nếu chúng ta loại bỏ Khóa chính thì sao? Vâng, sự hỗn loạn hoàn toàn sẽ xảy ra. Đó là những gì. Bạn không được chuyển trách nhiệm chính hoặc khóa ngoại sang cấp lập trình, nó phải ở cấp dữ liệu.

Hạn chế? Chắc chắn rồi ! Bởi vì khi chèn, rất nhiều kiểm tra sẽ xảy ra. Nhưng, nếu tính toàn vẹn dữ liệu quan trọng hơn hiệu suất, thì đó là điều không có trí tuệ. Vấn đề với hiệu suất trên Oracle liên quan nhiều hơn đến các chỉ mục, đi kèm với PK và FK.


1

Họ có thể làm cho việc xóa các bản ghi trở nên cồng kềnh hơn - bạn không thể xóa bản ghi "chính" trong đó có các bản ghi trong các bảng khác nơi các khóa ngoại sẽ vi phạm ràng buộc đó. Bạn có thể sử dụng kích hoạt để xóa tầng.

Nếu bạn chọn khóa chính của mình một cách không chính xác, thì việc thay đổi giá trị đó càng trở nên phức tạp hơn. Ví dụ: nếu tôi có PK của bảng "khách hàng" của mình làm tên của người đó và biến khóa đó thành FK trong bảng "đơn hàng", nếu khách hàng muốn đổi tên, thì đó là một nỗi đau hoàng gia .. Nhưng đó chỉ là thiết kế cơ sở dữ liệu kém chất lượng.

Tôi tin rằng những lợi thế trong việc sử dụng các phím fireign vượt trội hơn bất kỳ nhược điểm nào được cho là.


5
Tôi có xu hướng hiếm khi xóa mọi thứ. Chỉ cần đánh dấu có một bit "Hiển thị / hoạt động".
Dana

+1 cho "Tôi tin rằng những lợi thế trong việc sử dụng các phím lửa vượt trội hơn bất kỳ nhược điểm nào được cho là"
Ian Boyd

2
Bạn không bao giờ, thay đổi giá trị của khóa chính. Bạn xóa toàn bộ hàng và tạo lại nó khác nhau. Nếu bạn nghĩ rằng bạn cần thay đổi nó, lược đồ của bạn là thiếu sót.
DanMan

Thay đổi tên khách hàng sẽ không gây khó khăn chút nào NẾU khóa ngoại của bạn được đặt trên CustomerId (PK). trong bảng đơn hàng. Cách duy nhất sẽ là một nỗi đau là nếu FK được đặt trên Tên khách hàng, điều không bao giờ nên xảy ra. IMHO
KeyOfJ

1

Việc xác minh các ràng buộc khóa ngoài cần một chút thời gian của CPU, vì vậy một số người bỏ qua các khóa ngoại để có thêm hiệu suất.


6
Bao nhiêu thời gian CPU được dành để loại bỏ dữ liệu trùng lặp và không nhất quán?
Ed Guiness

Vâng, đây là sự thật. Trên một hệ thống tôi làm việc, chúng tôi phải chèn 10 - 40 hợp đồng dữ liệu cùng một lúc vào cơ sở dữ liệu và hiệu suất FK có và không có thể nhìn thấy trong tổng thời gian cần thiết.
Paul Mendoza

1

Tôi cũng đã nghe lập luận này - từ những người quên đặt chỉ mục vào khóa ngoại của họ và sau đó phàn nàn rằng các hoạt động nhất định là chậm (vì kiểm tra ràng buộc có thể tận dụng bất kỳ chỉ mục nào). Vì vậy, để tóm tắt: Không có lý do chính đáng để không sử dụng khóa ngoại. Tất cả các cơ sở dữ liệu hiện đại đều hỗ trợ xóa tầng, vì vậy ...


9
Tôi tin rằng lý do thực sự khiến các ràng buộc FK không được một số người sử dụng (hầu hết, theo quan điểm của tôi) là sự lười biếng tuyệt đối dưới sự giả vờ rằng họ có thể bảo vệ sự lười biếng của mình bằng lập luận tiết kiệm hiệu suất. Tôi tin chắc rằng phần lớn Chi phí ngu ngốc mà công ty chúng tôi phải gánh chịu là do thiếu thực thi các ràng buộc FK và hiệu ứng gợn mà điều này đã thông qua một công ty. Thiếu các khóa duy nhất là điều khác khiến tôi thất vọng bên cạnh hơn 2000 quy trình được lưu trữ với 12 cấp độ IF lồng nhau và thụt lề ngẫu nhiên, nhưng tôi sẽ dừng ngay bây giờ.
Chad

1

Lập luận tôi đã nghe là front-end nên có các quy tắc kinh doanh này. Khóa ngoại "thêm chi phí không cần thiết" khi bạn không nên cho phép bất kỳ thao tác chèn nào phá vỡ các ràng buộc của bạn ở vị trí đầu tiên. Tôi có đồng ý với điều này không? Không, nhưng đó là những gì tôi đã luôn luôn nghe.

EDIT: Tôi đoán là anh ấy đã đề cập đến các ràng buộc khóa ngoại , không phải là khóa ngoại như một khái niệm.


Không. Anh ấy không thích chìa khóa thực tế!
LJS

Điều đó làm tôi ngạc nhiên. Có một sự khác biệt lớn giữa việc không thích các ràng buộc khóa ngoại và không thích khóa ngoại. Tôi không chắc làm thế nào bạn có một cơ sở dữ liệu quan hệ mà không có chúng.
lordscarlet

Có tôi đã bị sốc khi nghe anh ấy. Tuy nhiên, anh ta có thể đã vô tình tặc lưỡi; có lẽ anh ấy sẽ đăng ở đây và làm rõ ở một số giai đoạn :-)
ljs

1

Đối với tôi, nếu bạn muốn tuân theo các tiêu chuẩn ACID , điều quan trọng là phải có khóa ngoại để đảm bảo tính toàn vẹn tham chiếu.


1

Tôi phải thứ hai hầu hết các ý kiến ​​ở đây, Khóa ngoại là các mục cần thiết để đảm bảo rằng bạn có dữ liệu với tính toàn vẹn. Các tùy chọn khác nhau cho BẬT XÓA và CẬP NHẬT sẽ cho phép bạn khắc phục một số "sự cố" mà mọi người đề cập ở đây liên quan đến việc sử dụng chúng.

Tôi thấy rằng trong 99% tất cả các dự án của mình, tôi sẽ có FK để thực thi tính toàn vẹn của dữ liệu, tuy nhiên, có những lần hiếm hoi tôi có khách hàng PHẢI giữ dữ liệu cũ của họ, bất kể nó tệ đến mức nào .... nhưng sau đó tôi dành rất nhiều thời gian để viết mã đi vào để chỉ nhận được dữ liệu hợp lệ, vì vậy nó trở nên vô nghĩa.


1

Làm thế nào về khả năng duy trì và kiên định trong suốt vòng đời ứng dụng? Hầu hết dữ liệu có tuổi thọ dài hơn các ứng dụng sử dụng nó. Mối quan hệ và tính toàn vẹn dữ liệu là quá quan trọng để hy vọng rằng nhóm nhà phát triển tiếp theo có được nó ngay trong mã ứng dụng. Nếu bạn chưa từng làm việc với db với dữ liệu bẩn không tôn trọng các mối quan hệ tự nhiên, bạn sẽ làm được. Tầm quan trọng của tính toàn vẹn dữ liệu sau đó sẽ trở nên rất rõ ràng.


1

Tôi cũng nghĩ rằng khóa ngoại là cần thiết trong hầu hết các cơ sở dữ liệu. Hạn chế duy nhất (bên cạnh hiệu năng đạt được khi có tính nhất quán bắt buộc) là có khóa ngoại cho phép mọi người viết mã giả sử có khóa ngoại chức năng. Điều đó không bao giờ nên được cho phép.

Ví dụ: tôi đã thấy mọi người viết mã chèn vào bảng được tham chiếu và sau đó thử chèn vào bảng tham chiếu mà không xác minh lần chèn đầu tiên đã thành công. Nếu khóa ngoại được xóa sau đó, điều đó dẫn đến cơ sở dữ liệu không nhất quán.

Bạn cũng không có tùy chọn giả định một hành vi cụ thể về cập nhật hoặc xóa. Bạn vẫn cần phải viết mã của bạn để làm những gì bạn muốn bất kể có khóa ngoại không. Nếu bạn cho rằng các lần xóa được xếp tầng khi không, các lần xóa của bạn sẽ thất bại. Nếu bạn cho rằng các cập nhật cho các cột được tham chiếu được hỗ trợ cho các hàng tham chiếu khi chúng không có, các cập nhật của bạn sẽ thất bại. Đối với mục đích viết mã, bạn cũng có thể không có các tính năng đó.

Nếu các tính năng đó được bật, thì mã của bạn sẽ mô phỏng chúng bằng mọi cách và bạn sẽ mất một chút hiệu suất.

Vì vậy, tóm tắt .... Khóa ngoại là rất cần thiết nếu bạn cần một cơ sở dữ liệu nhất quán. Khóa ngoại không bao giờ được coi là có mặt hoặc có chức năng trong mã mà bạn viết.


1

Tôi lặp lại câu trả lời của Dmitriy - rất tốt.

Đối với những người lo lắng về chi phí hiệu năng mà FK thường mang lại, có một cách (trong Oracle), bạn có thể có được lợi thế tối ưu hóa truy vấn của ràng buộc FK mà không cần chi phí xác thực ràng buộc trong quá trình chèn, xóa hoặc cập nhật. Đó là tạo ra ràng buộc FK với các thuộc tính LIÊN QUAN ĐẾN NOVALIDATE. Điều này có nghĩa là trình tối ưu hóa truy vấn ASSUMES rằng ràng buộc đã được thi hành khi xây dựng các truy vấn, mà không có cơ sở dữ liệu thực sự thực thi ràng buộc. Bạn phải rất cẩn thận ở đây để chịu trách nhiệm khi bạn điền vào bảng có ràng buộc FK như thế này để đảm bảo chắc chắn rằng bạn không có dữ liệu trong (các) cột FK vi phạm ràng buộc đó, như thể bạn làm như vậy có thể nhận được kết quả không đáng tin cậy từ các truy vấn liên quan đến bảng ràng buộc FK này.

Tôi thường sử dụng chiến lược này trên một số bảng trong lược đồ mart dữ liệu của mình, nhưng không phải trong lược đồ phân tầng tích hợp. Tôi chắc chắn rằng các bảng tôi đang sao chép dữ liệu từ đó đã có cùng một ràng buộc được thi hành hoặc thường trình ETL thực thi ràng buộc đó.


1

Nhiều người trả lời ở đây quá nôn nao về tầm quan trọng của tính toàn vẹn tham chiếu được thực hiện thông qua các ràng buộc tham chiếu. Làm việc trên các cơ sở dữ liệu lớn với tính toàn vẹn tham chiếu chỉ không hoạt động tốt. Oracle có vẻ đặc biệt tệ trong việc xóa tầng. Nguyên tắc nhỏ của tôi là các ứng dụng không bao giờ nên cập nhật cơ sở dữ liệu trực tiếp và phải thông qua một thủ tục được lưu trữ. Điều này giữ cơ sở mã bên trong cơ sở dữ liệu và có nghĩa là cơ sở dữ liệu duy trì tính toàn vẹn của nó.

Khi nhiều ứng dụng có thể truy cập vào cơ sở dữ liệu, các vấn đề sẽ phát sinh do các ràng buộc toàn vẹn tham chiếu nhưng điều này nằm trong tầm kiểm soát.

Có một vấn đề rộng lớn hơn ở chỗ, các nhà phát triển ứng dụng có thể có những yêu cầu rất khác nhau mà các nhà phát triển cơ sở dữ liệu có thể không nhất thiết phải quen thuộc.


5
"các ứng dụng không bao giờ nên cập nhật cơ sở dữ liệu trực tiếp và phải thông qua một thủ tục được lưu trữ. Điều này giữ cơ sở mã bên trong cơ sở dữ liệu và có nghĩa là cơ sở dữ liệu duy trì tính toàn vẹn của nó." <- Có một giả định ở đây rằng logic trong các thủ tục được lưu trữ không thể vi phạm tính toàn vẹn dữ liệu, điều này hoàn toàn sai.
Tim Gautier

1

Nếu bạn chắc chắn tuyệt đối, rằng một hệ thống cơ sở dữ liệu cơ bản sẽ không thay đổi trong tương lai, tôi sẽ sử dụng các khóa ngoại để đảm bảo tính toàn vẹn dữ liệu.

Nhưng đây là một lý do thực tế rất tốt khác để không sử dụng khóa ngoại:

Bạn đang phát triển một sản phẩm, cần hỗ trợ các hệ thống cơ sở dữ liệu khác nhau.

Nếu bạn đang làm việc với Entity Framework, có thể kết nối với nhiều hệ thống cơ sở dữ liệu khác nhau, bạn cũng có thể muốn hỗ trợ cơ sở dữ liệu máy chủ "miễn phí mã nguồn mở". Không phải tất cả các cơ sở dữ liệu này có thể hỗ trợ các quy tắc khóa ngoài của bạn (cập nhật, xóa hàng ...).

Điều này có thể dẫn đến các vấn đề khác nhau:

1.) Bạn có thể gặp lỗi, khi cấu trúc cơ sở dữ liệu được tạo hoặc cập nhật. Có thể sẽ chỉ có các lỗi im lặng, vì các khóa ngoại của bạn bị hệ thống cơ sở dữ liệu bỏ qua.

2.) Nếu bạn dựa vào khóa ngoại, bạn có thể thực hiện ít hơn hoặc thậm chí không kiểm tra tính toàn vẹn dữ liệu trong logic kinh doanh của bạn. Bây giờ, nếu hệ thống cơ sở dữ liệu mới không hỗ trợ các quy tắc khóa ngoài này hoặc chỉ hành xử theo một cách khác, bạn phải viết lại logic nghiệp vụ của mình.

Bạn có thể hỏi: Ai cần các hệ thống cơ sở dữ liệu khác nhau? Chà, không phải ai cũng có đủ khả năng hoặc muốn có một SQL-Server toàn diện trên máy của mình. Đây là phần mềm, cần được duy trì. Những người khác đã đầu tư thời gian và tiền bạc vào một số hệ thống DB khác. Cơ sở dữ liệu không có máy chủ rất tốt cho các khách hàng nhỏ chỉ trên một máy.

Không ai biết, tất cả các hệ thống DB này hoạt động như thế nào, nhưng logic kinh doanh của bạn, với kiểm tra tính toàn vẹn, luôn giữ nguyên.


0

Tôi luôn nghĩ rằng thật lười biếng khi không sử dụng chúng. Tôi đã được dạy nó nên luôn luôn được thực hiện. Nhưng sau đó, tôi không nghe cuộc thảo luận của Joel. Anh ta có thể có một lý do tốt, tôi không biết.


Đó là một nhận xét ngoài lề hơn là một cuộc thảo luận, mặc dù có lẽ tôi nên nghiên cứu chính xác những gì anh ấy nghĩ về chủ đề này một cách độc lập! Tuy nhiên tôi cũng tò mò về ý kiến ​​của cộng đồng về chủ đề này!
LJS

0

Một lần khi FK có thể gây ra sự cố cho bạn là khi bạn có dữ liệu lịch sử tham chiếu khóa (trong bảng tra cứu) mặc dù bạn không còn muốn khóa đó nữa.
Rõ ràng giải pháp là thiết kế mọi thứ tốt hơn ở phía trước, nhưng tôi đang nghĩ về các tình huống trong thế giới thực ở đây nơi bạn không luôn kiểm soát được giải pháp đầy đủ.
Ví dụ: có lẽ bạn có một bảng tra cứucustomer_type liệt kê các loại khách hàng khác nhau - giả sử bạn cần xóa một loại khách hàng nhất định, nhưng (do hạn chế kinh doanh) không thể cập nhật phần mềm máy khách và không ai phát hiện ra tình huống này khi phát triển phần mềm, việc nó là khóa ngoại trong một số bảng khác có thể ngăn bạn xóa hàng ngay cả khi bạn biết dữ liệu lịch sử tham chiếu đến nó không liên quan.
Sau khi bị đốt cháy với điều này một vài lần, bạn có thể tránh xa việc thực thi các mối quan hệ db.
(Tôi không nói điều này là tốt - chỉ đưa ra một lý do tại sao bạn có thể quyết định tránh các hạn chế FK và db nói chung)


Nếu tôi hiểu những gì bạn đang cố gắng nói, tôi nghĩ câu trả lời của tôi cho điều đó sẽ là xóa một cách hợp lý bản ghi trong bảng tra cứu hoặc lưu trữ dữ liệu lịch sử không còn phù hợp và lưu trữ bản ghi tra cứu nữa.
Chad
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.