Dữ liệu của bạn chỉ tốt nếu bạn có thể tin tưởng nó. Sử dụng các ràng buộc database để đảm bảo nó chính xác, đáng tin cậy và không phá vỡ mô hình dữ liệu của bạn.
Database là cần thiết cho nhiều ứng dụng, nhưng nó có thể trở nên lộn xộn nếu bạn không có hướng dẫn lưu trữ và xử lý dữ liệu.
Các ràng buộc (constraint) SQL chỉ định quy tắc để lưu trữ dữ liệu trong bảng. Khi bạn đặt ràng buộc, database sẽ phát sinh lỗi nếu bạn cố gắng lưu trữ dữ liệu vi phạm những quy tắc đó. Ràng buộc giúp duy trì tính toàn vẹn dữ liệu và đảm bảo tính đồng nhất trong database của bạn.
Dưới đây là một số kiểu ràng buộc SQL hữu ích nhất cho bạn trong việc xây dựng cấu trúc dữ liệu tốt.
Ràng buộc NOT NULL
Mặc định, cột database chấp nhận dữ liệu chứa giá trị NULL. Về cơ bản, nó có nghĩa là không có giá trị tồn tại. Ràng buộc NOT NULL buộc một cột từ chối các giá trị NULL.
Ràng buộc này đảm bảo mỗi cột phải chứa một giá trị. Bạn không thể thêm bản ghi database mà không cung cấp dữ liệu cho bất kỳ cột chứa ràng buộc NOT NULL.
Lấy ví dụ bảng Customers. Ở đây có một số chi tiết cần thiết về từng khách hàng bạn muốn ghi lại, chẳng hạn như tên của họ. Thêm ràng buộc NOT NULL vào trường bắt buộc để đảm bảo khách hàng cung cấp thông tin này.
Đây là một ví dụ cho bạn thấy cách dùng ràng buộc NOT NULL trong một database PostgreSQL:
CREATE TABLE Customers (
ID int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255) NOT NULL,
Mobile_No int NOT NULL,
Age int
);
Nếu thử chèn bản ghi khách hàng mà không có trường Age, database sẽ chấp nhận nó mà không gặp lỗi:
INSERT INTO Customers (ID, LastName, FirstName, Mobile_No)
VALUES (123456, 'Dior', 'Christian', 0723000000);
Tuy nhiên, nếu thử chèn một bản ghi mà không có trường FirstName, database sẽ bỏ qua nó bằng một thông báo lỗi:
ERROR: null value in column "firstname" violates not-null constraint
Detail: Failing row contains (123456, Dior, null, 723000000, null).
Ràng buộc PRIMARY KEY
KEY là một thuộc tính độc đáo đặt một cột hoặc trường xác định bộ dữ liệu của bảng (hoặc một bản ghi) trong hệ thống database. Một ràng buộc PRIMARY KEY đảm bảo tính duy nhất của các giá trị trong một cột hoặc tập hợp cột. Nó hoạt động như một định danh duy nhất trong một hàng, ngăn trùng lặp bản ghi ở một bảng database.
Các khóa chính chứa những giá trị độc đáo và không thể chứa giá trị NULL. Mỗi bảng database SQL chỉ được có duy nhất một khóa chính. PRIMARY KEY có thể có một hoặc nhiều cột.
Ví dụ, bạn đang tạo một database của các bản ghi khách hàng. Bạn cần mỗi khách hàng nhập vào số ID của họ khác với những khách hàng khác. Bạn có thể áp dụng ràng buộc khóa chính để đảm bảo không có khách hàng trùng số ID.
Code sau cho bạn thấy cách có thể giới thiệu một ràng buộc khóa chính trong database MySQL:
CREATE TABLE Customers (
ID int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int,
PRIMARY KEY (ID)
);
Database này sẽ không chấp nhận giá trị đó nếu người dùng nhập vào bản ghi khác với một ID tương tự. Thay vào đó, nó sẽ sinh lỗi báo trùng lặp. Người dùng cố gắng chèn hai bản ghi cùng ID trong ví dụ sau:
INSERT INTO Customers (ID, LastName, FirstName, Age)
VALUES (1, 'John', 'Doe', 35 );
INSERT INTO Customers (ID, LastName, FirstName, Age)
VALUES (1, 'Mary', 'Jane', 35 );
Database sẽ hiện một thông báo lỗi:
Duplicate entry '1' for key 'PRIMARY'
Thế nhưng nếu bạn thay đổi ID của khách hàng thứ hai, database chấp nhận mục nhập đó. Vì thế, khóa chính đảm bảo không có ID trùng lặp trong bản ghi khách hàng.
Ràng buộc FOREIGN KEY
CREATE TABLE Customers (
customer_id INT PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50)
);
CREATE TABLE Orders (
order_id INT PRIMARY KEY,
customer_id INT,
order_date DATE,
FOREIGN KEY (customer_id) REFERENCES Customers(customer_id)
);
INSERT INTO Customers(customer_id, first_name, last_name)
VALUES (1, 'Christian', 'Dior');
INSERT INTO Orders(order_id, customer_id, order_date)
VALUES (1, 1, '2023-08-07');
Các khóa ngoại thiết lập mối quan hệ giữa hai bảng. Bạn có thể thêm một khóa ngoại vào một trường/cột trong một bảng tham chiếu khóa chính này ở bảng khác.
Bảng chứa khóa chính là bảng cha, còn bảng chứa khóa ngoại là bảng con. Khi đó, một bản ghi không thể tồn tại trong bảng con nếu không tham chiếu tới bảng cha.
Ràng buộc khóa ngoại ngăn chặn hành động phá hủy các liên kết giữa các khóa ngoại. Ví dụ, bạn không thể DROP một bảng nếu nó liên kết tới bảng khác bằng một khóa ngoại. Bạn sẽ phải bỏ cả hai bảng cùng lúc.
Khác khóa chính, bạn có thể sao chép khóa ngoại và có nhiều hơn một khóa ngoại trong một bảng. Những giá trị khóa ngoại cũng có thể là NULL. Ở ví dụ sau, bạn phải dùng customer_id để tạo một đơn hàng.
CREATE TABLE Customers (
customer_id INT PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50)
);
CREATE TABLE Orders (
order_id INT PRIMARY KEY,
customer_id INT,
order_date DATE,
FOREIGN KEY (customer_id) REFERENCES Customers(customer_id)
);
INSERT INTO Customers(customer_id, first_name, last_name)
VALUES (1, 'Christian', 'Dior');
INSERT INTO Orders(order_id, customer_id, order_date)
VALUES (1, 1, '2023-08-07');
Nếu thử tạo một đơn hàng mà không có customer_id hiện tại, database hiện một thông báo lỗi:
Cannot add or update a child row: a foreign key constraint fails
(`db_9_4ee205c`.`orders`, CONSTRAINT `orders_ibfk_1` FOREIGN KEY
(`customer_id`) REFERENCES `customers` (`customer_id`))
Ràng buộc UNIQUE
Ràng buộc này đảm bảo không tồn tại hai hàng có cùng giá trị cho một cột cụ thể. Giống như khóa chính, một ràng buộc duy nhất duy trì tính toàn vẹn dữ liệu và ngăn các mục nhập trùng lặp. Nếu phải xử lý database được thiết kế kém mà không có ràng buộc UNIQUE, bạn có thể phải tìm và xóa các bản sao.
Khác khóa chính, bạn có thể có nhiều ràng buộc UNIQUE trên một bảng. Ví dụ, khi tạo bảng Customers, bạn có thể muốn sở hữu những ID duy nhất và số điện thoại. Để thêm một ràng buộc như thế bằng server MySQL, dùng cú pháp này:
CREATE TABLE Customers (
ID int NOT NULL UNIQUE,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Mobile_No BIGINT UNIQUE
);
Nếu chèn bản ghi với cùng số điện thoại trong database, sau đó nó sẽ hiện một thông báo lỗi.
INSERT INTO Customers (ID, LastName, FirstName, Mobile_No)
VALUES (123456, 'Dior', 'Christian', 254000000 );
INSERT INTO Customers (ID, LastName, FirstName, Mobile_No)
VALUES (7891011, 'Dedan', 'Kimathi', 254000000 );
Thông báo lỗi này trông sẽ như sau:
Duplicate entry '254000000' for key 'Mobile_No'
Ràng buộc UNIQUE đảm bảo database sẽ không có khách hàng trùng ID hoặc số điện thoại.
Ràng buộc CHECK
Ràng buộc CHECK hạn chế phạm vi dữ liệu đặt trong một cột. Thêm ràng buộc CHECK trên một cột sẽ chỉ cho phép những giá trị được chỉ định cho cột đó. Nó thực thi tính toàn vẹn dữ liệu bằng cách đảm bảo người dùng chỉ chèn dữ liệu hợp lệ vào bảng.
Ràng buộc CHECK phải đánh giá giá trị là TRUE hoặc UNKNOWN cho từng hàng hoặc mục bảng cụ thể. Nếu giá trị là FALSE, database hiện một thông báo lỗi.
Ví dụ, trong bảng Customers, có thể bạn chỉ muốn phục vụ khách hàng trên 18 tuổi. Bạn có thể thêm ràng buộc CHECK để đảm bảo bạn không phục vụ khách hàng dưới độ tuổi đó. Bạn có thể thêm ràng buộc trong database PostgreSQL, như code bên dưới:
CREATE TABLE Customers (
ID int NOT NULL,
Age int CHECK(Age>=18),
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Mobile_No BIGINT UNIQUE
);
Giờ nếu thử chèn tuổi của khách hàng dưới 18:
INSERT INTO Customers (ID, Age, LastName, FirstName, Mobile_No)
VALUES (123456, 15, 'Dior', 'Christian', 1254000000 );
Database sẽ hiện thông báo lỗi như thế này:
ERROR: new row for relation "customers" violates check constraint
"customers_age_check"
Detail: Failing row contains (123456, 15, Dior, Christian, 1254000000)
Trên đây chỉ là một vài trong số những ràng buộc SQL xây dựng cấu trúc dữ liệu tốt nhất. Bạn có thể học thiết kế database như ý muốn từ những ràng buộc này.