Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Cách tạo khóa ngoại trong SQL Server (Ví dụ T-SQL)

Trong bài viết này, tôi trình bày cách tạo khóa ngoại trong SQL Server bằng Transact-SQL. Tôi trình bày cách tạo khóa ngoại tại thời điểm tạo bảng (thay vì cập nhật bảng hiện có).

Khóa ngoại là một cột tham chiếu đến cột khóa chính của bảng khác. Điều này tạo ra mối quan hệ giữa các bảng.

Ví dụ 1 - Chuẩn bị

Trong ví dụ này, tôi sẽ tạo một cơ sở dữ liệu thử nghiệm với một bảng. Bảng này sẽ chứa khóa chính mà khóa ngoại của chúng ta sẽ tham chiếu.

Tạo cơ sở dữ liệu:

CREATE DATABASE FK_Test;

Bây giờ, hãy tạo bảng khóa chính:

USE FK_Test;

CREATE TABLE Country
(
    CountryId int IDENTITY (1,1) NOT NULL PRIMARY KEY,
    CountryName nvarchar(60)
);

Ví dụ 2 - Tạo khóa ngoại

Bây giờ chúng ta đã có một bảng có khóa chính, hãy tạo một bảng khác có khóa ngoại tham chiếu đến khóa chính đó.

CREATE TABLE City
(
    CityId int IDENTITY (1,1) NOT NULL PRIMARY KEY,
    CountryId int NOT NULL REFERENCES Country(CountryId),
    CityName nvarchar(60)
);

Đây là cách đơn giản nhất để tạo khóa ngoại. Tất cả những gì chúng tôi làm là thêm REFERENCES (cùng với bảng và cột khóa chính) vào cột sẽ có ràng buộc khóa ngoại.

Nói rõ hơn, phần xác định khóa ngoại là:

REFERENCES Country(CountryId)

Điều này được bao gồm trong định nghĩa cột và chỉ nói rằng cột này sẽ tham chiếu đến CountryId trong Country bảng.

Trong trường hợp này, cả khóa ngoại và khóa chính mà nó tham chiếu, đều có chung tên (CountryId ). Tuy nhiên, đây không phải là một yêu cầu - cột khóa ngoại của bạn có thể có tên hoàn toàn khác với cột mà nó tham chiếu (mặc dù tất cả các cột tham gia vào mối quan hệ khóa ngoại phải được xác định với cùng độ dài và tỷ lệ).

Ví dụ này khiến SQL Server tự động tạo tên của khóa ngoại. Đó là vì tôi không cung cấp tên. Đọc tiếp để biết cách bạn có thể tạo tên cho khóa ngoại của mình.

Nhưng trước tiên, hãy kiểm tra ràng buộc khóa ngoại mà chúng ta vừa tạo.

Ví dụ 3 - Kiểm tra Ràng buộc Khoá ngoại

Có nhiều cách để trả lại khóa ngoại bằng T-SQL và đây là một trong số chúng:

EXEC sp_fkeys @fktable_name = City;

Kết quả (sử dụng đầu ra dọc):

PKTABLE_QUALIFIER | FK_Test
PKTABLE_OWNER     | dbo
PKTABLE_NAME      | Country
PKCOLUMN_NAME     | CountryId
FKTABLE_QUALIFIER | FK_Test
FKTABLE_OWNER     | dbo
FKTABLE_NAME      | City
FKCOLUMN_NAME     | CountryId
KEY_SEQ           | 1
UPDATE_RULE       | 1
DELETE_RULE       | 1
FK_NAME           | FK__City__CountryId__38996AB5
PK_NAME           | PK__Country__10D1609FC8BFA7F2
DEFERRABILITY     | 7

sp_fkeys hệ thống lưu trữ thủ tục trả về thông tin về khóa ngoại của chúng tôi, khóa chính liên quan của nó và các chi tiết liên quan khác. Bạn chỉ cần nhập tên của bảng khóa ngoại hoặc bảng khóa chính và nó sẽ trả về thông tin liên quan.

Trong ví dụ này, tôi chuyển tên của bảng khóa ngoại - City . Trong kết quả, chúng ta có thể xem FK_NAME để thấy rằng bảng này có ràng buộc khóa ngoại được gọi là FK__City__CountryId__38996AB5 . Đây là cái mà chúng tôi vừa tạo.

Vì vậy, bây giờ chúng tôi đã tạo khóa ngoại, bất cứ khi nào chúng tôi cố gắng chèn hoặc cập nhật một giá trị trong City.CountryId , ràng buộc khóa ngoại sẽ chỉ cho phép nó nếu giá trị tương tự đã tồn tại trong Country.CountryId cột. Điều này đảm bảo rằng tính toàn vẹn của tham chiếu được duy trì trong cơ sở dữ liệu.

Ví dụ 4 - Tùy chọn khác

Có thể thêm nhiều tùy chọn hơn vào định nghĩa khóa ngoại của bạn.

Ví dụ:bạn có thể cung cấp tên cho khóa ngoại. Bạn cũng có thể chỉ định điều gì sẽ xảy ra với các giá trị trong cột này nếu giá trị tương ứng trong khóa chính được cập nhật hoặc xóa.

Ở đây, tôi tạo lại cả hai bảng, nhưng lần này tôi chỉ định rõ ràng các tùy chọn này (tôi làm tương tự cho các khóa chính):

