Chuẩn hóa cơ sở dữ liệu có thể tóm gọn trong một câu: "Cùng một sự thật chỉ lưu ở đúng một nơi." Cách làm điều đó một cách có hệ thống chính là 1NF → 2NF → 3NF.
Vì sao điều này quan trọng? — Nếu cùng một thông tin bị rải ra ở nhiều hàng, chỉ cần bạn sửa một chỗ mà quên những chỗ còn lại thì dữ liệu sẽ mâu thuẫn với nhau. Đây được gọi là bất thường cập nhật. Hãy thử tự trải nghiệm ở bên dưới.
Phòng làm việc của Prof.A đã thay đổi, nhưng trong bảng chưa chuẩn hóa thì bạn phải sửa thủ công cả 2 hàng. Chỉ cần sót một hàng thôi là sẽ xuất hiện mâu thuẫn kiểu "Prof.A vừa ở Room 301 vừa ở Room 502". Còn với bảng 3NF, bạn chỉ cần sửa đúng 1 hàng là xong.
Đó chính là toàn bộ ý tưởng của chuẩn hóa — phần còn lại chỉ là các quy tắc để quyết định "cột nào nên đặt ở đâu để mỗi sự thật chỉ được lưu một lần".
Phụ thuộc hàm — tiêu chí để quyết định chuẩn hóa
Chuẩn hóa xem xét "cột này phụ thuộc vào đâu". Điều này được gọi là phụ thuộc hàm.
Ví dụ, student_id → student_name có nghĩa là "biết ID sinh viên thì xác định được tên sinh viên".
Trong sơ đồ bên dưới, hãy chú ý màu của các mũi tên:
- Xanh lá = phụ thuộc vào toàn bộ khóa (bình thường)
- Vàng = chỉ phụ thuộc vào một phần của khóa (phụ thuộc bộ phận → vi phạm 2NF)
- Đỏ nét đứt = phụ thuộc thông qua một cột không khóa (phụ thuộc bắc cầu → vi phạm 3NF)
Loại bỏ các mũi tên màu vàng và đỏ = tách bảng ra = chuẩn hóa.
Nhìn 1NF → 2NF → 3NF trong một lần
Hãy bấm thử bên dưới để xem bảng được tách ra theo từng bước như thế nào. Các ô màu đỏ cho biết "cột này không nên nằm ở đây".
1NF: Mỗi ô chỉ có một giá trị
Nếu một ô chứa nhiều giá trị như MATH101, CS102 thì bạn sẽ không thể tìm kiếm đúng cách, cũng không thể JOIN được.
Quy tắc: Mọi ô đều phải mang tính nguyên tử (chỉ một giá trị).
Các cột như phone1, phone2, phone3 cũng gặp đúng vấn đề đó — chỉ là bạn đang giấu các giá trị vào trong tên cột mà thôi.
2NF: Loại bỏ phụ thuộc bộ phận
Trong một bảng có khóa ghép (student_id, course_id), thì student_name chỉ phụ thuộc vào student_id. Nó không phụ thuộc vào toàn bộ khóa, mà chỉ phụ thuộc vào một phần của khóa — đó chính là phụ thuộc hàm bộ phận.
Quy tắc: Mọi cột không khóa phải phụ thuộc vào toàn bộ khóa.
Nếu có phụ thuộc bộ phận, hãy tách cột đó ra thành một bảng riêng.
Nếu khóa chỉ có một cột thì sao? Khi đó phụ thuộc bộ phận là không thể xảy ra, nên nếu đã đạt 1NF thì tự động đạt 2NF.
3NF: Loại bỏ phụ thuộc bắc cầu
Trong bảng Courses, instructor_office không phụ thuộc trực tiếp vào course_id (khóa). Nó đi theo đường course_id → instructor_id → instructor_office — tức là một cột không khóa lại phụ thuộc vào một cột không khóa khác. Đây chính là phụ thuộc bắc cầu.
Quy tắc: Cột không khóa chỉ được phụ thuộc thông qua khóa mà thôi. Không được đi qua cột không khóa khác.
Cách xử lý: tách instructor_office sang bảng Instructors.
Thay vì học thuộc, chỉ cần nhớ một câu hỏi
"Mọi thuộc tính không khóa phải phụ thuộc vào khóa, toàn bộ khóa, và chỉ khóa mà thôi."
Câu này là đủ:
- khóa = 1NF (sự thật phải có thể được nhận diện bằng khóa)
- toàn bộ khóa = 2NF (phụ thuộc vào cả khóa, không chỉ một phần)
- chỉ khóa mà thôi = 3NF (phụ thuộc trực tiếp vào khóa, không đi qua cột không khóa)
Khi gặp bài chuẩn hóa trong đề thi, hãy chỉ đặt một câu hỏi: "Cột này phụ thuộc vào ai? Toàn bộ khóa, một phần của khóa, hay là một cột không khóa?"
Những nhầm lẫn thường gặp
"Đến 3NF là xong" — 3NF là một điểm khởi đầu tốt, không phải đích đến cuối cùng. Có trường hợp cần BCNF nghiêm ngặt hơn, và cũng có trường hợp người ta cố ý phi chuẩn hóa để tối ưu hiệu năng.
"Càng tách nhiều bảng càng tốt" — Mục tiêu của chuẩn hóa không phải là tăng số lượng bảng, mà là để "mỗi bảng chỉ chịu trách nhiệm cho một loại sự thật". Nếu tách mà không có lý do rõ ràng về quan hệ phụ thuộc, thì chỉ làm cho JOIN phức tạp hơn.
"NoSQL thì không cần chuẩn hóa" — Chuẩn hóa là thuật ngữ dành riêng cho DB quan hệ, nhưng bài toán "giữ tính nhất quán của dữ liệu trùng lặp" thì tồn tại trong mọi loại DB. Ngay cả khi phi chuẩn hóa, bạn cũng cần biết rõ mình đang đánh đổi điều gì.
Tự kiểm tra thử
Hãy chọn một bảng trong chính dự án của bạn và làm như sau:
- Viết ra khóa của bảng là gì.
- Kiểm tra xem mỗi cột không khóa có phụ thuộc vào toàn bộ khóa hay chỉ một phần của khóa. → Nếu chỉ một phần thì vi phạm 2NF.
- Kiểm tra xem cột không khóa có phụ thuộc vào cột không khóa khác hay không. → Nếu có thì vi phạm 3NF.
Chỉ với 3 bước này, bạn có thể phát hiện được phần lớn các vấn đề chuẩn hóa.
Cần trợ giúp giải bài?
Tải câu hỏi lên và nhận lời giải từng bước đã được xác minh trong vài giây.
Mở GPAI Solver →