Courses
Chuẩn hóa là một trong những khái niệm nền tảng nhất trong thiết kế cơ sở dữ liệu quan hệ. Trong hướng dẫn này, tôi sẽ đi qua từng dạng chuẩn (từ 1NF đến 5NF) kèm ví dụ thực tế để bạn có thể áp dụng các nguyên tắc này vào cơ sở dữ liệu của riêng mình. Dù bạn hướng tới trở thành nhà khoa học dữ liệu hay kỹ sư dữ liệu, việc hiểu chuẩn hóa là rất quan trọng.
TL;DR
- Chuẩn hóa tổ chức các bảng trong cơ sở dữ liệu quan hệ để loại bỏ dư thừa và bảo vệ tính toàn vẹn dữ liệu
- 1NF: Mỗi ô chứa một giá trị nguyên tử duy nhất; mỗi hàng có thể xác định duy nhất
- 2NF: Loại bỏ phụ thuộc bộ phận—các cột không khóa phải phụ thuộc vào toàn bộ khóa chính
- 3NF: Loại bỏ phụ thuộc bắc cầu—các cột không khóa chỉ phụ thuộc vào khóa chính, không phụ thuộc vào cột không khóa khác
- BCNF, 4NF, 5NF: Xử lý phụ thuộc hàm, phụ thuộc đa trị và phụ thuộc phép nối cho các lược đồ phức tạp
- Hầu hết cơ sở dữ liệu sản xuất chỉ cần chuẩn hóa đến 3NF; các dạng cao hơn áp dụng cho trường hợp chuyên biệt
Chuẩn hóa trong SQL là gì?
Trong ngữ cảnh này, chuẩn hóa là quá trình tổ chức dữ liệu trong một cơ sở dữ liệu (cơ sở dữ liệu quan hệ) để loại bỏ các bất thường dữ liệu như dư thừa.
Nói đơn giản, đó là việc tách một bảng lớn, phức tạp thành các bảng nhỏ và đơn giản hơn trong khi vẫn duy trì mối quan hệ dữ liệu.
Chuẩn hóa thường được sử dụng khi xử lý các tập dữ liệu lớn.
Hãy cùng điểm qua nhanh một số tình huống thường áp dụng chuẩn hóa.
Tính toàn vẹn dữ liệu
Hãy hình dung một cơ sở dữ liệu chứa thông tin khách hàng. Nếu không chuẩn hóa, khi khách hàng thay đổi tuổi, chúng ta phải cập nhật ở nhiều nơi, làm tăng rủi ro không nhất quán. Bằng cách chuẩn hóa dữ liệu, chúng ta có thể có các bảng riêng biệt được liên kết bằng một định danh duy nhất để đảm bảo dữ liệu chính xác và nhất quán.
Truy vấn hiệu quả
Xét một cơ sở dữ liệu phức tạp với nhiều bảng liên quan có lưu trữ thông tin dư thừa. Trong trường hợp này, các truy vấn có join sẽ phức tạp và tốn tài nguyên hơn. Chuẩn hóa giúp đơn giản hóa truy vấn bằng cách tách dữ liệu thành các bảng nhỏ, mỗi bảng chỉ chứa thông tin liên quan, từ đó giảm nhu cầu join phức tạp.
Tối ưu hóa lưu trữ
Một vấn đề lớn với dữ liệu dư thừa là chiếm dụng không gian lưu trữ không cần thiết. Ví dụ, nếu lưu cùng thông tin sản phẩm trong mọi bản ghi đơn hàng, sẽ dẫn đến trùng lặp. Với chuẩn hóa, bạn có thể loại bỏ dư thừa bằng cách tách dữ liệu vào các bảng riêng.
Vì sao chuẩn hóa trong SQL quan trọng?
Chuẩn hóa đóng vai trò then chốt trong thiết kế cơ sở dữ liệu. Dưới đây là một số lý do vì sao nó cần thiết:
- Giảm dư thừa:Dư thừalà khi cùng một thông tin được lưu nhiều lần, và cách tốt để tránh là tách dữ liệu thành các bảng nhỏ hơn.
- Cải thiện hiệu năng truy vấn: Bạn có thể thực thi truy vấn nhanh hơn trên các bảng nhỏ đã được chuẩn hóa.
- Giảm thiểu bất thường khi cập nhật: Với các bảng đã chuẩn hóa, bạn có thể cập nhật dữ liệu dễ dàng mà không ảnh hưởng tới bản ghi khác.
- Tăng cường tính toàn vẹn dữ liệu: Đảm bảo dữ liệu luôn nhất quán và chính xác.
Điều gì dẫn đến nhu cầu chuẩn hóa?
Nếu một bảng không được chuẩn hóa đúng và có dư thừa dữ liệu, nó không chỉ chiếm thêm không gian lưu trữ mà còn khiến việc xử lý và cập nhật cơ sở dữ liệu trở nên khó khăn.
Có một số yếu tố thúc đẩy nhu cầu chuẩn hóa, từ dư thừa dữ liệu (như đã đề cập) đến khó khăn khi quản lý quan hệ. Hãy đi thẳng vào vấn đề:
- Bất thường khi chèn, xóa và cập nhật: Bất kỳ thay đổi nào trong một bảng cũng có thể dẫn đến lỗi hoặc không nhất quán ở các bảng khác nếu không xử lý cẩn thận. Những thay đổi này có thể là thêm dữ liệu mới, cập nhật dữ liệu hoặc xóa bản ghi, dẫn đến mất dữ liệu ngoài ý muốn.
- Khó khăn khi quản lý quan hệ: Việc duy trì các quan hệ phức tạp trở nên thách thức hơn trong cấu trúc chưa chuẩn hóa.
- Các yếu tố khác thúc đẩy nhu cầu chuẩn hóa là phụ thuộc bộ phận và phụ thuộc bắc cầu, trong đó phụ thuộc bộ phận có thể gây dư thừa dữ liệu và bất thường cập nhật, còn phụ thuộc bắc cầu có thể gây bất thường dữ liệu. Chúng ta sẽ xem cách xử lý các phụ thuộc này để đảm bảo chuẩn hóa cơ sở dữ liệu ở các phần sau.
Các loại chuẩn hóa cơ sở dữ liệu
Đến đây, chúng ta đã xem chuẩn hóa trong SQL là gì, vì sao quan trọng và điều gì gây ra nhu cầu chuẩn hóa. Chuẩn hóa cơ sở dữ liệu cónhiều dạng, mỗi dạng có mức độ tổ chức dữ liệu cao dần.
Trong phần này, chúng ta sẽ thảo luận ngắn về các mức chuẩn hóa khác nhau rồi tìm hiểu sâu hơn ở phần kế tiếp.

