1. Database Normalization là gì?
Database Normalization (chuẩn hóa cơ sở dữ liệu) là quá trình tổ chức dữ liệu thành các bảng và thiết lập mối quan hệ phù hợp nhằm hạn chế dữ liệu trùng lặp không cần thiết, đồng thời giảm các vấn đề có thể xảy ra khi thêm, sửa hoặc xóa dữ liệu.
Trong một hệ thống Backend, dữ liệu thường liên quan đến nhiều thực thể như người dùng, sản phẩm, đơn hàng và danh mục. Nếu tất cả thông tin được lưu trong một bảng lớn, dữ liệu có thể bị lặp lại nhiều lần và trở nên khó quản lý.
Ví dụ, một bảng lưu đơn hàng có thể chứa các cột:
| order_id | customer_name | product_name | quantity |
|---|---|---|---|
| 1001 | An | Keyboard | 1 |
| 1001 | An | Mouse | 2 |
| 1002 | Bình | Keyboard | 1 |
Trong bảng trên, tên khách hàng An được lặp lại khi đơn hàng có nhiều sản phẩm. Tên sản phẩm Keyboard cũng xuất hiện nhiều lần.
Nếu tên sản phẩm thay đổi, hệ thống có thể phải cập nhật nhiều bản ghi. Nếu không cập nhật đầy đủ, dữ liệu sẽ không nhất quán.
Chuẩn hóa giúp tổ chức dữ liệu theo các thực thể và mối quan hệ phù hợp hơn.
2. Các vấn đề mà Normalization giải quyết
2.1. Data Redundancy — Dữ liệu trùng lặp
Dữ liệu trùng lặp xảy ra khi cùng một thông tin được lưu ở nhiều vị trí không cần thiết.
Ví dụ, nếu tên sản phẩm được lưu trong từng dòng đơn hàng, một sản phẩm xuất hiện trong nhiều đơn hàng sẽ khiến tên sản phẩm bị lặp lại.
Điều này làm tăng lượng dữ liệu cần quản lý và có thể khiến các bản ghi không đồng nhất.
2.2. Update Anomaly — Bất thường khi cập nhật
Update Anomaly xảy ra khi một thông tin được lưu ở nhiều vị trí và việc cập nhật không được thực hiện đồng bộ.
Ví dụ, tên sản phẩm Keyboard được lưu trong 100 dòng đơn hàng. Khi đổi tên sản phẩm, nếu chỉ sửa 99 dòng, dữ liệu sẽ tồn tại hai tên khác nhau cho cùng một sản phẩm.
2.3. Insertion Anomaly — Bất thường khi thêm dữ liệu
Insertion Anomaly xảy ra khi cấu trúc bảng khiến việc thêm một loại thông tin trở nên khó khăn hoặc buộc phải thêm những thông tin không cần thiết.
Ví dụ, nếu thông tin sản phẩm chỉ được lưu trong bảng đơn hàng, hệ thống có thể gặp khó khăn khi muốn thêm sản phẩm mới nhưng chưa có đơn hàng nào chứa sản phẩm đó.
2.4. Deletion Anomaly — Bất thường khi xóa dữ liệu
Deletion Anomaly xảy ra khi xóa một bản ghi làm mất luôn thông tin khác mà hệ thống vẫn cần giữ lại.
Ví dụ, nếu thông tin sản phẩm chỉ tồn tại trong các dòng đơn hàng, việc xóa dòng cuối cùng chứa sản phẩm đó có thể làm mất thông tin sản phẩm khỏi database.
Các bất thường trên là những lý do quan trọng khiến việc chuẩn hóa dữ liệu trở nên cần thiết.
3. First Normal Form (1NF) — Dạng chuẩn thứ nhất
Một bảng đạt First Normal Form (1NF) khi mỗi ô chứa một giá trị đơn lẻ theo mô hình dữ liệu đã chọn, thay vì lưu một danh sách các giá trị trong cùng một ô.
Xét bảng chưa đạt 1NF:
| order_id | product_names |
|---|---|
| 1001 | Keyboard, Mouse |
| 1002 | Keyboard, Monitor |
Cột product_names chứa nhiều sản phẩm trong cùng một ô. Điều này khiến việc tìm kiếm, cập nhật hoặc thống kê từng sản phẩm trở nên khó khăn.
Có thể chuyển dữ liệu thành:
| order_id | product_name |
|---|---|
| 1001 | Keyboard |
| 1001 | Mouse |
| 1002 | Keyboard |
| 1002 | Monitor |
Mỗi ô product_name giờ chỉ chứa một giá trị sản phẩm.
Ý nghĩa của 1NF: dữ liệu được tổ chức thành các giá trị riêng biệt, giúp việc truy vấn và xử lý từng giá trị dễ dàng hơn.
Lưu ý, 1NF không có nghĩa là mọi giá trị phải là một chuỗi đơn giản hoặc không được chứa dấu phẩy. Điều quan trọng là mỗi cột lưu một giá trị theo ý nghĩa dữ liệu của nó, thay vì gộp nhiều phần tử cần quản lý riêng thành một danh sách.
4. Second Normal Form (2NF) — Dạng chuẩn thứ hai
Một bảng đạt Second Normal Form (2NF) khi đã đạt 1NF và mọi thuộc tính không thuộc khóa đều phụ thuộc đầy đủ vào toàn bộ khóa ứng viên, không chỉ phụ thuộc vào một phần của khóa ghép.
Để hiểu điều này, xét bảng order_items:
| order_id | product_id | product_name | quantity |
|---|---|---|---|
| 1001 | 101 | Keyboard | 1 |
| 1001 | 102 | Mouse | 2 |
| 1002 | 101 | Keyboard | 1 |
Giả sử khóa chính của bảng là khóa ghép (order_id, product_id).
Trong bảng này:
quantityphụ thuộc vào cả đơn hàng và sản phẩm trong đơn hàng.product_namechỉ phụ thuộc vàoproduct_id, không phụ thuộc vào toàn bộ khóa ghép.
Đây là phụ thuộc một phần (Partial Dependency), khiến bảng không đạt 2NF.
Ta có thể tách bảng thành hai bảng.
Bảng products
| product_id | product_name |
|---|---|
| 101 | Keyboard |
| 102 | Mouse |
Bảng order_items
| order_id | product_id | quantity |
|---|---|---|
| 1001 | 101 | 1 |
| 1001 | 102 | 2 |
| 1002 | 101 | 1 |
Sau khi tách:
- Thông tin tên sản phẩm được quản lý trong
products. - Bảng
order_itemslưu sản phẩm nào thuộc đơn hàng nào và số lượng tương ứng.
Ý nghĩa của 2NF: loại bỏ sự phụ thuộc của thuộc tính không thuộc khóa vào chỉ một phần của khóa ghép.
Nếu bảng chỉ có các khóa ứng viên gồm một cột, bảng đã đạt 1NF thì không có phụ thuộc một phần vào khóa ghép; vì vậy, 2NF thường được quan tâm nhiều hơn khi thiết kế bảng có khóa ghép.
5. Third Normal Form (3NF) — Dạng chuẩn thứ ba
Một bảng đạt Third Normal Form (3NF) khi đã đạt 2NF và không có phụ thuộc bắc cầu không phù hợp từ khóa đến thuộc tính không thuộc khóa.
Xét bảng customers:
| customer_id | customer_name | city_id | city_name |
|---|---|---|---|
| 1 | An | 10 | Ho Chi Minh City |
| 2 | Bình | 20 | Da Nang |
| 3 | Chi | 10 | Ho Chi Minh City |
Giả sử:
customer_idxác định duy nhất một khách hàng.- Mỗi khách hàng có một
city_id. city_idxác địnhcity_name.
Khi đó, city_name phụ thuộc vào customer_id thông qua city_id. Đây là phụ thuộc bắc cầu.
Nếu tên thành phố thay đổi, nhiều bản ghi khách hàng có thể cần được cập nhật.
Ta có thể tách thành hai bảng.
Bảng customers
| customer_id | customer_name | city_id |
|---|---|---|
| 1 | An | 10 |
| 2 | Bình | 20 |
| 3 | Chi | 10 |
Bảng cities
| city_id | city_name |
|---|---|
| 10 | Ho Chi Minh City |
| 20 | Da Nang |
Bảng customers chỉ lưu city_id, còn tên thành phố được quản lý tại bảng cities.
Ý nghĩa của 3NF: tránh lưu thuộc tính mô tả một thực thể khác theo cách tạo ra phụ thuộc bắc cầu không phù hợp, từ đó giảm trùng lặp và các bất thường dữ liệu.
Theo định nghĩa hình thức, với mọi phụ thuộc hàm không tầm thường (X \to A), bảng đạt 3NF nếu (X) là siêu khóa hoặc (A) là thuộc tính khóa. Vì vậy, không phải mọi phụ thuộc bắc cầu đều tự động vi phạm 3NF; cần xét các khóa và phụ thuộc hàm thực tế.
6. Denormalization — Phi chuẩn hóa
Denormalization là việc chủ động đưa dữ liệu trùng lặp hoặc dữ liệu đã tổng hợp vào thiết kế database để phục vụ một nhu cầu cụ thể, thường nhằm giảm chi phí truy vấn hoặc đơn giản hóa việc đọc dữ liệu.
Denormalization không đơn giản là thiết kế database sai chuẩn. Đây có thể là một quyết định có chủ đích khi đã hiểu rõ các đánh đổi.
Ví dụ, với thiết kế chuẩn hóa, để lấy tên khách hàng cùng thông tin đơn hàng, ứng dụng có thể cần JOIN:
SELECT
orders.id,
customers.customer_name,
orders.total
FROM orders
JOIN customers
ON orders.customer_id = customers.customer_id;
Trong một số hệ thống, người ta có thể lưu thêm customer_name vào bảng orders để phục vụ việc hiển thị thông tin đơn hàng mà không cần JOIN với bảng khách hàng trong mỗi truy vấn.
| order_id | customer_id | customer_name |
|---|---|---|
| 1001 | 1 | An |
| 1002 | 2 | Bình |
Tuy nhiên, cần phân biệt hai trường hợp:
- Nếu
customer_nameđược lưu để phản ánh tên hiện tại của khách hàng, dữ liệu có thể trở nên không đồng nhất khi tên khách hàng thay đổi. - Nếu
customer_nameđược lưu để ghi nhận tên tại thời điểm đặt hàng, đây có thể là một yêu cầu nghiệp vụ hợp lý nhằm bảo tồn lịch sử đơn hàng.
Denormalization có thể hữu ích trong các hệ thống có nhiều truy vấn đọc, báo cáo hoặc dữ liệu tổng hợp. Tuy nhiên, nó cũng làm tăng dung lượng lưu trữ và độ phức tạp khi cập nhật dữ liệu.
Không nên phi chuẩn hóa chỉ vì nghĩ rằng ít JOIN hơn luôn đồng nghĩa với hiệu năng tốt hơn. Quyết định này nên dựa trên cách ứng dụng sử dụng dữ liệu và kết quả đo hiệu năng thực tế.
7. So sánh Normalization và Denormalization
| Tiêu chí | Normalization | Denormalization |
|---|---|---|
| Mục tiêu chính | Tổ chức dữ liệu và giảm trùng lặp không cần thiết | Phục vụ nhu cầu truy vấn cụ thể |
| Cách tổ chức | Tách dữ liệu thành các bảng có quan hệ phù hợp | Có thể lưu trùng lặp hoặc dữ liệu tổng hợp |
| Truy vấn | Có thể cần JOIN giữa nhiều bảng | Một số truy vấn có thể ít JOIN hơn |
| Cập nhật | Thường dễ duy trì một nguồn dữ liệu chính xác cho mỗi thuộc tính | Có thể cần đồng bộ các bản sao dữ liệu |
| Trường hợp sử dụng | Thiết kế dữ liệu nghiệp vụ thông thường | Báo cáo, dữ liệu tổng hợp hoặc tối ưu đã được đánh giá |
Normalization và Denormalization không nhất thiết loại trừ nhau. Một hệ thống có thể sử dụng thiết kế chuẩn hóa làm nền tảng và phi chuẩn hóa một số phần khi có nhu cầu cụ thể.
8. Database Normalization trong Backend
Khi xây dựng Backend bằng Go + Gin và PostgreSQL/MySQL, thiết kế database ảnh hưởng trực tiếp đến cách ứng dụng lưu và truy vấn dữ liệu.
Một kiến trúc phân lớp phổ biến:
Client
|
v
Handler
|
v
Service
|
v
Repository
|
v
Database
- Handler: nhận HTTP request và trả HTTP response.
- Service: xử lý các quy tắc nghiệp vụ.
- Repository: thực hiện các truy vấn và thao tác dữ liệu.
- Database: lưu dữ liệu và thực thi các ràng buộc được khai báo.
Normalization giúp tổ chức dữ liệu sao cho thông tin về người dùng, sản phẩm và đơn hàng được lưu tại những nơi phù hợp. Nhờ đó, Repository có thể truy vấn các bảng thông qua khóa và quan hệ đã thiết kế.
Ví dụ, thay vì lưu toàn bộ tên khách hàng và thông tin sản phẩm lặp lại trong mỗi dòng đơn hàng, hệ thống có thể sử dụng các bảng customers, products, orders và order_items.
Tuy nhiên, Normalization không thay thế việc kiểm tra nghiệp vụ trong Service, cũng không tự động bảo đảm mọi dữ liệu đều hợp lệ. Thiết kế database và logic Backend cần phối hợp với nhau để đáp ứng yêu cầu của ứng dụng.
9. Kết luận
Database Normalization là một phương pháp quan trọng để tổ chức dữ liệu có cấu trúc, giảm trùng lặp và hạn chế các bất thường khi thêm, sửa hoặc xóa dữ liệu.
- 1NF: tổ chức dữ liệu thành các giá trị đơn lẻ theo mô hình đã chọn.
- 2NF: loại bỏ phụ thuộc một phần vào khóa ghép.
- 3NF: loại bỏ các phụ thuộc bắc cầu không phù hợp theo định nghĩa chuẩn hóa.
- Denormalization: chủ động lưu dữ liệu trùng lặp hoặc tổng hợp khi có lý do cụ thể.
Đối với Backend Developer, hiểu Normalization giúp thiết kế database phù hợp với dữ liệu nghiệp vụ. Hiểu Denormalization giúp nhận biết khi nào có thể đánh đổi giữa sự đơn giản trong quản lý dữ liệu và nhu cầu truy vấn của hệ thống.








Khoá học lập trình game con rắn cho trẻ em




