Tại sao không khớp khóa chính / khóa ngoại được sử dụng để tham gia?


48

Theo như tôi có thể tìm ra nhiều DBMS (ví dụ: mysql, postgres, mssql) chỉ sử dụng kết hợp fk và pk để hạn chế thay đổi dữ liệu, nhưng chúng hiếm khi được sử dụng để tự động chọn các cột để tham gia (như nối tự nhiên với tên). Tại sao vậy? Nếu bạn đã xác định mối quan hệ giữa 2 bảng với pk / fk, tại sao cơ sở dữ liệu không thể hiểu rằng nếu tôi tham gia các bảng đó, tôi muốn tham gia chúng trên các cột pk / fk?

EDIT: để làm rõ điều này một chút:

giả sử tôi có một bảng1 và một bảng2. bảng1 một có một khóa ngoại trên cột a, tham chiếu đến khóa chính trên bảng2, cột b. Bây giờ nếu tôi tham gia các bảng này, tôi sẽ phải làm một cái gì đó như thế này:

SELECT * FROM table1
JOIN table2 ON table1.a = table2.b

Tuy nhiên, tôi đã xác định bằng cách sử dụng các khóa của mình mà bảng1.a tham chiếu đến bảng2.b, do đó, có vẻ như tôi không khó để tạo một hệ thống DBMS tự động sử dụng bảng1.a và bảng2.b làm cột tham gia, sao cho người ta có thể đơn giản sử dụng:

SELECT * FROM table1
AUTO JOIN table2

Tuy nhiên, nhiều DBMS dường như không thực hiện một cái gì đó như thế này.

Câu trả lời:


32

Trong nhiều trường hợp, có nhiều hơn một cách để tham gia hai bảng; Xem các câu trả lời khác cho rất nhiều ví dụ. Tất nhiên, người ta có thể nói rằng sẽ là một lỗi khi sử dụng 'tham gia tự động' trong những trường hợp đó. Sau đó, chỉ một số ít các trường hợp đơn giản mà nó có thể được sử dụng sẽ được để lại.

Tuy nhiên, có một nhược điểm nghiêm trọng! Các truy vấn chính xác hôm nay, có thể trở thành lỗi vào ngày mai chỉ bằng cách thêm FK thứ hai vào cùng một bảng!

Hãy để tôi nói điều đó một lần nữa: bằng cách thêm các cột, các truy vấn không sử dụng các cột đó có thể chuyển từ 'chính xác' thành 'lỗi'!

Đó là một cơn ác mộng bảo trì, mà bất kỳ hướng dẫn phong cách lành mạnh nào cũng sẽ cấm sử dụng tính năng này. Hầu hết đã cấm select *vì lý do tương tự!

Tất cả điều này sẽ được chấp nhận, nếu hiệu suất sẽ được tăng cường. Tuy nhiên, đó không phải là trường hợp.

Tóm tắt, tính năng này chỉ có thể được sử dụng trong một số trường hợp đơn giản giới hạn, không làm tăng hiệu suất và hầu hết các hướng dẫn kiểu sẽ cấm sử dụng tính năng này.

Do đó, không có gì ngạc nhiên khi hầu hết các nhà cung cấp cơ sở dữ liệu chọn dành thời gian của họ cho những thứ quan trọng hơn.


1
Có khả năng sẽ có một hiệu suất nhỏ trong thực tế vì nó phải tìm ra các cột tham gia thay vì làm hỏng chúng.
HLGEM

1
@HLGEM, Điều đó có thể được lưu trong bộ nhớ cache và cũng không liên quan đến các truy vấn lớn hơn. Ưu điểm là chúng ta có thể chắc chắn rằng các phím không bị bỏ sót do một số lỗi của con người.
Pacerier

Việc thêm và thay đổi các cột cũng có thể phá vỡ NATURAL JOIN(đó là lý do tại sao tôi thường tránh chúng), nhưng tôi không nghĩ rằng chính điều đó có nghĩa là một dbms không thể thực hiện một cách tự động để nối các bảng dựa trên các khóa ngoại.
Jay K

