CodeGym /Các khóa học /SQL SELF /Nguyên lý của chuẩn hóa dạng hai (2NF)

Nguyên lý của chuẩn hóa dạng hai (2NF)

SQL SELF
Mức độ , Bài học
Có sẵn

Một bảng được coi là đạt chuẩn hóa dạng hai nếu:

  1. Nó đã ở chuẩn hóa dạng một (1NF).
  2. 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_idcourse_id kết hợp tạo thành khóa chính tổng hợp.
  • Nhưng chú ý các cột course_nameinstructor_name. Chúng chỉ phụ thuộc vào course_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_nameinstructor_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_iditem_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_nameprice 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ử:

  1. Tìm các phụ thuộc vi phạm yêu cầu 2NF.
  2. 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!

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION