Hôm nay tụi mình sẽ đi sâu vào một khía cạnh quan trọng nữa khi làm việc với database — cách chèn dữ liệu vào bảng có ràng buộc NOT NULL và DEFAULT. Đến bước này chắc bạn đã quen với cú pháp cơ bản của lệnh INSERT INTO rồi, cũng như hiểu cách thêm dòng vào bảng có cấu trúc nhất định. Giờ là lúc đào sâu hơn — vì làm việc với ràng buộc thường là nguồn đau đầu cho dev. Nhưng đừng lo, hết bài này bạn sẽ tự tin xử lý mấy vụ này luôn!
Ràng buộc là gì?
Ràng buộc — là các quy tắc áp lên cột của bảng. Nó giúp giữ cho dữ liệu hợp lý về mặt logic. Ví dụ, không thể để trống trường bắt buộc phải có dữ liệu (NOT NULL), hoặc có thể không cần điền giá trị cho cột nếu đã có giá trị mặc định sẵn (DEFAULT).
Các loại ràng buộc: - NOT NULL — chỉ ra rằng cột này không được chứa NULL. - DEFAULT — đặt giá trị sẽ tự động được chèn vào cột nếu không chỉ định giá trị.
Ràng buộc giúp giữ cho dữ liệu luôn chuẩn. Ví dụ, bạn lưu danh sách sinh viên trong bảng students, và một trong các quy tắc là mỗi sinh viên bắt buộc phải có tên (NOT NULL). Nếu không có ràng buộc này, ai đó quên điền tên thì trong database sẽ có "sinh viên không tên". Hoặc ví dụ khác: bạn quyết định giá trị mặc định cho số tín chỉ của khoá học mới là 0 (DEFAULT), để khỏi phải nghĩ mỗi lần thêm khoá học.
Làm việc với ràng buộc NOT NULL
Ràng buộc NOT NULL bắt buộc phải điền giá trị cho cột đó khi thêm bản ghi. Nếu bạn thử chèn NULL vào cột này hoặc không điền gì, database sẽ "giận" (báo lỗi liền). Xem ví dụ nhé.
Tạo bảng đơn giản students:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL, -- Tên không được để trống
age INT
);
Lưu ý: cột name có ràng buộc NOT NULL, còn cột age thì không.
Ví dụ chèn dữ liệu với NOT NULL
Giờ thử thêm sinh viên:
-- Ví dụ chèn thành công
INSERT INTO students (name, age) VALUES ('Alice', 23);
-- Thành công: đã điền tên, trường này thoả mãn ràng buộc NOT NULL
-- Ví dụ lỗi:
INSERT INTO students (age) VALUES (30);
-- Lỗi: trường name không được NULL vì có ràng buộc NOT NULL
Khi bạn gặp lỗi kiểu null value in column "name" violates not-null constraint, đừng hoảng — PostgreSQL chỉ nhắc bạn cẩn thận hơn thôi.
Sử dụng giá trị mặc định (DEFAULT)
Ràng buộc DEFAULT nói với database: "Nếu lỡ quên điền giá trị cho cột này, hãy dùng giá trị này nhé". Cái này giúp dev đỡ phải điền từng dòng một cách thủ công.
Ví dụ bảng với ràng buộc DEFAULT
Tạo bảng courses:
CREATE TABLE courses (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
credits INT DEFAULT 0 -- Giá trị mặc định cho cột credits là 0
);
Ví dụ chèn dữ liệu với DEFAULT
Giờ thử thêm khoá học:
-- Đã chỉ định giá trị cho credits
INSERT INTO courses (name, credits) VALUES ('Mathematics', 5);
-- Không chỉ định giá trị cho credits — sẽ dùng giá trị mặc định (0)
INSERT INTO courses (name) VALUES ('History');
-- Xem kết quả
SELECT * FROM courses;
Kết quả:
| id | name | credits |
|---|---|---|
| 1 | Mathematics | 5 |
| 2 | History | 0 |
Lưu ý: khi thêm khoá học History mà không điền số tín chỉ, PostgreSQL tự động điền cột credits bằng 0.
Kết hợp ràng buộc NOT NULL và DEFAULT
Những cột như vậy luôn phải có giá trị, kể cả khi bạn không điền thì nó cũng không được NULL. Ví dụ, trong bảng courses cột credits vừa có DEFAULT vừa NOT NULL, đảm bảo không ai để trống NULL được.
CREATE TABLE courses (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
credits INT NOT NULL DEFAULT 0
);
Ví dụ chèn dữ liệu
Giả sử mỗi khoá học mới tạo mặc định có 0 tín chỉ, nhưng NULL là không chấp nhận.
-- Thành công: credits nhận giá trị mặc định
INSERT INTO courses (name) VALUES ('Physics');
-- Lỗi: cố tình chèn NULL vào cột có NOT NULL
INSERT INTO courses (name, credits) VALUES ('Chemistry', NULL);
Ví dụ: Thêm sinh viên với tên bắt buộc
Tạo bảng students với ràng buộc:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL, -- Tên là bắt buộc
enrollment_date DATE DEFAULT CURRENT_DATE -- Ngày nhập học mặc định là ngày hiện tại
);
Giờ thêm sinh viên vào bảng:
-- Đã điền tên, ngày nhập học sẽ tự động điền
INSERT INTO students (name) VALUES ('Bob');
-- Thử không điền tên (sẽ bị lỗi)
INSERT INTO students (enrollment_date) VALUES ('2024-10-01');
Đây là ví dụ hay cho việc PostgreSQL giúp đảm bảo dữ liệu chuẩn: mọi sinh viên đều có tên, còn ngày nhập học thì không cần điền cũng được.
Mẹo và "bẫy"
Khi làm việc với ràng buộc NOT NULL và DEFAULT, nhớ vài điều quan trọng nhé. Ví dụ, nếu dữ liệu của bạn hay có NULL, ràng buộc NOT NULL sẽ làm bạn đau đầu. Còn nếu đặt giá trị mặc định cho mọi cột, bạn có thể vô tình tạo ra dữ liệu không đúng (kiểu như 0 thay vì giá trị thực).
Thường thì nếu bạn thêm cột mới vào bảng đã có sẵn, các ô của cột đó cho dòng cũ sẽ là NULL. Nhưng nếu bạn chỉ định DEFAULT X, cả cột sẽ được điền giá trị X luôn. Cực tiện, giúp giữ database luôn chuẩn.
Ví dụ, cột mới là FOREING KEY tới bảng đã có. Và nó không được NULL hay 0. Nó phải tham chiếu tới dòng có sẵn của bảng kia.
Làm gì nếu quên thêm ràng buộc?
Đừng lo — bạn luôn có thể thêm ràng buộc sau bằng lệnh ALTER TABLE. Ví dụ:
-- Thêm ràng buộc DEFAULT cho cột đã có
ALTER TABLE courses ALTER COLUMN credits SET DEFAULT 0;
-- Thêm ràng buộc NOT NULL cho cột đã có
ALTER TABLE students ALTER COLUMN name SET NOT NULL;
Những câu lệnh này không làm hỏng dữ liệu cũ đâu - bạn có thể áp dụng cho bảng đã có dữ liệu quan trọng rồi.
Giờ thì bạn đã sẵn sàng tận dụng sức mạnh của PostgreSQL để quản lý ràng buộc rồi đó! Dữ liệu của bạn sẽ chuẩn hơn, ít lỗi hơn, còn query thì logic và dễ đoán hơn nhiều.
GO TO FULL VERSION