Việc sử dụng nhiều khóa ngoại trên cùng một cột trong SQL Server


10

SQL Server cho phép tôi tạo nhiều khóa ngoại trên một cột và mỗi lần chỉ sử dụng tên khác nhau, tôi có thể tạo một khóa khác tham chiếu đến cùng một đối tượng. Về cơ bản tất cả các khóa đang xác định cùng một mối quan hệ. Tôi muốn biết việc sử dụng nhiều khóa ngoại được xác định trên cùng một cột và tham chiếu đến cùng một cột trong bảng khác là gì. SQL Server cho phép chúng ta làm một việc như thế nào?

nhập mô tả hình ảnh ở đây

Câu trả lời:


12

Không có lợi ích khi có các ràng buộc dư thừa chỉ khác nhau theo tên. Tương tự, không có lợi ích gì khi có các chỉ mục dự phòng chỉ khác nhau theo tên. Cả hai thêm chi phí mà không có giá trị.

Công cụ cơ sở dữ liệu SQL Server không ngăn bạn làm như vậy. Các quy ước đặt tên ràng buộc ràng buộc tốt (ví dụ FK_ReferencesTable_ReferencedTable) có thể giúp bảo vệ một quy tắc chống lại các lỗi đó.


17

SQL Server cho phép bạn làm rất nhiều điều ngớ ngẩn.

Bạn thậm chí có thể tạo một khóa ngoại trên một cột tham chiếu chính nó - mặc dù thực tế là điều này không bao giờ có thể bị vi phạm vì mỗi hàng sẽ tự đáp ứng các ràng buộc.

Trường hợp một cạnh trong đó khả năng tạo hai khóa ngoại trên cùng một mối quan hệ sẽ có khả năng hữu ích là vì chỉ mục được sử dụng để xác thực khóa ngoại được xác định tại thời điểm tạo. Nếu một chỉ số tốt hơn (nghĩa là hẹp hơn) xuất hiện muộn hơn thì điều này sẽ cho phép một ràng buộc khóa ngoại mới được tạo ràng buộc vào chỉ mục tốt hơn và sau đó ràng buộc ban đầu giảm xuống mà không có bất kỳ khoảng cách nào không có ràng buộc hoạt động.

(Như trong ví dụ dưới đây)

CREATE TABLE T1(
    T1_Id INT PRIMARY KEY CLUSTERED  NOT NULL,
    Filler CHAR(4000) NULL,
) 

INSERT INTO T1 VALUES (1, '');

CREATE TABLE T2(
    T2_Id INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    T1_Id INT NOT NULL CONSTRAINT FK REFERENCES T1 (T1_Id), 
    Filler CHAR(4000) NULL,
)


ALTER TABLE T1 ADD CONSTRAINT
    UQ_T1 UNIQUE NONCLUSTERED(T1_Id) 


/*Execution Plan uses clustered index*/ 
INSERT INTO T2 VALUES (1,1) 

ALTER TABLE T2  WITH CHECK ADD  CONSTRAINT FK2 FOREIGN KEY(T1_Id)
REFERENCES T1 (T1_Id)    

ALTER TABLE T2 DROP CONSTRAINT FK

/*Now Execution Plan now uses non clustered index*/    
INSERT INTO T2 VALUES (1,1)    

DROP TABLE  T2, T1;

Như một phần dành cho giai đoạn tạm thời trong khi cả hai ràng buộc tồn tại, bất kỳ phần chèn nào cuối cùng cũng được xác nhận đối với cả hai chỉ mục.


Một giao dịch có thể được sử dụng để đảm bảo cập nhật ràng buộc không khoảng cách tương tự? Là phương pháp phi giao dịch này tốt hơn do ít khóa hơn, có lẽ?
biley

13

Không có cách sử dụng để có các ràng buộc khóa ngoại giống hệt nhau., Đó là trên cùng một cột và tham chiếu cùng bảng và cột.

Nó giống như có cùng một kiểm tra 2 lần trở lên.


-Không đồng ý. Có thể có khả năng bảng chính cần hai kiểm tra riêng biệt. Xem bên dưới ví dụ người gửi và người nhận hoàn toàn khác nhau - stackoverflow.com/questions/40400483/ trên
trex

@trex bạn đang nói về đôi khi khác nhau. Câu hỏi ở đây nêu rõ: "Tôi muốn biết việc sử dụng nhiều khóa ngoại được xác định trên cùng một cột và tham chiếu đến cùng một cột trong một bảng khác là gì ".
ypercubeᵀᴹ

@ ypercubeᵀᴹ - Hiểu rồi Cảm ơn đã làm cho nó rõ ràng
trex

6

Cùng một lý do bạn có thể tạo 50 chỉ mục trên cùng một cột, thêm tệp nhật ký thứ hai, đặt bộ nhớ máy chủ tối đa thành 20MB ... hầu hết mọi người sẽ không làm những việc này, nhưng đôi khi có thể có lý do chính đáng để thực hiện chúng, vì vậy không có lợi ích trong việc tạo ra chi phí trong động cơ để thêm kiểm tra đối với những thứ chỉ đơn thuần là khuyên dùng.


2

Âm thanh như một thứ màu xanh lam.

Khi bạn bắt đầu chuyển từ màu xanh sang màu xanh lá cây, bạn cần tạm thời tạo thêm các bản sao của sự vật.

Những gì chúng tôi muốn làm là tạm thời tạo thêm một khóa ngoại CHECK WITH NOCHECKON UPDATE CASCADE ON DELETE SET NULL; Cái này là khóa ngoại đang hoạt động nhưng các hàng hiện có không được kiểm tra khi khóa được tạo.

Sau khi dọn sạch tất cả các hàng phù hợp, chúng tôi sẽ tạo khóa ngoại mới mà không có bất kỳ tùy chọn lệnh nào (mặc định CHECK WITH CHECKlà thứ bạn thường muốn) và bỏ khóa ngoại tạm thời.

Lưu ý rằng nếu bạn vừa đánh rơi và tạo lại khóa ngoại, một số hàng rác có thể bị trượt.

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.