Hôm nay tụi mình sẽ lại nói về chủ đề quan trọng này, nhưng chi tiết hơn: ưu điểm và nhược điểm của chuẩn hóa, để bạn hiểu rõ hơn cách mấy khái niệm này áp dụng ngoài đời thực ra sao. Ok, thắt dây an toàn đi — bắt đầu thôi!
Loại bỏ dữ liệu dư thừa
Khi dữ liệu trong bảng chưa được chuẩn hóa, bạn sẽ thấy cùng một thông tin bị lặp lại ở nhiều dòng khác nhau. Ví dụ, trong bảng đơn hàng có thể có địa chỉ khách hàng bị lặp lại cho mỗi đơn. Chuẩn hóa sẽ loại bỏ mấy cái lặp này bằng cách chuyển dữ liệu chung sang bảng riêng.
Ví dụ:
-- Trước khi chuẩn hóa
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
customer_name TEXT,
customer_address TEXT,
order_date DATE
);
-- Sau khi chuẩn hóa
CREATE TABLE customers (
customer_id SERIAL PRIMARY KEY,
customer_name TEXT,
customer_address TEXT
);
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
customer_id INT REFERENCES customers(customer_id),
order_date DATE
);
Tại sao cái này quan trọng? Dữ liệu bị lặp ít hơn nghĩa là ít lỗi hơn. Nếu địa chỉ khách thay đổi, bạn chỉ cần update ở một chỗ duy nhất thôi.
Đảm bảo tính toàn vẹn dữ liệu
Khi dữ liệu được chia thành các bảng logic, việc quản lý mối quan hệ giữa chúng sẽ dễ hơn. Dùng foreign key giúp tự động giữ cho dữ liệu luôn nhất quán. Ví dụ, bạn sẽ không thể xóa nhầm khách hàng mà vẫn còn đơn hàng liên quan trong bảng orders.
Ví dụ:
-- Foreign key đảm bảo xóa khách sẽ xóa luôn các đơn liên quan
ALTER TABLE orders
ADD CONSTRAINT fk_customer FOREIGN KEY (customer_id)
REFERENCES customers(customer_id)
ON DELETE CASCADE;
Bạn có thể yên tâm là cấu trúc database sẽ không cho phép xuất hiện dữ liệu "mồ côi".
Dễ dàng cập nhật
Khi database của bạn đã chuẩn hóa, việc update sẽ dễ dàng và ít lỗi hơn. Quay lại ví dụ khách hàng — nếu khách đổi địa chỉ, bạn chỉ cần update ở một bảng. Nếu bảng chưa chuẩn hóa, rất dễ quên update ở vài dòng, dẫn đến dữ liệu không đồng nhất.
Giảm thiểu anomaly
Anomaly khi insert: với bảng chưa chuẩn hóa, bạn có thể gặp trường hợp không thể thêm dòng mới nếu thiếu thông tin. Ví dụ, không thể thêm đơn hàng nếu chưa biết tên khách.
Anomaly khi update: có thể xảy ra lỗi khi cập nhật dữ liệu. Ví dụ, đổi tên khách ở một dòng nhưng dòng khác vẫn tên cũ.
Anomaly khi xóa: xóa một dòng có thể làm mất thông tin quan trọng. Ví dụ, xóa đơn hàng cũng xóa luôn tên khách nếu hai dữ liệu này nằm chung một bảng.
Giảm dung lượng dữ liệu
Chuẩn hóa thường làm database nhỏ lại vì loại bỏ dữ liệu lặp. Đây là điểm quan trọng khi lưu trữ lượng lớn thông tin.
Nhược điểm của chuẩn hóa
1. Cấu trúc database phức tạp
Lâu dần, chuẩn hóa có thể làm cấu trúc database trở nên phức tạp, có thể lên tới hàng ngàn(!) bảng liên kết. Khi đó, để lấy dữ liệu mà trước đây chỉ nằm trong một bảng, bạn phải viết SQL query phức tạp với nhiều JOIN.
Ví dụ phức tạp:
-- Query lấy thông tin đơn hàng kèm chi tiết sản phẩm và category
SELECT
o.order_id,
o.order_date,
c.customer_name,
p.product_name,
cat.category_name,
oi.quantity,
oi.unit_price
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
JOIN order_items oi ON o.order_id = oi.order_id
JOIN products p ON oi.product_id = p.product_id
JOIN categories cat ON p.category_id = cat.category_id;
Nếu số lượng bảng và mối liên kết tăng lên, thời gian chạy query có thể tăng đáng kể.
2. Giảm hiệu năng khi JOIN nhiều
JOIN bảng thường tốn tài nguyên, nhất là khi bảng lớn và không có index. Trong hệ thống phân tích, nơi query phải xử lý hàng triệu dòng, chuẩn hóa sẽ làm hiệu năng giảm rõ rệt.
3. Cần thao tác thêm để denormalize
Nếu cấu trúc database chuẩn hóa dùng cho mục đích phân tích, đôi khi phải tạm thời denormalize để tăng tốc query phân tích. Việc này có thể bao gồm tạo VIEW hoặc bảng tổng hợp dữ liệu.
Ví dụ:
-- VIEW denormalize cho phân tích
CREATE VIEW orders_with_customers AS
SELECT
o.order_id,
o.order_date,
c.customer_name,
c.customer_address
FROM
orders o
JOIN
customers c ON o.customer_id = c.customer_id;
4. Khó tiếp cận cho người mới
Với người mới, chuẩn hóa có thể khá khó hiểu. Thay vì một bảng chứa hết dữ liệu, bạn phải làm việc với nhiều bảng và hiểu mối liên hệ giữa chúng. Điều này có thể làm chậm tiến độ phát triển, nhất là khi team chưa rành về database.
5. Đôi khi dư thừa lại có lợi
Trong dự án thực tế, đôi khi giữ lại dữ liệu dư thừa lại giúp tăng hiệu năng. Ví dụ, nếu app thường xuyên dùng dữ liệu chỉ lấy được qua JOIN phức tạp, thì tốt hơn nên lưu nó chung một bảng.
GO TO FULL VERSION