Hình ảnh của Tác giả
So sánh nhanh các dạng chuẩn
| Dạng chuẩn | Yêu cầu | Loại bỏ điều gì |
|---|---|---|
| 1NF | Giá trị nguyên tử trong mọi ô; các hàng là duy nhất | Nhóm lặp và ô đa trị |
| 2NF | Không có phụ thuộc bộ phận trên khóa tổng hợp | Dư thừa do quan hệ với một phần khóa |
| 3NF | Không có phụ thuộc bắc cầu | Phụ thuộc gián tiếp giữa các cột không khóa |
| BCNF | Mọi định thức là một khóa ứng viên | Bất thường bị 3NF bỏ sót |
| 4NF | Không có phụ thuộc đa trị | Thuộc tính đa trị độc lập |
| 5NF | Không có phụ thuộc phép nối | Dư thừa do phân rã bảng mất mát thông tin |
Dạng chuẩn thứ nhất (1NF)
Mức chuẩn hóa này đảm bảo mỗi cột trong dữ liệu chỉ chứa giá trị nguyên tử. Giá trị nguyên tử ở đây có nghĩa là mỗi mục trong một cột là không thể chia nhỏ. Tương tự như việc mỗi ô trong bảng tính chỉ nên chứa một thông tin. 1NF đảm bảo tính nguyên tử của dữ liệu, mỗi ô cột chỉ chứa một giá trị và mỗi cột có tên duy nhất.
Dạng chuẩn thứ hai (2NF)
Loại bỏ phụ thuộc bộ phận bằng cách đảm bảo các thuộc tính không khóa chỉ phụ thuộc vào khóa chính. Nói cách khác, phải có quan hệ trực tiếp giữa mỗi cột với khóa chính, chứ không phải giữa các cột với nhau.
Dạng chuẩn thứ ba (3NF)
Loại bỏ phụ thuộc bắc cầu bằng cách đảm bảo các thuộc tính không khóa chỉ phụ thuộc vào khóa chính. Mức chuẩn hóa này xây dựng trên 2NF.
Dạng chuẩn Boyce-Codd (BCNF)
Đây là phiên bản nghiêm ngặt hơn của 3NF, xử lý thêm các bất thường. Ở mức này, mọi định thức đều là khóa ứng viên.
Dạng chuẩn thứ tư (4NF)
Đây là mức chuẩn hóa xây dựng trên BCNF bằng cách xử lý phụ thuộc đa trị.
Dạng chuẩn thứ năm (5NF)
5NF là mức chuẩn hóa cao nhất, xử lý phụ thuộc phép nối. Được dùng trong các tình huống cụ thể để giảm thiểu hơn nữa dư thừa bằng cách tách một bảng thành các bảng nhỏ hơn.
Chuẩn hóa cơ sở dữ liệu với ví dụ thực tế
Chúng ta đã điểm qua các mức chuẩn hóa dữ liệu. Hãy đào sâu từng mức với ví dụ và giải thích.
Chuẩn hóa 1NF
1NF đảm bảo mỗi ô cột chỉ chứa giá trị nguyên tử. Hãy tưởng tượng cơ sở dữ liệu thư viện với bảng lưu thông tin sách (title, author, genre và borrowed_by). Nếu bảng chưa chuẩn hóa, borrowed_by có thể chứa danh sách tên người mượn ngăn cách bằng dấu phẩy. Điều này vi phạm 1NF vì một ô chứa nhiều giá trị. Bảng dưới đây là minh họa điển hình cho vi phạm 1NF như đã mô tả.
title | author | genre | borrowed_by |
To Kill a Mockingbird | Harper Lee | Fiction | John Doe, Jane Doe, James Brown |
The Lord of the Rings | J. R. R. Tolkien | Fantasy | Emily Garcia, David Lee |
Harry Potter and the Sorcerer’s Stone | J.K. Rowling | Fantasy | Michael Chen |
Giải pháp?
Trong 1NF, chúng ta tạo một bảng riêng cho người mượn và liên kết với bảng sách. Các bảng này có thể liên kết bằng khóa ngoại trong bảng người mượn hoặc một bảng liên kết riêng. Cách dùng khóa ngoại trong bảng người mượn là thêm một cột khóa ngoại tham chiếu khóa chính của bảng sách. Cách này cưỡng bức quan hệ giữa các bảng, đảm bảo tính nhất quán dữ liệu.
Bạn có thể xem minh họa dưới đây:
Dưới đây là SQL để tạo các bảng đã chuẩn hóa:
CREATE TABLE books (
book_id INT PRIMARY KEY,
title VARCHAR(255),
author VARCHAR(100),
genre VARCHAR(50)
);
CREATE TABLE borrowers (
borrower_id INT PRIMARY KEY,
name VARCHAR(100),
book_id INT,
FOREIGN KEY (book_id) REFERENCES books(book_id)
);Bảng Books
book_id (PK) | title | author | genre |
1 | To Kill a Mockingbird | Harper Lee | Fiction |
2 | The Lord of the Rings | J. R. R. Tolkien | Fantasy |
3 | Harry Potter and the Sorcerer’s Stone | J.K. Rowling | Fantasy |
Bảng Borrowers
borrower_id (PK) | name | book_id (FK) |
1 | John Doe | 1 |
2 | Jane Doe | 1 |
3 | James Brown | 1 |
4 | Emily Garcia | 2 |
5 | David Lee | 2 |
6 | Michael Chen | 3 |
Dạng chuẩn thứ hai (2NF)
Mức chuẩn hóa này, như đã mô tả, xây dựng trên 1NF bằng cách đảm bảo không có phụ thuộc bộ phận vào khóa chính. Nói đơn giản, mọi thuộc tính không khóa phải phụ thuộc vào toàn bộ khóa chính chứ không chỉ một phần.
Từ 1NF đã triển khai, chúng ta có hai bảng riêng (xem phần 1NF).
Giờ, giả sử chúng ta muốn liên kết các bảng này để ghi nhận việc mượn. Cách tiếp cận ban đầu có thể là thêm cột borrower_id vào bảng books, như dưới đây:
book_id (PK) | title | author | genre | borrower_id (FK) |
1 | To Kill a Mockingbird | Harper Lee | Fiction | 1 |
2 | The Lord of the Rings | J. R. R. Tolkien | Fantasy | NULL |
3 | Harry Potter and the Sorcerer’s Stone | J.K. Rowling | Fantasy | 6 |
Cách này có vẻ là giải pháp, nhưng nó vi phạm 2NF vì borrower_id chỉ phụ thuộc bộ phận vào book_id. Một cuốn sách có thể có nhiều người mượn, nhưng một borrower_id chỉ có thể liên kết với một cuốn sách trong cấu trúc này. Điều này tạo phụ thuộc bộ phận.
Giải pháp?
Chúng ta cần đạt quan hệ nhiều-nhiều giữa sách và người mượn để đạt 2NF. Có thể thực hiện bằng cách thêm một bảng riêng:
Bảng Book_borrowings
| borrowing_id (PK) | book_id (FK) | borrower_id (FK) | borrowed_date |
|---|---|---|---|
| 1 | 1 | 1 | 2024-05-04 |
| 2 | 2 | 4 | 2024-05-04 |
| 3 | 3 | 6 | 2024-05-04 |
Bảng này thiết lập quan hệ rõ ràng giữa sách và người mượn. book_id và borrower_id đóng vai trò khóa ngoại, tham chiếu khóa chính ở các bảng tương ứng. Cách này đảm bảo borrower_id phụ thuộc vào toàn bộ khóa chính (book_id) của bảng books, tuân thủ 2NF.
Dạng chuẩn thứ ba (3NF)
3NF xây dựng trên 2NF bằng cách loại bỏ phụ thuộc bắc cầu. Phụ thuộc bắc cầu xảy ra khi một thuộc tính không khóa phụ thuộc vào một thuộc tính không khóa khác, và thuộc tính đó lại phụ thuộc vào khóa chính. Về bản chất, nó theo luật bắc cầu.
Từ 2NF đã triển khai, có ba bảng trong cơ sở dữ liệu thư viện của chúng ta:
Bảng Books
book_id (PK) | title | author | genre |
1 | To Kill a Mockingbird | Harper Lee | Fiction |
2 | The Lord of the Rings | J. R. R. Tolkien | Fantasy |
3 | Harry Potter and the Sorcerer’s Stone | J.K. Rowling | Fantasy |
Bảng Borrowers
borrower_id (PK) | name | book_id (FK) |
1 | John Doe | 1 |
2 | Jane Doe | 1 |
3 | James Brown | 1 |
4 | Emily Garcia | 2 |
5 | David Lee | 2 |
6 | Michael Chen | 3 |
Bảng Book_borrowings
borrowing_id (PK) | book_id (FK) | borrower_id (FK) | borrowed_date |
1 | 1 | 1 | 2024-05-04 |
2 | 2 | 4 | 2024-05-04 |
3 | 3 | 6 | 2024-05-04 |
Cấu trúc 2NF trông hiệu quả, nhưng có thể tồn tại phụ thuộc ẩn. Giả sử chúng ta thêm cột due_date vào bảng books. Nghe có vẻ hợp lý, nhưng sẽ tạo ra phụ thuộc bắc cầu nơi:
- Cột due_date phụ thuộc vào borrowing_id (một thuộc tính không khóa) từ bảng book_borrowings.
- borrowing_id lại phụ thuộc vào book_id (khóa chính) của bảng books.
Hệ quả là due_date phụ thuộc vào một thuộc tính trung gian không khóa (borrowing_id) thay vì phụ thuộc trực tiếp vào khóa chính (book_id). Điều này vi phạm 3NF.
Giải pháp?
Chúng ta có thể chuyển cột due_date sang bảng phù hợp nhất bằng cách cập nhật bảng book_borrowings để bao gồm các cột due_date và returned_date.
Dưới đây là bảng đã cập nhật:
borrowing_id (PK) | book_id (FK) | borrower_id (FK) | borrowed_date | due_date |
1 | 1 | 1 | 2024-05-04 | 2024-05-20 |
2 | 2 | 4 | 2024-05-04 | 2024-05-18 |
3 | 3 | 6 | 2024-05-04 | 2024-05-10 |
Bằng cách đặt cột due_date trong bảng book_borrowing, chúng ta đã loại bỏ thành công phụ thuộc bắc cầu.
Điều này có nghĩa due_date giờ phụ thuộc trực tiếp vào mối quan hệ kết hợp giữa book_id và borrower_id. Ở đây, book_id và borrower_id đóng vai trò khóa ngoại tổng hợp, cùng nhau tạo thành khóa chính của bảng book_borrowings.
Dạng chuẩn Boyce-Codd (BCNF)
BCNF dựa trên phụ thuộc hàm, xét tất cả khóa ứng viên trong một quan hệ.
Phụ thuộc hàm (FD) xác định quan hệ giữa các thuộc tính trong cơ sở dữ liệu quan hệ. Một FD nêu rằng giá trị của một cột quyết định giá trị của cột liên quan khác. FD rất quan trọng vì chúng định hướng quá trình chuẩn hóa bằng cách xác định các phụ thuộc và đảm bảo dữ liệu được phân bổ hợp lý giữa các bảng.
BCNF nghiêm ngặt hơn 3NF. Nó đảm bảo mọi định thức (tập thuộc tính xác định duy nhất một hàng) trong một bảng là khóa ứng viên (tập thuộc tính tối thiểu xác định duy nhất một hàng). Tinh thần cốt lõi là mọi định thức đều có thể đóng vai trò khóa chính.
Nó đảm bảo mọi phụ thuộc hàm (FD) có một siêu khóa làm định thức. Nói cách khác, nếu X —> Y (X quyết định Y) đúng, X phải là khóa ứng viên (siêu khóa) của quan hệ. Lưu ý X và Y là các cột trong một bảng dữ liệu.
Kế thừa từ 3NF, chúng ta có ba bảng:
Bảng Books
book_id (PK) | title | author | genre |
1 | To Kill a Mockingbird | Harper Lee | Fiction |
2 | The Lord of the Rings | J. R. R. Tolkien | Fantasy |
3 | Harry Potter and the Sorcerer’s Stone | J.K. Rowling | Fantasy |
Bảng Borrowers
borrower_id (PK) | name | book_id (FK) |
1 | John Doe | 1 |
2 | Jane Doe | 1 |
3 | James Brown | 1 |
4 | Emily Garcia | 2 |
5 | David Lee | 2 |
6 | Michael Chen | 3 |
Bảng Book_borrowings
borrowing_id (PK) | book_id (FK) | borrower_id (FK) | borrowed_date | due_date |
1 | 1 | 1 | 2024-05-04 | 2024-05-20 |
2 | 2 | 4 | 2024-05-04 | 2024-05-18 |
3 | 3 | 6 | 2024-05-04 | 2024-05-10 |
Dù cấu trúc 3NF là tốt, có thể tồn tại một định thức ẩn trong bảng book_borrowings. Giả sử một người mượn không thể mượn cùng cuốn sách hai lần đồng thời, thì kết hợp book_id và borrower_id cùng nhau xác định duy nhất một bản ghi mượn.
Cấu trúc này vi phạm BCNF vì tập kết hợp (book_id và borrower_id) không phải khóa chính của bảng (khóa chính chỉ là borrowing_id).
Giải pháp?
Để đạt BCNF, chúng ta có thể hoặc phân rã bảng book_borrowings thành hai bảng riêng, hoặc đặt tập thuộc tính kết hợp làm khóa chính.
- Cách 1 (phân rã bảng): Ở cách này, chúng ta sẽ phân rã bảng book_borrowings thành các bảng riêng:
- Một bảng với borrowing_id là khóa chính, borrowed_date, due_date và returned_date.
- Một bảng riêng để liên kết sách và người mượn, với book_id là khóa ngoại, borrower_id là khóa ngoại, và có thể có các thuộc tính bổ sung riêng cho sự kiện mượn.
- Cách 2 (đặt tập thuộc tính kết hợp làm khóa chính): Có thể cân nhắc đặt book_id và borrower_id làm khóa chính tổng hợp để xác định duy nhất các bản ghi mượn. Vấn đề của cách này là không phù hợp nếu một người mượn có thể mượn cùng cuốn sách nhiều lần.
Cuối cùng, lựa chọn giữa các phương án phụ thuộc vào nhu cầu dữ liệu cụ thể và cách bạn muốn mô hình hóa quan hệ mượn sách.
Dạng chuẩn thứ tư (4NF)
4NF xử lý phụ thuộc đa trị. Phụ thuộc đa trị tồn tại khi một thuộc tính có thể có nhiều thuộc tính phụ thuộc, và các thuộc tính phụ thuộc này độc lập với khóa chính. Khá phức tạp, nhưng chúng ta sẽ tìm hiểu sâu hơn bằng ví dụ.
Ví dụ thư viện trước đó không còn phù hợp ở mức chuẩn hóa này. 4NF thường áp dụng cho tình huống một thuộc tính có thể có nhiều thuộc tính phụ thuộc không liên quan trực tiếp đến khóa chính.
Hãy xét bối cảnh khác. Hình dung cơ sở dữ liệu lưu thông tin ấn phẩm. Ta xét bảng “Publications” với các cột title, author, publication_year và keywords.
publication_id (PK) | title | author | publication_year | keywords |
1 | To Kill a Mockingbird | Harper Lee | 1960 | Coming-of-Age, Legal |
2 | The Lord of the Rings | J. R. R. Tolkien | 1954 | Fantasy, Epic, Adventure |
3 | Pride and Prejudice | Jane Austen | 1813 | Romance, Social Commentary |
Cấu trúc bảng trên vi phạm 4NF vì:
- Cột keywords có phụ thuộc đa trị vào khóa chính publication_id. Tức là một ấn phẩm có thể có nhiều từ khóa, và các từ khóa này độc lập với định danh duy nhất của ấn phẩm.
Giải pháp?
Chúng ta có thể tạo một bảng riêng.
Bảng Publication_keywords
publication_id (FK) | keyword |
1 | Coming-of-Age |
1 | Legal |
2 | Fantasy |
2 | Epic |
2 | Adventure |
3 | Romance |
3 | Social Commentary |
Bảng mới (Publication_keywords) thiết lập quan hệ nhiều-nhiều giữa ấn phẩm và từ khóa. Mỗi ấn phẩm có thể có nhiều từ khóa liên kết qua publication_id (khóa ngoại), và mỗi từ khóa có thể gắn với nhiều ấn phẩm.
Với điều này, chúng ta đã loại bỏ thành công phụ thuộc đa trị và đạt 4NF.
Dạng chuẩn thứ năm (5NF)
5NF là dạng chuẩn hóa phức tạp nhất, loại bỏ phụ thuộc phép nối. Đây là tình huống khi cần nối dữ liệu từ nhiều bảng để trả lời một truy vấn cụ thể, ngay cả khi các bảng đã ở 4NF.
Nói đơn giản, 5NF đảm bảo không thể suy ra thêm thông tin mới bằng cách nối các bảng với nhau ngoài những gì vốn có trong các bảng riêng lẻ.
Phụ thuộc phép nối ít xảy ra khi các bảng đã được chuẩn hóa (ở 3NF hoặc 4NF), vì vậy khó tạo ví dụ rõ ràng, trực quan cho 5NF.
Tuy nhiên, hãy xem kịch bản nơi 5NF có thể phù hợp:
Hãy hình dung cơ sở dữ liệu đại học với các bảng đã chuẩn hóa cho “Courses” và “Enrollments”.
Bảng Courses
course_id (PK) | course_name | department |
101 | Introduction to Programming | Computer Science |
202 | Data Structures and Algorithms | Computer Science |
301 | Web Development I | Computer Science |
401 | Artificial Intelligence | Computer Science |
Bảng Enrollments
enrollment_id (PK) | student_id (FK) | course_id (FK) | grade |
1 | 12345 | 101 | A |
2 | 12345 | 202 | B |
3 | 56789 | 301 | A- |
4 | 56789 | 401 | B+ |
Giả sử các bảng này đã ở 3NF hoặc 4NF, một phụ thuộc phép nối có thể tồn tại tùy cách lưu dữ liệu. Chẳng hạn, một học phần có yêu cầu học phần tiên quyết được lưu trong bảng “Courses” dưới cột “prerequisite_course_id”.
Điều này có vẻ hiệu quả lúc đầu. Tuy nhiên, hãy xét truy vấn cần lấy các học phần sinh viên đã đăng ký và học phần tiên quyết tương ứng. Trong tình huống này, bạn cần join các bảng “Courses” và “Enrollments”, rồi có thể join tiếp bảng “Courses” để lấy thông tin môn tiên quyết.
Giải pháp?
Để có thể loại bỏ phụ thuộc phép nối và đạt 5NF, chúng ta có thể bổ sung bảng “Course Prerequisites” riêng:
Bảng Course_prerequisite
course_id (FK) | prerequisite_course_id (FK) |
202 | 101 |
301 | NULL |
401 | 202 |
Cách tiếp cận này tách riêng thông tin tiên quyết và cho phép truy xuất hiệu quả các học phần đã đăng ký và môn tiên quyết của chúng bằng một phép nối giữa các bảng “Enrollments” và “Course_prerequisites”.
Lưu ý: Chúng ta giả định một học phần chỉ có một môn tiên quyết.
5NF là dạng chuẩn hóa rất phức tạp và hiếm gặp, vì vậy với người mới học dữ liệu, bạn có thể chưa áp dụng ngay. Tuy nhiên, đây là kiến thức bổ sung hữu ích để bạn sẵn sàng khi gặp cơ sở dữ liệu phức tạp.
Chuẩn hóa và Phi chuẩn hóa
Trong khi chuẩn hóa giảm dư thừa và cải thiện tính toàn vẹn dữ liệu, có những trường hợp phi chuẩn hóa lại là lựa chọn tốt hơn. Phi chuẩn hóa chủ động đưa dư thừa vào để cải thiện hiệu năng đọc cho các khối lượng công việc cụ thể.
| Tiêu chí | Chuẩn hóa | Phi chuẩn hóa |
|---|---|---|
| Mục tiêu | Giảm dư thừa và bất thường | Cải thiện hiệu năng đọc/truy vấn |
| Phù hợp nhất cho | Hệ thống OLTP (giao dịch) | Hệ thống OLAP (phân tích, báo cáo) |
| Tốc độ ghi | Nhanh hơn (cập nhật một nơi) | Chậm hơn (cập nhật nhiều nơi) |
| Tốc độ đọc | Có thể chậm hơn (cần nhiều phép nối) | Nhanh hơn (ít phép nối hơn) |
| Tính toàn vẹn dữ liệu | Cao hơn | Thấp hơn (rủi ro không nhất quán) |
| Lưu trữ | Ít hơn (không trùng lặp dữ liệu) | Nhiều hơn (cố ý trùng lặp dữ liệu) |
Trong thực tế, hầu hết cơ sở dữ liệu sản xuất sử dụng kết hợp cả hai. Bắt đầu với lược đồ chuẩn hóa đầy đủ, sau đó chọn lọc phi chuẩn hóa các bảng nơi hiệu năng truy vấn đòi hỏi.
Xây dựng kỹ năng SQL của bạn
Nếu bạn đang đọc đến đây, xin chúc mừng vì đã theo dõi đến cuối. Chúng ta đã có một hành trình tuyệt vời để khám phá chuẩn hóa trong SQL là gì, vì sao quan trọng, điều gì dẫn đến nhu cầu chuẩn hóa và các loại chuẩn hóa cơ sở dữ liệu. Các kịch bản sử dụng để giải thích từng loại nhằm giúp bạn hiểu trọn vẹn và có thể áp dụng kiến thức này trong hành trình học tập.
Chuẩn hóa là kỹ năng nền tảng cho bất kỳ ai bắt đầu sự nghiệp trong lĩnh vực dữ liệu. Bằng cách hiểu các nguyên tắc này, bạn đã sẵn sàng xây dựng các cơ sở dữ liệu hiệu quả và có tổ chức tốt.
Học tập là rất quan trọng trong lĩnh vực dữ liệu, và để nâng cao kỹ năng SQL, chúng tôi có một số tài nguyên cho bạn.
Câu hỏi thường gặp
Chuẩn hóa trong DBMS là gì?
Chuẩn hóa cơ sở dữ liệu là kỹ thuật thiết kế tối ưu lược đồ của cơ sở dữ liệu quan hệ. Nó liên quan đến việc chia các bảng thành các bảng con nhỏ hơn và lưu trữ con trỏ tới dữ liệu thay vì sao chép dữ liệu.
Vì sao chuẩn hóa quan trọng?
Chuẩn hóa giúp ngăn ngừa dư thừa dữ liệu, cải thiện tính toàn vẹn dữ liệu và đơn giản hóa thao tác dữ liệu trong cơ sở dữ liệu.
Tôi có cần chuẩn hóa cơ sở dữ liệu đến 5NF không?
Không nhất thiết. Chuẩn hóa đến 3NF hoặc 4NF thường là đủ cho hầu hết cơ sở dữ liệu. 5NF là dạng nghiêm ngặt nhất và có thể hữu ích cho các cơ sở dữ liệu phức tạp với mẫu truy vấn đặc thù.
Làm sao quyết định có cần chuẩn hóa đến 5NF không?
Phân tích cẩn thận các truy vấn và mô hình dữ liệu của bạn. Nếu bạn thấy mình cần join nhiều bảng để truy xuất thông tin có thể suy ra về mặt lý thuyết từ chính các bảng riêng lẻ, thì 5NF có thể đáng cân nhắc. Tuy nhiên, luôn cân bằng giữa độ phức tạp và lợi ích hiệu năng tiềm năng. Bạn có thể tham khảo phần 5NF, nơi dùng một tình huống minh họa để hiểu rõ hơn.
Sự khác nhau giữa chuẩn hóa và phi chuẩn hóa là gì?
Chuẩn hóa tổ chức cơ sở dữ liệu để giảm dư thừa bằng cách tách dữ liệu thành các bảng nhỏ, có liên quan. Phi chuẩn hóa thì ngược lại: chủ động đưa dư thừa vào để cải thiện hiệu năng đọc. Hầu hết cơ sở dữ liệu sản xuất bắt đầu ở trạng thái chuẩn hóa và phi chuẩn hóa có chọn lọc cho các khối lượng công việc truy vấn nặng như báo cáo và phân tích.
Dạng chuẩn nào được dùng phổ biến nhất trong thực tế?
Dạng chuẩn thứ ba (3NF) là mức chuẩn hóa được dùng rộng rãi nhất trong các cơ sở dữ liệu sản xuất. Nó loại bỏ dư thừa do phụ thuộc bộ phận và bắc cầu, đồng thời giữ cho lược đồ thực tiễn, dễ làm việc. Các dạng chuẩn cao hơn như BCNF, 4NF và 5NF ít dùng hơn và thường chỉ trong các kịch bản chuyên biệt với quan hệ dữ liệu phức tạp.
Chuyên gia dữ liệu và tác giả dày dạn kinh nghiệm, đam mê hỗ trợ những người đang theo đuổi con đường trở thành chuyên gia trong lĩnh vực dữ liệu.