2
Nhiều trường hợp? Trên một nghìn bảng DB, tôi chỉ có một vài trường hợp có quan hệ nhiều hơn 1 giữa hai bảng. Dù sao, đó không phải là một vấn đề, nó sẽ là đủ để thêm tên quan hệ như thế AUTO JOIN mytable THROUGH myrelation, nó sẽ rất tốt đẹp.
Teejay

Đó là những gì chúng tôi làm trong trình xây dựng .NET SQL được xây dựng tùy chỉnh của chúng tôi, với intellisense, nhưInnerJoin(SRC_TABLE.rDEST_TABLE.REL_NAME_F01)
Teejay 19/12/17

27

Khóa ngoại có nghĩa là hạn chế dữ liệu. tức là thực thi toàn vẹn tham chiếu. Đó là nó. Không có gì khác.

  1. Bạn có thể có nhiều khóa ngoại vào cùng một bảng. Hãy xem xét những điều sau đây trong đó một lô hàng có điểm bắt đầu và điểm kết thúc.

    table: USA_States
    StateID
    StateName
    
    table: Shipment
    ShipmentID
    PickupStateID Foreign key
    DeliveryStateID Foreign key

    Bạn có thể muốn tham gia dựa trên trạng thái đón. Có lẽ bạn muốn tham gia vào trạng thái giao hàng. Có lẽ bạn muốn thực hiện 2 lần tham gia cho cả hai! Động cơ sql không có cách nào để biết những gì bạn muốn.

  2. Bạn sẽ thường xuyên tham gia các giá trị vô hướng. Mặc dù vô hướng thường là kết quả của các tính toán trung gian, đôi khi bạn sẽ có một bảng mục đích đặc biệt với chính xác 1 bản ghi. Nếu động cơ cố gắng phát hiện khóa foriegn cho phép nối .... nó sẽ không có ý nghĩa vì các phép nối chéo không bao giờ khớp với một cột.

  3. Trong một số trường hợp đặc biệt, bạn sẽ tham gia vào các cột không phải là duy nhất. Do đó, sự hiện diện của PK / FK trên các cột đó là không thể.

  4. Bạn có thể nghĩ điểm 2 và 3 nêu trên không liên quan kể từ khi câu hỏi của bạn là về khi có một đơn PK / FK mối quan hệ giữa các bảng. Tuy nhiên, sự hiện diện của PK / FK đơn giữa các bảng không có nghĩa là bạn không thể có các trường khác để tham gia ngoài PK / FK. Công cụ sql sẽ không biết bạn muốn tham gia vào lĩnh vực nào.

  5. Hãy nói rằng bạn có một bảng "USA_States" và 5 bảng khác có FK cho các trạng thái. Các bảng "năm" cũng có một vài khóa ngoại với nhau. Công cụ sql có nên tự động tham gia các bảng "năm" với "USA_States" không? Hay nó nên tham gia "năm" với nhau? Cả hai? Bạn có thể thiết lập các mối quan hệ để công cụ sql đi vào một vòng lặp vô hạn cố gắng kết hợp các thứ lại với nhau. Trong tình huống này, không thể biết trước động cơ sql để đoán những gì bạn muốn.

Tóm lại: PK / FK không liên quan gì đến các phép nối bảng. Chúng là những thứ không liên quan riêng biệt. Đó chỉ là một tai nạn tự nhiên mà bạn thường tham gia trên các cột PK / FK.

Bạn có muốn công cụ sql đoán xem đó là một tham gia đầy đủ, trái, phải hoặc bên trong? Tôi không nghĩ vậy. Mặc dù điều đó có thể được coi là một tội lỗi ít hơn so với việc đoán các cột để tham gia.


7
Tôi coi các khóa ngoại và chuẩn hóa rất phù hợp với các phép nối bảng.