CREATE TABLE Country
(
    CountryId int IDENTITY (1,1) NOT NULL,
      CONSTRAINT PK_Country_CountryId PRIMARY KEY CLUSTERED (CountryId),
    CountryName nvarchar(60)
);

CREATE TABLE City
(
    CityId int IDENTITY (1,1) NOT NULL,
      CONSTRAINT PK_City_CityId PRIMARY KEY CLUSTERED (CityId),
    CountryId int NOT NULL,
      CONSTRAINT FK_City_Country FOREIGN KEY (CountryID)
        REFERENCES Country (CountryID)
        ON DELETE CASCADE
        ON UPDATE CASCADE,
    CityName nvarchar(60)
);

Trong trường hợp này, định nghĩa khóa ngoại bắt đầu bằng CONSTRAINT , theo sau là tên của khóa ngoại, tiếp theo là FOREIGN KEY , theo sau là cột mà ràng buộc khóa ngoại sẽ được áp dụng (được chèn trong dấu ngoặc đơn).

Sau đó, chúng tôi thấy cùng một REFERENCES mà chúng ta đã thấy trong ví dụ trước.

ON DELETE CASCADEON UPDATE CASCADE các mệnh đề được sử dụng để đảm bảo rằng các thay đổi được thực hiện đối với Country bảng được tự động truyền đến City bàn. Ví dụ:nếu một hàng bị xóa khỏi bảng mẹ (khóa chính), thì mọi hàng tương ứng sẽ bị xóa khỏi bảng (khóa ngoại) tham chiếu.

Giá trị mặc định cho ON DELETEON UPDATENO ACTION . Trong trường hợp này, Công cụ cơ sở dữ liệu phát sinh lỗi và hành động cập nhật hoặc xóa trên hàng trong bảng mẹ được khôi phục lại.

Bạn cũng có thể sử dụng SET NULL để đặt cột khóa ngoại thành NULL (yêu cầu cột khóa ngoại không thể trống) hoặc SET DEFAULT để đặt nó thành giá trị mặc định (yêu cầu cột khóa ngoại có định nghĩa mặc định. Nếu một cột là giá trị rỗng và không có bộ giá trị mặc định rõ ràng, NULL trở thành giá trị mặc định tiềm ẩn của cột).

Trong ví dụ này, tôi cũng đã nhân cơ hội để đặt tên cho các khóa chính. Bạn có thể thấy rằng cú pháp khóa chính tương tự như cú pháp khóa ngoại, nhưng không có REFERENCES mệnh đề (và với một CLUSTERED được thêm vào đối số, là mặc định cho khóa chính).

Bây giờ hãy kiểm tra khóa ngoại:

EXEC sp_fkeys @fktable_name = City;

Kết quả:

PKTABLE_QUALIFIER | FK_Test
PKTABLE_OWNER     | dbo
PKTABLE_NAME      | Country
PKCOLUMN_NAME     | CountryId
FKTABLE_QUALIFIER | FK_Test
FKTABLE_OWNER     | dbo
FKTABLE_NAME      | City
FKCOLUMN_NAME     | CountryId
KEY_SEQ           | 1
UPDATE_RULE       | 0
DELETE_RULE       | 0
FK_NAME           | FK_City_Country
PK_NAME           | PK_Country_CountryId
DEFERRABILITY     | 7

Chúng ta có thể thấy tên của khóa ngoại hiện là FK_City_Country và ràng buộc khóa chính của cột mà nó tham chiếu được gọi là PK_Country_CountryId .

Ví dụ 5 - Khóa ngoại trên nhiều cột

Bạn cũng có thể tạo khóa ngoại trên nhiều cột tham chiếu đến khóa chính nhiều cột. Khóa chính nhiều cột còn được gọi là khóa chính tổng hợp. Để tạo khóa ngoại tổng hợp, chỉ cần tách các cột bằng dấu phẩy khi xác định khóa.

Như thế này:

CONSTRAINT FK_FKName FOREIGN KEY
 (FKColumn1, FKColumn2)
REFERENCES PrimaryKeyTable (PKColumn1, PKColumn2)

Xem Cách tạo khóa ngoại tổng hợp trong SQL Server để có ví dụ chi tiết hơn.

Khóa chính có thực sự cần thiết không?

Khóa chính không hoàn toàn cần thiết cho khóa ngoại, vì bạn có thể sử dụng một ràng buộc duy nhất hoặc chỉ mục duy nhất. Cụ thể, tài liệu của Microsoft nêu rõ điều này:

FOREIGN KEY các ràng buộc chỉ có thể tham chiếu đến các cột trong PRIMARY KEY hoặc UNIQUE các ràng buộc trong bảng được tham chiếu hoặc trong một UNIQUE INDEX trên bảng được tham chiếu.

Vì vậy, mặc dù phương pháp hay là có khóa chính trên tất cả các bảng, nhưng khóa ngoại của bạn không có nghĩa vụ phải tham chiếu đến chúng.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. kiểu dữ liệu tương đương mysql

  2. Giám sát truy vấn chạy SQL Server

  3. Chuyển đổi Mili giây UTC thành DATETIME trong máy chủ SQL

  4. Hội thảo trên web:Theo dõi tiến trình truy vấn trong SQL Server

  5. Xem lịch sử công việc của SQL Server Agent với SSMS