Chuẩn hóa cơ sở dữ liệu là một quá trình thiết kế được sử dụng để tổ chức một tập dữ liệu nhất định thành các bảng và cột trong cơ sở dữ liệu. Mỗi bảng phải chứa dữ liệu liên quan đến một “thứ” cụ thể và chỉ có dữ liệu metadata – “dây mơ rễ má” với “thứ” đó mới được cho vào trong bảng.
Mục tiêu của quá trình này là giảm dữ liệu trùng lặp có trong cơ sở dữ liệu của bạn đồng thời tối ưu hiệu suất khi cập nhật hoặc chèn vào chính cơ sở dữ liệu đó.
Ví dụ: Thay đổi địa chỉ khách hàng dễ thực hiện hơn nhiều nếu vị trí duy nhất của địa chỉ khách hàng được lưu duy nhất trong bảng “Khách hàng”. Các dạng chuẩn hóa phổ biến nhất là dạng chuẩn hóa thứ nhất, thứ hai và thứ ba. Cùng mình tìm hiểu từng loại he ❤️
Dạng chuẩn 1
Các tiêu chí của dạng chuẩn 1 gồm:
- Từng tập dữ liệu liên quan luôn thuộc về một bảng riêng biệt.
- Loại bỏ các nhóm lặp lại trong các bảng riêng lẻ và thường không chứa các cột được nội suy tính toán từ những cột khác
- Xác định khóa chính cho từng tập dữ liệu liên quan | Các bảng phải có khóa chính cho mình
Trong mô hình này, bạn không nên sử dụng nhiều cột trong một bảng để lưu trữ dữ liệu tương tự nhau.
Ví dụ: Nếu sản phẩm có thể có nhiều màu, bạn không nên có nhiều cột trong một hàng có chứa các giá trị màu khác nhau.
Bảng bên dưới về màu sản phẩm chưa đạt dạng chuẩn 1 vì có các giá trị lặp lại cho màu sắc. Đối với các sản phẩm chỉ có một màu, việc thiết kế này gây lãng phí. Rồi giờ nếu một sản phẩm có nhiều hơn ba màu thì nghe toang nhỉ, u là trời phải tạo bao nhiêu cột cho đủ cái bảng màu?
| ProductID | Color1 | Color2 | Color3 |
|---|---|---|---|
| 1 | Red | Green | Yellow |
| 2 | Yellow | ||
| 3 | Blue | Red | |
| 4 | Blue | ||
| 5 | Red |
Thay vì phải đặt số lượng màu tối đa, chúng ta có thể tạo lại bảng như trong bảng thứ hai, (ProductColor_2). Và vì để đạt Dạng chuẩn 1 thì cần phải có một khóa duy nhất cho bảng, đó là cột (hoặc các cột) có giá trị xác định duy nhất giữa dòng dữ liệu. Well, Không cột nào trong bảng thứ hai là duy nhất, nhưng cùng với nhau, sự kết hợp của ProductID và Color là duy nhất (Nghe như sức mạnh của tình bạn nhỉ 😂) Khi ghép nhiều cột lại thành một khóa chính thì cái khóa đó được gọi là khóa ghép (composite key).
| ProductID | Color |
|---|---|
| 1 | Red |
| 1 | Green |
| 1 | Yellow |
| 2 | Yellow |
| 3 | Blue |
| 3 | Red |
| 4 | Blue |
| 5 | Red |
Bảng thứ ba bên dưới, ProductInfo, đạt dạng chuẩn một vì mỗi hàng đề cập đến một sản phẩm cụ thể, không có nhóm lặp lại và nó có cột ProductID để sử dụng làm Khóa chính (Primary Key)
| ProductID | ProductName | Price | ProductionCountry | ShortLocation |
|---|---|---|---|---|
| 1 | Widget | 15.95 | United States | US |
| 2 | Foop | 41.95 | United Kingdom | UK |
| 3 | Glombit | 49.95 | United Kingdom | UK |
| 4 | Sorfin | 99.99 | Republic of the Philippines | RepPhil |
| 5 | Stem Bolt | 29.95 | United States | US |
Dạng chuẩn 2
Dạng chuẩn 2 có đặc điểm kỹ thuật sau, ngoài những yêu cầu của dạng chuẩn 1:
- Nếu bảng có khóa tổng hợp, tất cả các thuộc tính phải phụ thuộc vào toàn bộ thành phần tạo ra khóa đó chứ không chỉ một phần của nó.
Dạng chuẩn 2 chỉ liên quan đến các bảng có các khóa tổng hợp, như trong bảng ProductColor_2 ở trên. Hãy xem xét trường hợp bảng ProductColor_3 bên dưới thêm một cột giá của sản phẩm. Bảng này có khóa tổng hợp trên ProductID và Color, vì chỉ sử dụng cả hai giá trị cột mới có thể xác định tính duy nhất của dòng dữ liệu. Nhưng hãy cùng đánh giá lại bảng sau để thấy vấn đề nhé:
| ProductID | Color | Price |
|---|---|---|
| 1 | Red | 15.95 |
| 1 | Green | 15.95 |
| 1 | Yellow | 15.95 |
| 2 | Yellow | 41.95 |
| 3 | Blue | 49.95 |
| 3 | Red | 49.95 |
| 4 | Blue | 99.95 |
| 5 | Red | 29.95 |
Đố mọi người bảng trên có đạt chuẩn 2 không? 😁
Gợi ý
Trước khi trả lời hãy xem thử hen: Cột giá tiền đúng là nó có thay đổi đối với từng sản phẩm thật. NHƯNG nó chỉ thay đổi khi ProductID thay đổi giá trị Color có thay đổi thì nó cũng chả care.
Đáp án
Tới đây thì mọi người cũng thấy rõ nó chả đạt nổi dạng chuẩn 2 rùi
Vậy có vấn đề gì không khi không đạt được dạng chuẩn 2? 🤔Một ngày đẹp trời, bạn nhận được yêu cầu cập nhật giá cho sản phẩm có mã là 1:
Ta có ba hàng với ProductID = 1, vì vậy giá cho sản phẩm đó được lặp lại ba lần. Vấn đề nảy sinh khi cập nhật giá của sản phẩm mã 1 đó rõ ràng ta phải đảm bảo cập nhật nó ở mọi dòng liên quan nó. Nhưng Bùmm 💥 bạn nhận ra yêu cầu chỉ cung cấp xác nhận danh tính bằng mã thui mà ở đây có cả màu trong khóa chính để xác nhận danh tính nữa (Khóa chính là của dạng chuẩn 1 và ở đây ta mặc nhiên đã đạt được nó) – Cũng có thể nói theo cách khác là ta buộc phải xác định bằng cả 2 thuộc tính trong khóa thì mới cập nhật được!
Ủa vậy nó có ở 3 dòng luôn vậy thì mình làm seo? Cập nhật dòng đầu tiên thôi !? Nếu vậy ta sẽ rơi vào trường hợp có tên “update anomaly” (Cập nhật bất thường). Cập nhật đủ 3 dòng !? Ngon nhỉ, Lấy căn cứ dựa vào đâu mà bạn có quyền cập nhật toàn bộ khi mà bạn đang chơi “luật” của dạng chuẩn 1 😢
Giải pháp là tách bảng ra, di chuyển cột Price sang bảng khác cũng có ProductID làm khóa cột duy nhất, vì đó là cột duy nhất mà Giá phụ thuộc vào. Ví dụ ta có bảng ProductPrice
| ProductID | Price |
|---|---|
| 1 | 15.95 |
| 2 | 41.95 |
| 3 | 49.95 |
| 4 | 99.95 |
| 5 | 29.95 |
Bạn có bao giờ hỏi tại sao lại cần dạng chuẩn 2 chưa vì rõ ràng nó khá là … mập mờ ranh giới?
Là vậy nè: Hãy liên tưởng tới cuộc đời bạn, bạn nhận ra dù mình cố gắng như thế nào cũng chỉ được công nhận ngang hàng như nhau với mọi người xung quanh. Zời bạn nhận ra điều này quá bất công và bạn muốn có sự đảm bảo xác nhận chính xác phần thưởng của mình! Yes và đó là lý do tại sao cần dạng chuẩn 2 – Tính tường minh trong dữ liệu.
Có thể bạn chưa biết ❤️
Dạng chuẩn 3
Dạng chuẩn ba thường nhắm tới các cơ sở dữ liệu OLTP. Nó có đặc điểm kỹ thuật sau, (Tất nhiên nó phải đạt những yêu cầu của dạng chuẩn hai trước đã):
- Tất cả các cột không phải khóa không phụ thuộc bắt cầu vào khóa chính – Nói cách khác là các cột không phải khóa phải được suy ra trực tiếp từ khóa chính.
Mối quan hệ bắc cầu ngụ ý rằng một cột trong bảng có liên quan đến các cột khác, thông qua cột thứ hai. Sự phụ thuộc có nghĩa là một cột có thể lấy giá trị của nó từ một cột khác, là kết quả của một sự phụ thuộc.
Ví dụ, tuổi của bạn có thể được xác định từ ngày sinh của bạn, làm cho tuổi của bạn phụ thuộc vào ngày sinh của bạn. Tham khảo lại bảng dbo.ProductInfo. Bảng này ở dạng chuẩn hai, nhưng không ở dạng thứ ba. Cột ShortLocation phụ thuộc vào cột ProductionCountry, cột này không phải là khóa. Giống như dạng chuẩn hai, vi phạm dạng chuẩn ba có thể dẫn đến update anomalies – cập nhật bất thường. Ta sẽ nhận được dữ liệu không nhất quán nếu cập nhật ShortLocation trong một hàng nhưng không cập nhật nó trong tất cả các hàng nơi vị trí đó có mặt. Để tránh điều này, ta có thể tạo một bảng riêng để lưu tên quốc gia và các dạng rút gọn của chúng.