3
Đối số của bạn giữ khi từ khóa THAM GIA bình thường luôn cố gắng khớp với từ khóa đó (như tôi đã làm sai trong ví dụ của mình, tôi sẽ sửa lỗi đó). Tuy nhiên, nhiều liên kết có thể được lấy trực tiếp từ chỉ các liên kết vì vậy tôi không thấy bất kỳ lý do nào khiến không thể có bất kỳ cú pháp rõ ràng nào để tham gia chúng. Nhiều DBMS có một phép nối tự nhiên, về cơ bản là giống nhau nhưng với tên cột (= bad). Điều tương tự có thể được thực hiện với kiểu tham gia này, ví dụ: bằng cách chỉ định thao tác AUTO THAM GIA.

5
"Đó chỉ là một tai nạn tự nhiên mà bạn thường tham gia trên các cột PK / FK" - Tôi không bị thuyết phục!
onedaywhen ngày

2
"Bình thường hóa?" Tôi nghĩ rằng suy nghĩ ở đây là nếu bạn bắt đầu với một Relvar 1NF sau đó phân tách thành các relvar 6NF thì khả năng là a) họ sẽ có khóa ngoại khi thực hiện và b) họ sẽ thường xuyên được tham gia truy vấn.
onedaywhen ngày

4
Tôi sẽ nâng cao nếu không có "PK / FK không liên quan gì đến việc tham gia bảng."
ypercubeᵀᴹ

11

khái niệm "khả năng tham gia." Mối quan hệ r1r2có thể tham gia khi và chỉ khi các thuộc tính có cùng tên cùng loại ... khái niệm này không chỉ áp dụng để tham gia như vậy mà còn cho các hoạt động khác [chẳng hạn như liên minh].

Lý thuyết SQL và quan hệ: Cách viết mã SQL chính xác theo ngày của CJ

SQL chuẩn đã có một tính năng như vậy, được biết đến NATURAL JOINvà đã được triển khai trong myQuery.

Mặc dù đề xuất của bạn không hoàn toàn xứng đáng, nhưng nó có vẻ hợp lý. Với SQL Server ( thiếu hỗ trợNATURAL JOIN ), tôi sử dụng SQL Prompt trong Management Studio: khi viết INNER JOINInteliSense của nó gợi ý ONcác mệnh đề dựa trên cả tên thuộc tính chung và khóa ngoại và tôi thấy nó rất hữu ích. Mặc dù vậy, tôi không muốn thấy loại tham gia SQL (tiêu chuẩn) mới cho việc này.


1
Tham gia và tham gia tự nhiên trên các cột chung khác biệt với & trực giao với khái niệm tham gia trên FK-PK. (Xem câu trả lời của tôi.)
philipxy

@philipxy: đồng ý, tôi không có ý định nói khác. (Của bạn là một câu trả lời tuyệt vời!)
onedaywhen

9

SQL đến đầu tiên!

Các ràng buộc Khóa ngoài và Khóa ngoài xuất hiện sau và về cơ bản là tối ưu hóa cho các ứng dụng kiểu "giao dịch".

Các cơ sở dữ liệu quan hệ ban đầu được hình thành như một phương pháp áp dụng các truy vấn phức tạp trên các tập hợp dữ liệu theo cách có thể chứng minh bằng toán học bằng cách sử dụng đại số quan hệ. IE cho một tập hợp dữ liệu nhất định và một truy vấn nhất định luôn có một câu trả lời đúng duy nhất.

Các cơ sở dữ liệu quan hệ đã đi một chặng đường dài kể từ đó, và việc sử dụng chính là lớp kiên trì cho các hệ thống giao dịch không phải là những gì CODD et. tất cả dự tính.

Tuy nhiên, cơ quan tiêu chuẩn ANSI cho tất cả các mục tiêu mâu thuẫn và chính trị của nhà cung cấp luôn luôn cố gắng duy trì các thuộc tính "có thể chứng minh về mặt toán học" của SQL.

Nếu bạn cho phép cơ sở dữ liệu suy ra các thuộc tính tham gia từ dữ liệu khóa ngoài "ẩn", bạn sẽ mất thuộc tính này (xem xét sự mơ hồ nếu có nhiều hơn một bộ khóa ngoại được xác định).

Ngoài ra, một lập trình viên đọc SQL sẽ không nhất thiết phải biết khóa ngoại nào hiện được xác định cho hai bảng và, sẽ cần kiểm tra lược đồ cơ sở dữ liệu để tìm ra truy vấn đang làm gì.


3
Cảm ơn, điều này có ý nghĩa với tôi! Tuy nhiên, không tham gia tự nhiên có cùng một vấn đề? Mặc dù các phép nối tự nhiên thậm chí có vấn đề lớn hơn, nhiều DBMS hỗ trợ chúng. IMO một tham gia dựa trên pk / fk sẽ là một tham gia tự nhiên được thực hiện ngay.

1
Không có sự khác biệt nào khi hầu hết các công cụ cơ sở dữ liệu có liên quan giữa một phép nối tự nhiên và một "THAM GIA ... BẬT" rõ ràng. Công cụ phân tích truy vấn và thực hiện tham gia một cách tốt nhất có thể dựa trên các vị từ khác nhau. Sử dụng một phép nối rõ ràng không bắt buộc sử dụng một chỉ mục hoặc đường dẫn truy cập cụ thể, chủ yếu là để hỗ trợ cú pháp nối "LEFT, OUTER, INNER" cần biết các biến vị ngữ nối rõ ràng để biết khi nào nên chèn một hàng "thiếu" .

6
SQL đã không đến đầu tiên! Mô hình quan hệ (tất nhiên bao gồm khái niệm khóa ngoại) lần đầu tiên được EFCodd đưa ra vào năm 1969. SEQUEL, như lúc đó, đã không nhìn thấy ánh sáng cho đến khoảng năm 1974. Các nhà phát minh của nó đã làm rõ ngay từ đầu rằng SEQUEL / SQL được dự định dựa trên mô hình quan hệ đã có từ trước - mặc dù SQL đã không còn là một ngôn ngữ quan hệ thực sự.
nvogel

@sqlvogel - đúng! Nên phrased nó "SQL đã được thực hiện đầu tiên".
James Anderson

Ngày của CJ trong 'Giới thiệu về hệ thống cơ sở dữ liệu' (tr276) cho biết Codd đã phát minh ra khái niệm khóa ngoại; không nói khi nào nhưng tôi cho rằng đó là trước khi triển khai SQL đầu tiên.
ngày

7

Mặc dù bạn đã xác định mối quan hệ Khóa ngoài không có nghĩa đó là cách bạn muốn tham gia các bảng trong tất cả các truy vấn. Đây là phương pháp có thể xảy ra nhất để tham gia các bảng, nhưng có những trường hợp không chính xác.

  • Bạn có thể muốn sử dụng một sản phẩm của Cartesian trong hai bảng hoặc một phần của chúng cho một số mục đích.
  • Có thể có các lĩnh vực khác mà bạn có thể tham gia cho mục đích khác.
  • Nếu bạn đang tham gia ba hoặc nhiều bảng, một trong các bảng có thể liên quan đến hai hoặc nhiều bảng. Trong trường hợp này thường chỉ có một trong các mối quan hệ FK có thể có thể phù hợp trong truy vấn.

7

Bạn có thể đang hoạt động trên một giả định sai. Bạn nói 'theo như bạn có thể tìm ra' nhưng không đưa ra bất kỳ bằng chứng thực nghiệm hoặc bằng chứng nào. Nếu pk hoặc fk là chỉ mục tốt nhất cho truy vấn thì nó sẽ được sử dụng. Tôi không biết tại sao bạn lại thấy điều này, nhưng phỏng đoán của tôi là các truy vấn được hình thành kém.


