Tại sao một bảng sẽ sử dụng khóa chính của nó làm khóa ngoại


21

Nhìn qua một cơ sở dữ liệu, tôi bắt gặp một bảng sử dụng khóa chính của nó làm khóa ngoại cho chính nó.

Tôi đã thấy rằng một bảng có thể có khóa ngoại để tự xây dựng cấu trúc phân cấp, nhưng nó sẽ sử dụng một cột khác để tham chiếu khóa chính.

Vì khóa chính là duy nhất, trong tình huống này, hàng sẽ không thể quay trở lại chính nó chứ? Đó dường như là một liên kết tautological, vì nếu tôi đã có hàng, thì tôi đã có hàng.

Có bất kỳ lý do này sẽ được thực hiện?

Bảng tham gia vào chính nó

Tôi chắc chắn ràng buộc được viết theo cách đó (không chỉ nhìn vào sơ đồ) bởi vì cùng một bảng và cột được sử dụng cho cả hai nửa của định nghĩa.


6
Có lẽ thông qua việc sử dụng tay thiết kế của nhà thiết kế là lý thuyết của tôi
Martin Smith

Câu trả lời:


28

Như bạn đã nói. Một FOREIGN KEYràng buộc tham chiếu cùng một bảng thường dành cho cấu trúc phân cấp và nó sẽ sử dụng một cột khác để tham chiếu khóa chính. Một ví dụ điển hình là bảng nhân viên:

EmployeeId    Int     Primary Key
EmployeeName  String
ManagerId     Int     Foreign key going back to the EmployeeId

Vì vậy, trong trường hợp này có một khóa ngoại từ bảng trở lại chính nó. Tất cả các nhà quản lý cũng là nhân viên nên ManagerIdthực sự là EmployeeIdcủa người quản lý.

Mặt khác, nếu bạn có nghĩa là ai đó đã sử dụng EmployeeIdlàm khóa ngoại trở lại bảng Nhân viên thì đó có thể là một sai lầm . Tôi đã chạy thử nghiệm và điều đó là có thể nhưng nó sẽ không có công dụng thực sự.

CREATE TABLE Employee (EmployeeId Int PRIMARY KEY,
                        EmployeeName varchar(50),
                        ManagerId Int);


ALTER TABLE Employee ADD CONSTRAINT fk_employee 
    FOREIGN KEY (EmployeeId) REFERENCES Employee(EmployeeId);

1
Đặt một ràng buộc đối với ManagerId liên quan đến EmployeeId trong trường hợp này có thể có lợi nếu Manger bị "tách rời". Nó sẽ không cho phép xóa hàng nếu được đặt theo cách đó. Không nói rằng tôi sẽ làm theo cách đó nhưng nó có thể có một số lợi ích nếu ứng dụng của bạn dựa vào nhân viên có người quản lý.
zgr024

6

Tôi chỉ tìm thấy một khóa ngoại như vậy trong db của riêng tôi và nó phải là chính tôi tạo ra nó. Tôi nghĩ điều này chỉ xảy ra một cách tình cờ. Nếu tôi nhấp vào "Khóa ngoại mới" trong menu ngữ cảnh của bảng có khóa chính (trong Management Studio, SQL 2014 Express) thì điều này đã tự động tạo ra một khóa ngoại như vậy đề cập đến chính nó. Xem bên dưới:

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

Nếu sau đó tôi không nhận ra rằng tôi nên thay đổi cái đó thay vì thêm cái mới, nó sẽ ở lại đó. Hoặc, nếu tôi chỉ cần nhấp vào nút [Đóng] có nghĩa là nó sẽ giống như [Hủy], khóa ngoại vẫn sẽ được tạo sau khi lưu định nghĩa bảng.

Vì vậy, với tôi một khóa ngoại như vậy không có ý nghĩa và có thể được gỡ bỏ.


Có thể bạn muốn tạo FK và trong quá trình bạn nhận ra bảng khác chưa đặt PK nên bạn hủy, chuyển sang bảng khác và sau đó vì một số lý do bạn quên tiếp tục quy trình FK. Ở đó bạn có FK đệ quy của bạn.
Andrew

4

Có lẽ các nhà thiết kế muốn vô hiệu hóa việc sử dụng TRUNCATE TABLE?

TRUNCATE TABLEkhông thể được sử dụng trên một bảng có ràng buộc khóa ngoại đối với một bảng khác mặc dù nó có thể được sử dụng nếu có các khóa ngoại tự tham chiếu . Từ tài liệu cho TRUNCATE TABLE (Transact-SQL) :

Chiết xuất BOL

Một DELETEcâu lệnh không có WHEREmệnh đề có tác dụng tương tự như TRUNCATE TABLE(loại bỏ tất cả các hàng trong bảng) nhưng DELETEcâu lệnh kích hoạt xóa các kích hoạt, đây có thể là một lý do để cho phép DELETEnhưng không TRUNCATE TABLE.

Tôi sẽ làm điều này bằng cách sử dụng quyền ( DELETEyêu cầu quyền xóa, TRUNCATE TABLEyêu cầu quyền thay đổi bảng), nhưng có thể có một số lý do mà người thiết kế không thể làm điều này?

Lưu ý: Mặc dù những gì nhà thiết kế đã thực hiện không thực sự vô hiệu hóa việc sử dụng TRUNCATE TABLE, tôi vẫn suy đoán rằng đây là ý định của họ.

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.