Chuẩn hóa cơ sở dữ liệu: 1NF, 2NF, 3NF giải thích bằng ví dụ

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

Một bảng đơn chứa mọi thứ nhìn thì tiện, nhưng sẽ sớm gây ra dữ liệu trùng lặp, sửa một chỗ quên chỗ khác và mâu thuẫn thông tin. Chuẩn hóa là quy trình tách bảng hợp lý để tránh những vấn đề đó. Bài này đi qua ba dạng chuẩn đầu tiên bằng ví dụ dễ hình dung.

Bảng ban đầu có vấn đề gì?

Giả sử bạn lưu đơn hàng trong một bảng duy nhất:

orders_raworder_id | customer_name | customer_phone | products1        | An            | 0901...        | "Bút, Vở, Thước"2        | An            | 0901...        | "Bút"3        | Bình          | 0902...        | "Vở, Thước"

Rắc rối thấy ngay: thông tin khách hàng lặp lại (đổi số điện thoại của An phải sửa nhiều dòng), cột sản phẩm nhồi nhiều giá trị khiến việc tìm kiếm và thống kê rất khó. Đây là những bất thường khi chèn, sửa và xóa mà chuẩn hóa nhắm tới.

Dạng chuẩn 1 (1NF): mỗi ô một giá trị

Yêu cầu: mỗi cột chỉ chứa một giá trị nguyên tử, không có nhóm lặp. Cột products chứa nhiều sản phẩm vi phạm quy tắc này. Cách sửa là mỗi sản phẩm một dòng:

order_itemsorder_id | customer_name | customer_phone | product1        | An            | 0901...        | Bút1        | An            | 0901...        | Vở1        | An            | 0901...        | Thước2        | An            | 0901...        | Bút

Dữ liệu đã nguyên tử, nhưng thông tin khách hàng lặp còn nhiều hơn trước. Chúng ta cần bước tiếp theo.

Dạng chuẩn 2 (2NF): phụ thuộc toàn phần vào khóa

Yêu cầu: đạt 1NF, và mọi cột không thuộc khóa phải phụ thuộc vào toàn bộ khóa chính, không chỉ một phần của nó. Khóa của bảng trên là cặp (order_id, product), nhưng customer_name chỉ phụ thuộc order_id, vi phạm 2NF. Tách ra:

orders:       order_id | customer_name | customer_phoneorder_items:  order_id | product

Dạng chuẩn 3 (3NF): không phụ thuộc bắc cầu

Yêu cầu: đạt 2NF, và các cột không thuộc khóa không được phụ thuộc vào nhau qua cột khác. Trong orders, customer_phone phụ thuộc vào khách hàng chứ không trực tiếp vào đơn hàng (order_id → customer → phone). Tách thêm bảng khách hàng:

customers:    customer_id | name | phoneorders:       order_id | customer_idproducts:     product_id | name | priceorder_items:  order_id | product_id | quantity

Giờ mỗi thông tin chỉ nằm ở đúng một nơi. Đổi số điện thoại của An chỉ cần sửa một dòng.

Trong SQL

CREATE TABLE customers (  id BIGINT PRIMARY KEY AUTO_INCREMENT,  name VARCHAR(100) NOT NULL,  phone VARCHAR(20));CREATE TABLE orders (  id BIGINT PRIMARY KEY AUTO_INCREMENT,  customer_id BIGINT NOT NULL,  FOREIGN KEY (customer_id) REFERENCES customers(id));CREATE TABLE order_items (  order_id BIGINT NOT NULL,  product_id BIGINT NOT NULL,  quantity INT NOT NULL DEFAULT 1,  PRIMARY KEY (order_id, product_id));

Khi nào nên phi chuẩn hóa?

Chuẩn hóa tối đa không phải lúc nào cũng tốt. Việc ghép nhiều bảng cho mỗi truy vấn có thể chậm khi dữ liệu rất lớn. Đôi khi người ta cố ý lặp một ít dữ liệu (phi chuẩn hóa) để tăng tốc đọc. Ví dụ lưu giá sản phẩm tại thời điểm mua trong order_items, vì giá hiện tại có thể đổi sau này; đây không phải sai lầm mà là yêu cầu nghiệp vụ. Quy tắc: chuẩn hóa trước cho đúng, phi chuẩn hóa có chủ đích sau khi đã đo được vấn đề.

Mẹo thiết kế thực tế

  • Mỗi bảng đại diện cho một loại thực thể rõ ràng.
  • Dùng khóa chính ổn định (id tự tăng hoặc UUID), đừng dùng dữ liệu có thể đổi như email làm khóa chính.
  • Khai báo khóa ngoại để database bảo vệ tính toàn vẹn.
  • Quan hệ nhiều-nhiều cần bảng trung gian như order_items.
  • Vẽ sơ đồ quan hệ thực thể (ERD) trước khi tạo bảng.

Câu hỏi hay gặp khi phỏng vấn

Chuẩn hóa là chủ đề quen thuộc trong phỏng vấn backend. Người phỏng vấn thường không cần bạn đọc thuộc định nghĩa; họ muốn thấy bạn giải thích được vì sao chuẩn hóa, qua một ví dụ cụ thể, và biết khi nào nên phi chuẩn hóa. Hãy luyện cách kể câu chuyện như bài này: bắt đầu từ bảng lộn xộn, chỉ ra bất thường khi sửa dữ liệu, rồi tách dần. Nếu bạn nêu thêm được ví dụ phi chuẩn hóa có lý do chính đáng như lưu giá tại thời điểm mua hoặc lưu sẵn số lượng bình luận để tránh đếm lại, bạn sẽ ghi điểm vì cho thấy tư duy thực tế chứ không chỉ lý thuyết.

Kết luận

Ba dạng chuẩn đầu tiên có thể nhớ gọn: một giá trị mỗi ô, phụ thuộc toàn bộ khóa, và không phụ thuộc bắc cầu. Hãy thử lấy một bảng "tất cả trong một" trong dự án của bạn và chuẩn hóa nó, bạn sẽ thấy dữ liệu trở nên sạch và dễ bảo trì hơn hẳn.

Muốn học bài bản và có lộ trình rõ ràng? Bạn có thể xem các khóa học trên codebem.com.

author_photo
Nguyễn Đình Cường

0 comment