Chỉnh sửa ngay bây giờ rằng câu hỏi đã được viết lại hoàn toàn: Trường hợp bạn đang mô tả sẽ chỉ dành cho một nhóm truy vấn rất nhỏ. Nếu có 12 bảng tham gia thì sao? Điều gì xảy ra nếu không có FK .... Ngay cả khi có một tham gia mặc định trên tôi vẫn sẽ luôn chỉ định tham gia chỉ để dễ đọc. (Tôi không muốn phải xem dữ liệu và sau đó cố gắng tìm hiểu xem cái gì đang được tham gia)

Một số công cụ Truy vấn thực sự tự động tham gia cho bạn sau đó cho phép bạn xóa hoặc chỉnh sửa tham gia. Tôi nghĩ Trình tạo truy vấn của MS Access thực hiện việc này.

Cuối cùng, tiêu chuẩn ANSII nói rằng việc tham gia phải được chỉ định. Đó là lý do đủ để không cho phép nó.


3
Xin lỗi, có lẽ tôi đã không đủ rõ ràng. Tôi không nói về chỉ mục, tôi đang nói về việc tham gia. Giả sử tôi có bảng1 và bảng2, với fk trên bảng1.a trỏ đến bảng2.b. Nếu tôi tham gia các bảng này, tôi sẽ phải nói rõ ràng rằng tôi muốn tham gia chúng trên các cột a và b (ví dụ: 'CHỌN * TỪ bảng1 THAM GIA bảng2 TRÊN bảng1.a = bảng2.b '), trong khi tôi đã xác định trong cơ sở dữ liệu của mình Đề án mà hai người có liên quan. Câu hỏi đặt ra là tại sao tôi không thể thực hiện 'CHỌN * TỪ bảng1 THAM GIA bảng2' và để DBMS tự động chọn các cột tham gia dựa trên fk / pk.

3
Đặc biệt là khả năng đọc có ý nghĩa với tôi! Tuy nhiên, tiêu chuẩn nói như vậy không phải là một cuộc tranh luận thực sự tốt IMO. Nhiều tiêu chuẩn đã đưa ra lựa chọn sai trước đây (ví dụ HTML).

3

Có nhiều lý do để cơ sở dữ liệu không thể thực hiện việc này một cách an toàn, bao gồm cả việc thêm / xóa Khóa ngoại sẽ thay đổi ý nghĩa của các truy vấn được viết trước bao gồm các truy vấn trong mã nguồn của ứng dụng. Hầu hết các cơ sở dữ liệu cũng không có một bộ Khóa ngoại tốt bao gồm tất cả các phép nối có thể bạn muốn làm. Ngoài ra để tốt hơn hoặc có giá trị, Khóa ngoại thường được xóa để tăng tốc hệ thống và không thể được sử dụng trên các bảng được tải theo thứ tự "sai" từ tệp.

Tuy nhiên, không có lý do tại sao một công cụ thiết kế truy vấn hoặc trình soạn thảo văn bản không thể tự động hoàn thành việc tham gia với sự trợ giúp của Khóa ngoài giống như cách họ cung cấp cho bạn thông tin về tên cột. Bạn có thể chỉnh sửa truy vấn nếu công cụ đã sai và lưu một truy vấn được xác định hoàn toàn. Một công cụ như vậy cũng có thể sử dụng một cách hữu ích quy ước đặt tên các cột Khóa ngoài theo tên và bảng của bảng cha mẹ có cùng tên trong cả bảng cha / con, v.v.

(Vợ tôi vẫn không thể hiểu được sự khác biệt giữa Management Studio và Sql Server và nói về việc khởi động máy chủ sql khi cô ấy khởi động studio quản lý!)


3

