Các loại ràng buộc trong SQL Server
Trong hướng dẫn này, bạn sẽ tìm hiểu và học cách sử dụng các ràng buộc như PRIMARY KEY, FOREIGN KEY, UNIQUE, CHECK, NOT NULL trong SQL Server.
Ràng buộc PRIMARY KEY trong SQL Server
PRIMARY KEY (Khóa chính) là một cột hoặc một nhóm cột xác định giá trị duy nhất mỗi hàng trong bảng. Bạn tạo khóa chính cho bảng bằng cách sử dụng ràng buộc PRIMARY KEY
.
Cú pháp ràng buộc PRIMARY KEY trong SQL Server
Nếu khóa chính chỉ bao gồm một cột, bạn có thể xác định ràng buộc PRIMARY KEY
sử dụng làm ràng buộc cột như sau:
CREATE TABLE table_name (
pk_column data_type PRIMARY KEY,
...
);
Trong trường hợp khóa chính có hai hoặc nhiều cột, bạn phải sử dụng ràng buộc PRIMARY KEY
làm ràng buộc bảng như sau:
CREATE TABLE table_name (
pk_column_1 data_type,
pk_column_2 data type,
...
PRIMARY KEY (pk_column_1, pk_column_2)
);
Mỗi bảng chỉ có thể chứa một khóa chính. Tất cả các cột tham gia vào khóa chính phải được định nghĩa là NOT NULL
. SQL Server tự động đặt ràng buộc NOT NULL
cho tất cả các cột khóa chính nếu ràng buộc NOT NULL
không được chỉ định cho các cột này.
SQL Server cũng tự động tạo một unique clustered index (hoặc một non-clustered index nếu được chỉ định như vậy) khi bạn tạo khóa chính.
Ví dụ về ràng buộc PRIMARY KEY trong SQL Server
Ví dụ sau tạo một bảng có khóa chính bao gồm một cột:
CREATE TABLE sales.activities (
activity_id INT PRIMARY KEY IDENTITY,
activity_name VARCHAR (255) NOT NULL,
activity_date DATE NOT NULL
);
Trong bảng sales.activities
này, cột activity_id
là cột khóa chính. Nó có nghĩa là cột activity_id
chứa các giá trị duy nhất.
Thuộc tính IDENTITY
được sử dụng cho các cột activity_id
để tự động tạo ra giá trị số nguyên duy nhất.
Câu lệnh sau tạo một bảng mới có tên sales.participants
có khóa chính của nó bao gồm hai cột:
CREATE TABLE sales.participants(
activity_id int,
customer_id int,
PRIMARY KEY(activity_id, customer_id)
);
Trong ví dụ này, các giá trị trong một trong hai cột activity_id
hoặc customer_id
có thể trùng lặp, nhưng mỗi kết hợp giá trị từ cả hai cột phải là duy nhất.
Thông thường, một bảng luôn có một khóa chính được xác định tại thời điểm tạo. Tuy nhiên, đôi khi, một bảng hiện có có thể không có khóa chính. Trong trường hợp này, bạn có thể thêm khóa chính vào bảng bằng cách sử dụng câu lệnh ALTER TABLE
. Hãy xem xét ví dụ sau:
Câu lệnh sau tạo một bảng không có khóa chính:
CREATE TABLE sales.events(
event_id INT NOT NULL,
event_name VARCHAR(255),
start_date DATE NOT NULL,
duration DEC(5,2)
);
Để đặt cột event_id
làm khóa chính, bạn sử dụng câu lệnh ALTER TABLE
như sau:
ALTER TABLE sales.events
ADD PRIMARY KEY(event_id);
Lưu ý rằng nếu bảng
sales.events
đã có dữ liệu, trước khi thăng hạng cộtevent_id
làm khóa chính, bạn phải đảm bảo rằng các giá trị của cộtevent_id
trong bảng là duy nhất.
Ràng buộc FOREIGN KEY trong SQL Server
Hãy xem các bảng vendor_groups
và vendors
sau đây:
CREATE TABLE procurement.vendor_groups (
group_id INT IDENTITY PRIMARY KEY,
group_name VARCHAR (100) NOT NULL
);
CREATE TABLE procurement.vendors (
vendor_id INT IDENTITY PRIMARY KEY,
vendor_name VARCHAR(100) NOT NULL,
group_id INT NOT NULL,
);
Mỗi nhà cung cấp thuộc một nhóm nhà cung cấp và mỗi nhóm nhà cung cấp có thể có không hoặc nhiều nhà cung cấp. Mối quan hệ giữa các bảng vendor_groups
và vendors
là một-nhiều.
Đối với mỗi hàng trong bảng vendors
, bạn luôn có thể tìm thấy một hàng tương ứng trong bảng vendor_groups
.
Tuy nhiên, với thiết lập bảng hiện tại, bạn có thể insert một hàng vào bảng vendors
mà không có hàng tương ứng trong bảng vendor_groups
. Tương tự, bạn cũng có thể xóa một hàng trong bảng vendor_groups
mà không cần cập nhật hoặc xóa các hàng tương ứng trong bảng vendors
dẫn đến các hàng trong bảng vendors
bị mất.
Để thực thi liên kết giữa dữ liệu trong bảng vendor_groups
và vendors
, bạn cần thiết lập khóa ngoại trong bảng vendors
.
Khóa ngoại (foreign key) là một cột hoặc một nhóm cột trong một bảng xác định duy nhất một hàng của bảng khác (hoặc cùng một bảng trong trường hợp tự tham chiếu).
Để tạo khóa ngoại, bạn sử dụng ràng buộc FOREIGN KEY
.
Các câu lệnh sau xóa bảng vendors
và tạo lại nó với một ràng buộc FOREIGN KEY
:
DROP TABLE vendors;
CREATE TABLE procurement.vendors (
vendor_id INT IDENTITY PRIMARY KEY,
vendor_name VARCHAR(100) NOT NULL,
group_id INT NOT NULL,
CONSTRAINT fk_group FOREIGN KEY (group_id)
REFERENCES procurement.vendor_groups(group_id)
);
Bảng vendor_groups
hiện nay được gọi là bảng cha đó là bảng để mà tham khảo ràng buộc khoá ngoại. Bảng vendors
được gọi là bảng con đó là bảng mà ràng buộc khoá ngoại được áp dụng.
Trong câu lệnh trên, mệnh đề sau đây tạo ra một ràng buộc FOREIGN KEY
có tên là fk_group
liên kết cột group_id
trong bảng vendors
với cột group_id
trong bảng vendor_groups
:
CONSTRAINT fk_group FOREIGN KEY (group_id) REFERENCES procurement.vendor_groups(group_id)
Cú pháp ràng buộc FOREIGN KEY trong SQL Server
Cú pháp chung để tạo một ràng buộc FOREIGN KEY
như sau:
CONSTRAINT fk_constraint_name
FOREIGN KEY (column_1, column2,...)
REFERENCES parent_table_name(column1,column2,..)
Hãy xem xét cú pháp này một cách chi tiết.
Đầu tiên, chỉ định tên ràng buộc FOREIGN KEY
sau từ khóa CONSTRAINT
. Tên ràng buộc là tùy chọn do đó có thể tạo một ràng buộc FOREIGN KEY
như sau:
FOREIGN KEY (column_1, column2,...)
REFERENCES parent_table_name(column1,column2,..)
Trong trường hợp này, SQL Server sẽ tự động tạo tên cho ràng buộc FOREIGN KEY
.
Thứ hai, chỉ định danh sách các cột khóa ngoại được phân tách bằng dấu phẩy được đặt trong dấu ngoặc đơn sau từ khóa FOREIGN KEY
.
Thứ ba, chỉ định tên của bảng cha mà khóa ngoại tham chiếu đến và danh sách các cột được phân tách bằng dấu phẩy có liên kết với cột trong bảng con.
Ví dụ về ràng buộc FOREIGN KEY trong SQL Server
Đầu tiên, hãy insert một số nhóm nhà cung cấp vào bảng vendor_groups
:
INSERT INTO procurement.vendor_groups(group_name)
VALUES('Third-Party Vendors'),
('Interco Vendors'),
('One-time Vendors');
Tiếp theo, insert một nhà cung cấp mới kèm theo Id của một nhóm nhà cung cấp vào bảng vendors
:
INSERT INTO procurement.vendors(vendor_name, group_id)
VALUES('ABC Corp',1);
Câu lệnh đã hoạt động như mong đợi.
Tiếp theo, cố gắng insert một nhà cung cấp mới có Id của một nhóm nhà cung cấp không tồn tại trong bảng vendor_groups
:
INSERT INTO procurement.vendors(vendor_name, group_id)
VALUES('XYZ Corp',4);
SQL Server sẽ đưa ra lỗi sau:
The INSERT statement conflicted with the FOREIGN KEY constraint "fk_group". The conflict occurred in database "BikeStores", table "procurement.vendor_groups", column 'group_id'.
Trong ví dụ này, do ràng buộc FOREIGN KEY
, SQL Server đã từ chối câu lệnh insert và đưa ra lỗi.
Xem thêm về ràng buộc FOREIGN KEY
trong SQL Server tại đây:
Ràng buộc CHECK trong SQL Server
Ràng buộc CHECK
trong SQL Server cho phép bạn chỉ định các giá trị trong một cột phải đáp ứng một biểu thức Boolean.
Cú pháp khai báo ràng buộc CHECK trong SQL Server
Ví dụ: để yêu cầu đơn giá lớn hơn 0, bạn có thể sử dụng:
CREATE SCHEMA test;
GO
CREATE TABLE test.products(
product_id INT IDENTITY PRIMARY KEY,
product_name VARCHAR(255) NOT NULL,
unit_price DEC(10,2) CHECK(unit_price > 0)
);
Như bạn có thể thấy, CHECK
định nghĩa ràng buộc nằm sau kiểu dữ liệu. Nó bao gồm từ khóa CHECK
theo sau là một biểu thức logic trong dấu ngoặc đơn:
CHECK(unit_price > 0)
Bạn cũng có thể gán cho ràng buộc một tên riêng bằng cách sử dụng từ khóa CONSTRAINT
như sau:
CREATE TABLE test.products(
product_id INT IDENTITY PRIMARY KEY,
product_name VARCHAR(255) NOT NULL,
unit_price DEC(10,2) CONSTRAINT positive_price CHECK(unit_price > 0)
);
Chỉ định tên ràng buộc rõ ràng giúp phân loại các thông báo lỗi và cho phép bạn tham chiếu đến các ràng buộc khi bạn muốn sửa đổi chúng.
Nếu bạn không chỉ định tên ràng buộc theo cách này, SQL Server sẽ tự động tạo tên cho bạn.
Xem câu lệnh insert sau:
INSERT INTO test.products(product_name, unit_price)
VALUES ('Awesome Free Bike', 0);
SQL Server sẽ thông báo lỗi sau:
The INSERT statement conflicted with the CHECK constraint "positive_price". The conflict occurred in database "BikeStores", table "test.products", column 'unit_price'.
Lỗi xảy ra do đơn giá không lớn hơn 0 như được chỉ định trong ràng buộc CHECK
.
Câu lệnh sau hoạt động tốt vì biểu thức logic được xác định trong ràng buộc CHECK
đánh giá là TRUE
:
INSERT INTO test.products(product_name, unit_price)
VALUES ('Awesome Bike', 599);
Xem thêm về ràng buộc CHECK trong SQL Server tại đây:
Ràng buộc UNIQUE trong SQL Server
Ràng buộc UNIQUE
của SQL Server cho phép bạn đảm bảo rằng dữ liệu được lưu trữ trong một cột hoặc một nhóm cột, là duy nhất giữa các hàng trong bảng.
Cú pháp khai báo ràng buộc UNIQUE trong SQL Server
Câu lệnh sau tạo một bảng có dữ liệu trong cột email
là duy nhất giữa các hàng trong bảng hr.persons
:
CREATE SCHEMA hr;
GO
CREATE TABLE hr.persons(
person_id INT IDENTITY PRIMARY KEY,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE
);
Trong cú pháp này, bạn xác định ràng buộc UNIQUE
là một ràng buộc cột. Bạn cũng có thể xác định ràng buộc UNIQUE
dưới dạng ràng buộc bảng, như sau:
CREATE TABLE hr.persons(
person_id INT IDENTITY PRIMARY KEY,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
email VARCHAR(255),
UNIQUE(email)
);
SQL Server tự động tạo một index UNIQUE
để thực thi tính duy nhất của dữ liệu được lưu trữ trong các cột tham gia vào ràng buộc UNIQUE
. Do đó, nếu bạn cố gắng insert một hàng trùng lặp, SQL Server sẽ từ chối và trả về thông báo lỗi cho biết ràng buộc UNIQUE
đã bị vi phạm.
Câu lệnh sau sẽ insert một hàng mới vào bảng hr.persons
:
INSERT INTO hr.persons(first_name, last_name, email)
VALUES('John','Doe','j.doe@bike.stores');
Câu lệnh hoạt động như mong đợi. Tuy nhiên, câu lệnh sau không thành công do email bị trùng lặp:
INSERT INTO hr.persons(first_name, last_name, email)
VALUES('Jane','Doe','j.doe@bike.stores');
SQL Server đã đưa ra thông báo lỗi sau:
Violation of UNIQUE KEY constraint 'UQ__persons__AB6E616417240E4E'. Cannot insert duplicate key in object 'hr.persons'. The duplicate key value is (j.doe@bike.stores).
Nếu bạn không chỉ định tên cho ràng buộc UNIQUE
, SQL Server sẽ tự động tạo tên cho nó. Trong ví dụ này, tên ràng buộc là UQ__persons__AB6E616417240E4E
, không thể đọc được.
Để gán một tên cụ thể cho một ràng buộc UNIQUE
, bạn sử dụng từ khóa CONSTRAINT
như sau:
CREATE TABLE hr.persons (
person_id INT IDENTITY PRIMARY KEY,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
email VARCHAR(255),
CONSTRAINT unique_email UNIQUE(email)
);
Sau đây là những lợi ích của việc gán tên cụ thể cho một ràng buộc UNIQUE
:
- Nó dễ dàng hơn để phân loại thông báo lỗi.
- Bạn có thể tham chiếu tên ràng buộc khi bạn muốn sửa đổi nó.
Xem thêm về ràng buộc UNIQUE trong SQL Server tại đây:
Ràng buộc NOT NULL trong SQL Server
Ràng buộc NOT NULL
của SQL Server chỉ định rằng một cột không được chứa dữ liệu NULL
.
Ví dụ sau tạo ra một bảng với ràng buộc NOT NULL
cho các cột: first_name
, last_name
và email
:
CREATE SCHEMA hr;
GO
CREATE TABLE hr.persons(
person_id INT IDENTITY PRIMARY KEY,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
phone VARCHAR(20)
);
Lưu ý: ràng buộc
NOT NULL
luôn được viết dưới dạng các ràng buộc cột.
Theo mặc định, nếu bạn không chỉ định ràng buộc NOT NULL
, SQL Server sẽ cho phép cột chấp nhận giá trị NULL
. Trong ví dụ này, cột phone
có thể chấp nhận giá trị NULL
.
Thêm ràng buộc NOT NULL vào một cột hiện có trong SQL Server
Để thêm ràng buộc NOT NULL
vào cột hiện có, bạn làm theo các bước sau:
Đầu tiên, hãy cập nhật bảng để không có giá trị NULL
trong cột:
UPDATE table_name
SET column_name = <value>
WHERE column_name IS NULL;
Tiếp theo, thay đổi bảng để tạo ràng buộc NOT NULL
cho cột:
ALTER TABLE table_name
ALTER COLUMN column_name data_type NOT NULL;
Ví dụ: để thêm ràng buộc NOT NULL
vào cột phone
của bảng hr.persons
, bạn sử dụng các câu lệnh sau:
Trước tiên, nếu một người không có số điện thoại, thì hãy cập nhật số điện thoại thành số điện thoại của công ty chẳng hạn, ví dụ: (408) 123 4567:
UPDATE hr.persons
SET phone = "(408) 123 4567"
WHER phone IS NULL;
Tiếp theo, sửa đổi thuộc tính của cột phone
:
ALTER TABLE hr.persons
ALTER COLUMN phone VARCHAR(20) NOT NULL;
Xóa ràng buộc NOT NULL trong SQL Server
Để loại bỏ ràng buộc NOT NULL
khỏi một cột, bạn sử dụng câu lệnh ALTER TABLE ALTER COLUMN
như sau:
ALTER TABLE table_name
ALTER COLUMN column_name data_type NULL;
Ví dụ, để loại bỏ ràng buộc NOT NULL
khỏi cột phone
, bạn sử dụng câu lệnh sau:
ALTER TABLE hr.pesons
ALTER COLUMN phone VARCHAR(20) NULL;
Trong hướng dẫn này, bạn đã học cách sử dụng ràng buộc NOT NULL
trong SQL Server để đảm bảo một cột không chứa dữ liệu NULL
.
Trong hướng dẫn này, bạn đã tìm hiểu và học được cách sử dụng các ràng buộc như PRIMARY KEY, FOREIGN KEY, UNIQUE, CHECK, NOT NULL trong SQL Server.