Chuẩn hóa CSDL
Là quá trình tổ chức dữ liệu để giảm thiểu dư thừa và tăng tính toàn vẹn của dữ liệu. Gồm 4 loại chuẩn hóa như bên dưới nhưng thú thật thường loại 1NF, 2NF là đủ.
First Normal Form (1NF) – Chuẩn 1
Điều kiện:
Mỗi bảng phải có một khóa chính (Primary Key).
Mỗi cột chỉ chứa một giá trị duy nhất (Atomicity).
Không có danh sách giá trị trong một cột.
Ví dụ vi phạm 1NF (Cột chứa nhiều giá trị)
ID | Họ tên | Số điện thoại | Địa chỉ |
1 | An | 0987-123-456, 0978-555-666 | Hà Nội |
2 | Bình | 0912-333-444 | TP.HCM |
Lỗi vi phạm: Cột "Số điện thoại" chứa nhiều giá trị trong một ô, không tuân theo nguyên tắc "atomicity".
Cách chuẩn hóa thành 1NF (Tách thành nhiều dòng riêng biệt):
ID | Họ tên | Số điện thoại | Địa chỉ |
1 | An | 0987-123-456 | Hà Nội |
1 | An | 0978-555-666 | Hà Nội |
2 | Bình | 0912-333-444 | TP.HCM |
Second Normal Form (2NF) – Chuẩn 2
Điều kiện:
Đạt 1NF.
Mọi cột phải phụ thuộc hoàn toàn vào khóa chính, không có phụ thuộc một phần.
Ví dụ vi phạm 2NF (Cột phụ thuộc một phần vào khóa chính)
Mã đơn | Mã sản phẩm | Tên sản phẩm | Giá |
101 | P01 | Laptop Dell | 20tr |
102 | P02 | iPhone 15 | 30tr |
Lỗi vi phạm:
Khóa chính: (Mã đơn, Mã sản phẩm)
Tình trạng vi phạm:
- "Tên sản phẩm" và "Giá" chỉ phụ thuộc vào "Mã sản phẩm", không phụ thuộc hoàn toàn vào (Mã đơn, Mã sản phẩm).
Cách chuẩn hóa thành 2NF (Tách bảng sản phẩm riêng):
Bảng Đơn Hàng
Mã đơn | Mã sản phẩm |
101 | P01 |
102 | P02 |
Bảng Sản Phẩm
Mã sản phẩm | Tên sản phẩm | Giá |
P01 | Laptop Dell | 20tr |
P02 | iPhone 15 | 30tr |
Third Normal Form (3NF) – Chuẩn 3
Điều kiện:
Đạt 2NF.
Không có phụ thuộc bắc cầu giữa các cột không phải khóa chính.
Ví dụ vi phạm 3NF (Cột phụ thuộc bắc cầu)
Mã nhân viên | Tên nhân viên | Mã phòng | Tên phòng ban |
NV01 | An | PB01 | Kế toán |
NV02 | Bình | PB02 | Kỹ thuật |
Lỗi vi phạm:
Khóa chính: Mã nhân viên.
Tình trạng vi phạm:
- "Tên phòng ban" phụ thuộc vào "Mã phòng", mà "Mã phòng" lại phụ thuộc vào "Mã nhân viên" ⇒ phụ thuộc bắc cầu.
Cách chuẩn hóa thành 3NF (Tách bảng phòng ban riêng):
Bảng Nhân Viên
Mã nhân viên | Tên nhân viên | Mã phòng |
NV01 | An | PB01 |
NV02 | Bình | PB02 |
Bảng Phòng Ban
Mã phòng | Tên phòng ban |
PB01 | Kế toán |
PB02 | Kỹ thuật |
Boyce-Codd Normal Form (BCNF)
Điều kiện:
Đạt 3NF.
Nếu một cột không phải khóa chính phụ thuộc vào một phần của khóa chính, cần tách bảng.
Ví dụ vi phạm BCNF (Cột phụ thuộc một phần vào khóa chính)
Mã nhân viên | Mã dự án | Tên dự án | Vai trò |
NV01 | DA01 | AI System | Dev |
NV02 | DA02 | E-commerce | QA |
Lỗi vi phạm:
Khóa chính: (Mã nhân viên, Mã dự án).
Tình trạng vi phạm:
- "Tên dự án" chỉ phụ thuộc vào "Mã dự án", không phụ thuộc vào cả khóa chính.
Cách chuẩn hóa thành BCNF (Tách bảng dự án riêng):
Bảng Nhân Viên
Mã nhân viên | Mã dự án | Vai trò |
NV01 | DA01 | Dev |
NV02 | DA02 | QA |
Bảng Dự Án
Mã dự án | Tên dự án |
DA01 | AI System |
DA02 | E-commerce |
Fourth Normal Form (4NF)
Điều kiện:
Đạt BCNF.
Không có phụ thuộc đa trị giữa các cột.
Ví dụ vi phạm 4NF (Cột có quan hệ đa trị)
Mã giáo viên | Môn học | Ngôn ngữ dạy |
GV01 | Toán | Tiếng Việt |
GV01 | Toán | Tiếng Anh |
GV01 | Lý | Tiếng Việt |
Lỗi vi phạm:
- "Môn học" và "Ngôn ngữ dạy" là hai thuộc tính độc lập với giáo viên, nhưng đang được lưu chung một bảng.
Cách chuẩn hóa thành 4NF (Tách bảng riêng):
Bảng Giáo Viên – Môn Học
Mã giáo viên | Môn học |
GV01 | Toán |
GV01 | Lý |
Bảng Giáo Viên – Ngôn Ngữ Dạy
Mã giáo viên | Ngôn ngữ dạy |
GV01 | Tiếng Việt |
GV01 | Tiếng Anh |
Khi nào không nên dùng chuẩn hóa
Nếu hiệu năng bị ảnh hưởng: Khi số lượng bảng quá nhiều, việc join dữ liệu có thể gây giảm hiệu suất.
Khi dữ liệu có sự ổn định cao: Nếu dữ liệu ít thay đổi, có thể không cần chuẩn hóa quá mức.
Nếu đọc dữ liệu quan trọng hơn ghi dữ liệu: Hệ thống đọc dữ liệu nhiều (Read-heavy) có thể chấp nhận một số dư thừa để tối ưu tốc độ truy vấn.
Lưu ý khi áp dụng chuẩn hóa
Xác định mức chuẩn hóa phù hợp: Không phải lúc nào cũng cần đến 4NF hoặc BCNF. 1NF, 2NF, 3NF là đủ cho hầu hết các hệ thống.
Cân bằng giữa đọc và ghi dữ liệu: Chuẩn hóa quá cao có thể ảnh hưởng đến hiệu năng đọc dữ liệu.
Xem xét caching và indexing: Nếu phải join nhiều bảng, cần tối ưu bằng cache hoặc index.
Xem xét NoSQL nếu cần: Nếu hệ thống không yêu cầu quá nhiều ràng buộc quan hệ, có thể dùng NoSQL như MongoDB để tăng hiệu suất.