Tự nhiên tham gia "tự động" tham gia vào sự bình đẳng của các cột phổ biến, nhưng bạn chỉ nên viết rằng nếu đó là những gì bạn muốn dựa trên ý nghĩa của bảng và kết quả mong muốn của bạn. Không có "tự động" biết cách hai bảng "nên" được nối hoặc theo bất kỳ cách nào khác mà bất kỳ bảng nào "nên" xuất hiện trong một truy vấn. Chúng ta không cần phải biết các ràng buộc để truy vấn. Sự hiện diện của họ chỉ có nghĩa là đầu vào có thể bị hạn chế và do đó, đầu ra có thể cũng vậy. Bạn có thể định nghĩa một số loại toán tử jo_on_fk_to_pk "tự động" tham gia theo các ràng buộc được khai báo; nhưng nếu bạn muốn ý nghĩa của truy vấn giữ nguyên nếu chỉ các ràng buộc thay đổi nhưng không có nghĩa của bảng thì bạn phải thay đổi truy vấn đó để không sử dụng các hằng số khai báo mới.đã để lại ý nghĩa như nhau mặc dù có bất kỳ thay đổi ràng buộc nào .

Những ràng buộc nào (bao gồm PK, FK, UNIQUE & KIỂM TRA) không ảnh hưởng đến ý nghĩa của các bảng. Tất nhiên, nếu ý nghĩa của bảng thay đổi thì các điều kiện có thể thay đổi. Nhưng nếu các ràng buộc thay đổi, điều đó không có nghĩa là các truy vấn sẽ thay đổi.

Người ta không cần biết các ràng buộc để truy vấn. Biết về các ràng buộc có nghĩa là chúng ta có thể sử dụng các biểu thức xa hơn mà không có ràng buộc giữ sẽ không trả lại cùng một câu trả lời. Ví dụ, mong đợi thông qua UNIQUE rằng một bảng có một hàng, vì vậy chúng ta có thể sử dụng nó như một vô hướng. Các truy vấn này có thể phá vỡ nếu ràng buộc được giả định nhưng không được khai báo. Nhưng tuyên bố một ràng buộc mà truy vấn không cho rằng không thể phá vỡ nó.

Có quy tắc nào để xây dựng truy vấn SQL từ một mô tả có thể đọc được không?


2

Lý do là có NGÔN NGỮ, và sau đó có các hiệu trưởng cơ bản. Ngôn ngữ thưa thớt và thiếu nhiều tính năng mà bạn mong đợi sẽ thấy trong một ngôn ngữ có mục đích chung. Đây đơn giản là một tính năng hay chưa được thêm vào ngôn ngữ và có lẽ sẽ không có. Đó không phải là ngôn ngữ chết nên có chút hy vọng, nhưng tôi sẽ không lạc quan.

Như những người khác đã chỉ ra, một số triển khai sử dụng một phần mở rộng trong đó phép nối (cột) nối hai bảng dựa trên một tên cột chung, có phần giống nhau. Nhưng nó không được lan truyền rộng rãi. Lưu ý rằng tiện ích mở rộng này khác với SELECT * FROM employee NATURAL JOIN department;cú pháp không bao gồm cách chỉ định cột nào sẽ sử dụng. Không phụ thuộc vào mối quan hệ giữa các bảng, điều này làm cho chúng không đáng tin cậy (cú pháp nối tự nhiên nhiều hơn phần mở rộng).

Không có trở ngại cơ bản nào đối với "bảng tham gia bên trong trên PKFK" trong đó PKFK là một từ khóa có nghĩa là "mối quan hệ khóa ngoài được xác định giữa hai bảng", có thể có nhiều vấn đề với nhiều fk cho cùng một bảng, nhưng điều đó có thể gây ra lỗi. Câu hỏi đặt ra là những người thiết kế ngôn ngữ có cho rằng a) một ý tưởng tốt và b) làm việc tốt hơn so với một số thay đổi ngôn ngữ khác ...


