Bài học theo mô-đun (2/4)
Các ràng buộc cấp độ bảng và nhiều
Việc đảm bảo rằng dữ liệu trong cơ sở dữ liệu là chính xác ở lớp cơ bản nhất ("toàn vẹn dữ liệu") là điều cơ bản. Nếu bạn chỉ ghi sự an toàn vào ứng dụng Node.js, các lỗi có thể khiến dữ liệu trong DB không nhất quán. Các hạn chế ở cấp độ DDL là tuyến phòng thủ cuối cùng, không thể xuyên thủng.
Những hạn chế chính
Ngoài PRIMARY KEY (làm cho một cột duy nhất và KHÔNG NULL) và NOT NULL và UNIQUE cổ điển, có hai danh mục cơ bản đảm bảo tính nhất quán logic của dữ liệu:
1. FORIGN KEY (Tính toàn vẹn tham chiếu)
Ràng buộc REFERENCES đảm bảo rằng ID liên kết thực sự tồn tại trong bảng "cha" mà nó trỏ tới.
Ví dụ: một đơn đặt hàng phải được liên kết với một khách hàng hiện có.
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
customer_id INTEGER REFERENCES customers(id)
);Khóa ngoại có tác dụng gì?
- Nó ngăn bạn chèn
customer_idkhông tồn tại trongcustomers. - Nó ngăn bạn
DELETE(xóa) một khách hàng khỏicustomersnếu có các đơn đặt hàng trỏ đến họ (nó bảo vệ khỏi các bản ghi "mồ côi").
Chúng ta cũng có thể quyết định điều gì sẽ xảy ra khi "mẹ" bị xóa:
customer_id INTEGER REFERENCES customers(id) ON DELETE CASCADEVới ON DELETE CASCADE, nếu chúng tôi xóa khách hàng, Postgres sẽ tự động xóa tất cả orders được liên kết! (Sử dụng hết sức thận trọng; thông thường, cài đặt mặc định chặn hoạt động sẽ được ưu tiên hơn.)
2. KIỂM TRA các ràng buộc
Ràng buộc CHECK xác thực hàng bằng cách kiểm tra biểu thức boolean trước khi tiếp tục lưu.
CREATE TABLE contratti (
id SERIAL PRIMARY KEY,
stipendio NUMERIC(10,2) CHECK (stipendio > 0),
data_inizio DATE,
data_fine DATE,
CHECK (data_fine > data_inizio)
);CHECK đầu tiên là ràng buộc cột (nó chỉ đề cập đến stipendio).
CHECK thứ hai ở dưới cùng là ràng buộc bảng (nó có thể vượt qua các giá trị từ nhiều cột và phải được khai báo ở dưới cùng).
Nếu INSERT hoặc UPDATE cố gắng lưu phần cuối trước khi bắt đầu, Postgres sẽ từ chối và báo lỗi!
Ràng buộc đặt tên
Thông thường, bạn nên đặt tên rõ ràng cho các ràng buộc (sử dụng từ khóa CONSTRAINT). Bằng cách này, khi Postgres chặn một bản ghi, lỗi sẽ cho bạn biết ví dụ như "ràng buộc 'stipendio_positivo' bị vi phạm", điều này rõ ràng hơn nhiều cho việc gỡ lỗi!
CREATE TABLE prodotti (
id SERIAL PRIMARY KEY,
nome VARCHAR(50),
CONSTRAINT nome_univoco UNIQUE(nome)
);Hãy thử nó
Tạo bảng 'prenotazioni' có id (SERIAL PRIMARY KEY) và 'customer_id' (INTEGER). Sử dụng CONSTRAINT fk_cliente FOREIGN KEY (customer_id) REFERENCES customer(id) để đặt tên rõ ràng cho ràng buộc Khóa ngoại. Làm điều đó ở phía dưới, như một ràng buộc bảng.
Hiển thị gợi ý
Viết CONSTRAINT fk_cliente FOREIGN KEY (local_column) TÀI LIỆU THAM KHẢO external_table(external_col)
Giải pháp khả dụng sau 3 lần thử
Các ràng buộc với logic tùy chỉnh
Tạo bảng 'eventi' với id (SERIAL PRIMARY KEY), posti_totali (INTEGER) và biglietti_venduti (INTEGER). Thêm một ràng buộc bảng có tên là 'check_capienza' trong đó biglietti_venduti không bao giờ được lớn hơn posti_totali.
Hiển thị gợi ý
Thêm ràng buộc ở dưới cùng bằng cách sử dụng CONSTRAINT check_capienza CHECK ( biểu thức )
Giải pháp khả dụng sau 3 lần thử