Một bảng được coi là đạt chuẩn hóa dạng hai nếu:
- Nó đã ở chuẩn hóa dạng một (1NF).
- Mỗi cột không phải khóa đều phụ thuộc vào toàn bộ khóa chính, chứ không chỉ một phần của khóa.
Nếu khóa chính gồm nhiều trường (khóa tổng hợp), thì không thuộc tính (cột) nào không phải khóa được phép phụ thuộc chỉ vào một phần của khóa đó. Nói cách khác, 2NF loại bỏ phụ thuộc từng phần.
Ví dụ vi phạm 2NF
Giả sử bạn có bảng student_courses (Sinh viên và Khóa học), lưu thông tin về sinh viên, các khóa học của họ và giảng viên:
| student_id | course_id | course_name | instructor_name |
|---|---|---|---|
| 1 | 101 | Toán học | Lin |
| 1 | 102 | Văn học | Song |
| 2 | 101 | Toán học | Lin |
student_idvàcourse_idkết hợp tạo thành khóa chính tổng hợp.- Nhưng chú ý các cột
course_namevàinstructor_name. Chúng chỉ phụ thuộc vàocourse_id, chứ không phải cả cặp (student_id,course_id).
Đây chính là phụ thuộc từng phần! course_name và instructor_name chỉ phụ thuộc vào một phần của khóa tổng hợp (course_id). Đây là vi phạm nguyên tắc 2NF.
Đưa bảng về 2NF
Nhiệm vụ của chúng ta là loại bỏ phụ thuộc từng phần bằng cách tách bảng thành hai bảng. Việc này giúp loại bỏ dư thừa và tăng tính nhất quán của dữ liệu.
Chúng ta tách thông tin về khóa học sang bảng riêng courses:
| course_id | course_name | instructor_name |
|---|---|---|
| 101 | Toán học | Lin |
| 102 | Văn học | Song |
Bảng chính còn lại như sau:
| student_id | course_id |
|---|---|
| 1 | 101 |
| 1 | 102 |
| 2 | 101 |
Bây giờ mỗi cột đều phụ thuộc vào toàn bộ khóa chính. Chúng ta đã chia dữ liệu hợp lý và loại bỏ vi phạm 2NF.
Ma thuật loại bỏ dư thừa
Hãy chú ý bảng trước khi chuẩn hóa. Ở cột instructor_name tên "Lin" bị lặp lại. Nếu trong thực tế có hàng ngàn bản ghi thì số lần lặp sẽ còn nhiều hơn nữa! Khi tách bảng, chúng ta loại bỏ dư thừa và giảm nguy cơ lỗi, ví dụ như gõ nhầm ("Lin" vs "Ling").
Ví dụ thực tế
Hãy tưởng tượng bạn đang quản lý đơn đặt hàng sản phẩm. Bạn có bảng order_items (đơn hàng và sản phẩm), trong đó order_id và item_id tạo thành khóa chính:
| order_id | item_id | item_name | price |
|---|---|---|---|
| 1 | 101 | Laptop | 50000 |
| 1 | 102 | Chuột | 1000 |
| 2 | 101 | Laptop | 50000 |
Như bạn thấy, giá và tên sản phẩm bị lặp lại. Đây là dấu hiệu vi phạm 2NF, vì item_name và price chỉ phụ thuộc vào item_id.
Để đưa bảng về 2NF, hãy tạo bảng items:
| item_id | item_name | price |
|---|---|---|
| 101 | Laptop | 50000 |
| 102 | Chuột | 1000 |
Và sửa bảng order_items, chỉ giữ lại id đơn hàng và id sản phẩm:
| order_id | item_id |
|---|---|
| 1 | 101 |
| 1 | 102 |
| 2 | 101 |
Bây giờ dữ liệu sạch như code sau khi review — không còn dư thừa nữa.
Bài tập thực hành: thử tự làm nhé!
Giả sử bạn có bảng employee_projects, chứa thông tin về nhân viên, dự án của họ và quản lý dự án:
| employee_id | project_id | project_name | manager_name |
|---|---|---|---|
| 1 | 201 | CRM Upgrade | Lin |
| 2 | 202 | Website Revamp | Ming |
| 1 | 202 | Website Revamp | Ming |
Hãy thử:
- Tìm các phụ thuộc vi phạm yêu cầu 2NF.
- Tách bảng thành hai bảng, loại bỏ vi phạm.
Tại sao phải tuân thủ 2NF?
Tại sao phải tuân thủ chuẩn hóa dạng hai (2NF)? Đơn giản thôi: để dữ liệu không bị lặp lại và không gây rối. Khi bạn loại bỏ phụ thuộc từng phần, bảng sẽ sạch hơn — không còn thông tin lặp lại như tên giảng viên xuất hiện ở mọi dòng. Điều này tiết kiệm dung lượng và tránh rủi ro sai lệch: chỉ cần cập nhật tên ở một nơi là mọi thứ đều đúng.
Hơn nữa, việc truy vấn cũng dễ hơn: khi cấu trúc hợp lý và dữ liệu không bị rải rác khắp nơi, filter và group sẽ chạy nhanh và ổn định hơn. Đúng là bạn sẽ phải viết SQL query phức tạp hơn một chút với JOIN, vì số bảng tăng lên. Nhưng tốt hơn là dùng một JOIN còn hơn phải xử lý hàng trăm dòng lặp lại cùng một tên. Hầu hết các trường hợp, chuẩn hóa rất đáng giá.
Tích hợp vào dự án thực tế
Kiến thức về 2NF sẽ hữu ích cho bạn:
- Khi thiết kế cơ sở dữ liệu: giúp tránh lộn xộn trong bảng.
- Khi phỏng vấn: thường bị hỏi giải thích hoặc chuẩn hóa bảng về dạng chuẩn.
- Khi làm việc thực tế: khi bạn được giao tối ưu hóa database hiện tại, tách bảng "monolithic" thành bảng chuẩn hóa.
Chuẩn hóa dạng hai (2NF) giúp loại bỏ phụ thuộc từng phần trong bảng có khóa chính tổng hợp. Chúng ta chia bảng thành các khối logic, để mỗi cột chỉ phụ thuộc vào toàn bộ khóa, không phải một phần. Điều này nâng cao chất lượng database, loại bỏ dư thừa và tăng tính linh hoạt. Sẵn sàng cho chuẩn hóa dạng ba chưa? Tiếp tục nào!
GO TO FULL VERSION