3
Điều này cho rằng đó là một ý tưởng tốt mà họ nên đã thực hiện. Cũng có khả năng là họ đã xem xét điều này và quyết định không làm điều đó. Có lẽ đó là một ý tưởng rất tồi trong thực tế: Sjoerd đã đề cập đến một ví dụ, trong đó một truy vấn có thể phá vỡ chỉ bằng cách thêm một cột mới và mối quan hệ FK. Lord Tydus cũng giải thích các khóa ngoại có trách nhiệm khác với việc ra lệnh cho các bảng của bạn nên được tham gia.

1
@JonathanHobbs: Ý tôi là câu trả lời của tôi nói chung là trung lập. Nhưng từ bỏ tính trung lập. Logic của thiếu sót. Thay đổi các bảng đã phá vỡ các truy vấn, thêm một cột mới vào khóa chính của bảng sẽ phá vỡ các truy vấn hoặc bắt đầu trả về kết quả không chính xác. Trên thực tế, điều này sẽ bảo vệ bạn từ đó đến một mức độ nào đó, miễn là mối quan hệ bảng được duy trì, các thay đổi cột có thể được thực hiện một cách an toàn. Điều này có thể sẽ tăng việc sử dụng các mối quan hệ FK, vì nó sẽ hữu ích cho những thứ khác ngoài RI.Most tham gia là trên PK hoặc bao gồm cả LOL.Để xử lý nhiều fk, sử dụng tên cột.
jmoreno

1

Nếu bỏ qua mệnh đề ON được cho là tuân theo các trường dựa trên tính toàn vẹn tham chiếu, bạn sẽ làm một sản phẩm của Cartesian như thế nào?

Chỉnh sửa: sử dụng AUTO Ưu điểm của việc này là gõ ít hơn một chút và bạn không cần phải biết cách chúng được nối hoặc nhớ một phép nối phức tạp. Nếu relationhip thay đổi, nó được xử lý tự động, nhưng điều đó hiếm khi xảy ra ngoại trừ trong giai đoạn đầu phát triển.

Những gì bạn phải làm bây giờ là quyết định xem tất cả các tham gia AUTO của bạn có được giữ trong khi thay đổi mối quan hệ để phù hợp với mục đích của tuyên bố lựa chọn của bạn hay không.


@JeffO: ưu điểm chính là nó thể hiện ý định chính xác hơn, theo cách khai báo rất rõ ràng. Tham gia vào tên cột không cho bạn biết gì, ngoài thực tế là một số nội dung của các cột tương tự như trong các cột khác (nhưng có thể không cùng loại). Một tham gia vào một ref fk, nói với bạn rằng đó một ref fk, không có danh sách cột có nghĩa là chỉ có 1 fk giữa các bảng, hoặc ngược lại rằng có 1+ (xem xét một chìa khóa multicolumn với hơn 1 ref gì xảy ra khi bạn trộn các cột c1 = fk1_c1 và c2 = fk2_c2). Ngay cả khi gõ nhiều hơn trung bình, điều này sẽ tốt.
jmoreno

Sử dụng (INNER) THAM GIA mà không BẬT không phải là SQL chuẩn. Dấu phẩy, CROSS THAM GIA & (INNER hoặc bất kỳ OUTER nào) THAM GIA 0 = 0 trả lại sản phẩm Cartesian.
philipxy

-1

tại sao cơ sở dữ liệu không thể hiểu rằng nếu tôi tham gia các bảng đó, tôi muốn tham gia chúng trên các cột pk / fk?

Các phần của lý do là:

1 - về lý thuyết bạn có thể nối các bảng trên các cột tùy ý từ hai bảng. Trong khi đây không phải là thông lệ, nó có giá trị. Hãy nhớ rằng SQL giống như một ngôn ngữ lập trình, nó không hiểu thông tin nào bên trong các cột của khóa học và tên, đối với SQL, không có ý nghĩa gì nhiều trong vấn đề này.

2 - Có nhiều loại khác nhau (trái, righ, bên trong) - Joins bên trong chỉ là 1 trong số chúng.

3 - Tiêu chuẩn SQL có thể được hướng dẫn theo nguyên tắc là ngôn ngữ cấp thấp hơn cho phép phương ngữ cấp cao hơn hình thành trí thông minh sử dụng nó. Sự so sánh có phần rõ ràng hơn nếu bạn nghĩ về ngôn ngữ thế hệ thứ 4 so với ngôn ngữ thế hệ thứ 3. Trên thực tế, một công cụ tôi đã sử dụng, IEF, cho phép bạn viết một cái gì đó như thế này:

ReadEach Customer 
Where Customer Places Orders and That Customer LivesIn "California" 
and OrderValue > 100.00

Tóm lại, đề xuất của bạn rất thú vị và có thể được thực hiện như là một phần của tiêu chuẩn hoặc là một thủ tục được lưu trữ (nó sẽ được mặc định là Tham gia Nội bộ).


-10

Tiddo, tôi tin rằng bạn hoàn toàn đúng, SQL về chủ đề đó khá ngu ngốc và tôi nhớ đã nghĩ giống như bạn đã làm về các khóa ngoại trong khi học SQL khoảng mười năm trước.

Ok, cho rằng, cuối cùng tôi đã phải vượt qua kỳ thi đó; và để vượt qua nó, tôi đã phải buông tay . SQL giống như một con tàu đắm hơn bất kỳ ai có khả năng thừa nhận, đường dẫn tiêu chuẩn hóa của nó là một thảm họa hoàn chỉnh và một số triển khai được thực hiện đầy đủ . Nói chung, nó vẫn khá tiện dụng. (Tôi không phải là một luddite K / V)

Khóa ngoại, thì ... không tiện chút nào. Chúng là một khái niệm quan trọng trong mô hình quan hệ , ok, nhưng tính năng SQL có cùng tên không so sánh tốt.

Giới thiệu với bạn thẳng: không sử dụng rằng tính năng SQL gọi Foreign Keyở tất cả , cho đến khi bạn nhấn một số hệ thống lớn với vấn đề hiệu suất. Một cách rõ ràng nói với động cơ mà lĩnh vực là chìa khóa trong và ngoài mà không được chỉ được sử dụng để lập chỉ mục, và nó vô hình cho người dùng db.

Có phải là sai lệch?
Đúng.

Họ sẽ làm cho nó mạnh hơn bây giờ, sau 30 năm mọi người bị lừa dối?
Không phải là một cơ hội.

Hoàn toàn bỏ qua Khóa ngoại cho đến khi cần thiết ... SQL cố định cho tôi?
Đúng!

Và tại sao tất cả những điều này xảy ra ở nơi đầu tiên?
Chà, tính năng chúng ta gọikhóa ngoại được thêm vào sau này, thành SQL; SQL là một tiêu chuẩn phát triển theo thời gian, từ dưới lên. Các nhà cung cấp thực hiện các tính năng lố bịch, trong khi các cơ quan tiêu chuẩn được cung cấp.

Các khóa ngoại như đã nói, nơi chỉ có nghĩa là lập chỉ mục và không có cấu trúc THAM GIA có sẵn. (tham gia nơi thực hiện với SELECTcác truy vấn, JOINtruy vấn khá gần đây và chỉ có nghĩa là để alias SELECTchức năng) Họ có thể mặc dù gọi là indexing cờ FOREIGN KEY, là một minh đặt tên hack trên các khái niệm lý thuyết db quan hệ.


13
Liên quan đến khóa ngoại, tôi lấy nó bạn đã từng chạm vào công cụ MyISAM trên MySQL chưa? Ause Nguyên nhân thậm chí không quan tâm đến câu nói nhỏ nhặt đó, mọi điều trong câu trả lời này đều sai.

Fk không được sử dụng để lập chỉ mục, trên thực tế, một vấn đề phổ biến là không có chỉ mục trên cột fk có thể có tác động hiệu suất đáng kể.
jmoreno
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.