Mô hình chưa chuẩn hóa bằng mô hình chuẩn hóa năm 2024
Chuẩn hóa là quá trình phân rã lược đồ quan hệ dựa trên một tập phụ thuộc hàm nhằm đảm các lược đồ quan hệ thoả mãn 2 tính chất: Show
Để trình bày các qui tắc chính trong quá trình chuẩn hóa, tôi dựa theo ví dụ cổ điển về Hóa đơn (Invoice) và chuẩn hóa nó về dạng 3NF (Third Normal Form). Trong quá trình đó, chúng ta sẽ hình thành Sơ đồ liên kết thực thể (Entity Relationship Diagram - ERD) cho cơ sở dữ liệu. Để bắt đầu: Trước tiên, xin nhớ nằm lòng 3 qui tắc sau về các dạng chuẩn như sau:
Bài toán: Quản lí Hóa đơnAi đó chưa biết về CSDL quan hệ có thể đưa các thông tin đó vào spreadsheet trong Excel như sau: Hình A-1: Bảng hóa đơn Điều gì xảy ra nếu ta muốn lấy các thông tin phức tạp như: • Có bao nhiêu 3" Red Freens mà Freens R Us đặt trong năm 2002? • Tổng số 56" Blue Freens được bán ở Texas? • Những sản phẩm nào được bán vào ngày 14 tháng 7 năm 2003? Chúng ta đang bắt đầu việc chuẩn hóa CSDL (normalization). 1. Dạng chuẩn thứ 1 (1NF): Không có phần tử/nhóm phần tử lặpNhìn vào hàng 2, 3, 4 của bảng trong Hình A-1, ta thấy tất cả các dữ liệu liên quan đến một hóa đơn (Invoice 125). Theo thuật ngữ CSDL, nhóm các hàng này được gọi là một hàng đơn CSDL (a single database row). Một hàng đơn CSDL ở đây được tạo bởi ba hàng trong bảng ở Hình A-1.Dạng chuẩn 1NF muốn chúng ta triệt tiêu các phần tử lặp. Chúng là các phần tử nào? Một lần nữa, để ý hóa đơn đầu tiên ( 125) trong Hình A-1. Ô H2, H3, và H4 chứa một danh sách các số Item ID. Đây là một cột trong hàng CSDL đầu tiên của chúng ta. Tương tự, I2-I4 hình thành một cột khác; tương tự với J2-J4, K2-K4, L2-L4, và M2-M4. Các cột trong CSDL thường được gọi là thuộc tính (attributes) (hàng/cột có cách gọi khác là bộ/thuộc tính). Để ý thấy các cột này chứa danh sách các giá trị. Rõ ràng là các danh sách như thế vi phạm luật chuẩn 1NF: 1NF không cho phép danh sách hay chuỗi giá trị như vậy tồn tại trong một cột CSDL. 1NF đòi hỏi tính nguyên tố - tức là sự không thể phân chia một thuộc tính thành các phần nhỏ hơn. Vì thế chúng ta cần phải loại bỏ sự lặp lại thông tin về item trong hàng giành cho Hóa đơn125. Trong Hình A-1, đó là các ô sau: • Từ H2 đến M2 • Từ H3 đến M3 • Từ H4 đến M4 Tương tự, chúng ta cũng thấy hiện tượng trùng lặp dữ liệu trong hàng giành cho Hóa đơn126. Chúng ta có thể chuẩn hóa sang dạng 1NF để đạt được tính nguyên tố một cách dễ dàng như sau – cho mỗi item một hàng riêng biệt (thường gọi là cách làm phẳng).Hình A-2: làm phẳng bảng dữ liệu Đến đây chúng ta mới chỉ đi được một nửa chặng đường để đạt được dạng chuẩn 1NF. Dạng chuẩn 1NF giải quyết 2 vấn đề:
Chúng ta đã giải quyết xong tính nguyên tố. Để giải quyết vấn đề Khóa Chinh, chúng ta cần phải chuyển toàn bộ dữ liệu sang một hệ quản trị CSDL quan hệ (RDBMS). Ở đây, dùng Microsoft Access để tạo bảng orders như Hình B: Hình B: Bảng orders Như nhìn thấy trong hình B, không có một cột đơn nào có thể dùng để xác định duy nhất các hàng. Tuy nhiên, nếu chúng ta kết hợp 2 cột order_id và item_id thì được: không có hai hàng nào có giá trị order_id và item_id giống nhau. Vì thế, kế hợp hai cột đó với nhau, chúng ta có khóa chính của bảng Orders. Chúng ta gọi hai cột đó là khóa gộp (concatened key). Một giá trị, giúp xác định duy nhất một hàng gọi là khóa chính. Khi giá trị đó được tạo bởi hơn một cột thì ta gọi chúng là concatenated primary key. Cấu trúc của bảng Order có thể được biểu diễn trong Hình C ở dưới: 2.1 Dạng chuẩn thứ 2 (2NF): Không có phụ thuộc hàm không đầy đủ vào khóa chính.Bây giờ, chúng ta tìm các phụ thuộc hàm không đầy đủ vào khóa chính để loại bỏ chúng. Với các bảng có khóa chính được tạo bởi hơn một thuộc tính, các thuộc tính không nằm trong khóa chính phải phụ thuộc hàm đầy đủ vào khóa chính mà không được phép tồn tại các thuộc tính chỉ phụ thuộc vào một phần của khóa chính. Nếu có thuộc tính nào chỉ phụ thuộc một phần vào khóa chính thì bảng đó chưa đạt dạng chuẩn 2NF. Để hiểu rõ, chúng ta xem xét từng thuộc tính của bảng Orders. Với mỗi thuộc tính, chúng ta sẽ đặt câu hỏi: Liệu thuộc tính này có thể tồn tại mà không cần một hay nhiều thuộc tính nào đó nằm trong khóa chính không? Nếu câu trả lời là “có” – dù chỉ một – thì bảng chưa đạt chuẩn 2NF. Xem lại Hình C ở bên để nhớ lại cấu trúc bảng. Đầu tiên, nhắc lại ý nghĩa của hai thuộc tính làm nên khóa chính:
Do đó, bảng Orders không đạt 2NF. Bây giờ hãy xem xét các thuộc tính còn lại. Chúngta cần tìm tất cả các thuộc tính không thỏa mãn 2NF để xử lí. customer_id là số ID của khách hàng. Nó có phụ thuộc vào order_id? Không: một khách hàng có thể tồn tại mà không cần mua hàng. Nó có phụ thuộc vào item_id? Không: với cùng lí do. Đây là một điều thú vị: customer_id (cùng với các thuộc tính customer khác) không phụ thuộc vào customerid lẫn orderid, tức là không phụ thuộc vào bất cứ thuộc tính nào của khóa chính). Chúng ta sẽ làm gì với chúng? Chúng ta chỉ quan tâm tới chúng khi xem xét dạng chuẩn 3NF. Bây giờ chúng ta đánh dấu chúng là “không rõ ràng” (unknown). ? item_description là miêu tả về hàng hóa. Rõ rang là nó phụ thuộc vào item_id. Nhưng nó có thể tồn tại mà không cần orderid? Có! Một item có thể tổn tại trong kho mãi mãi, mà không bao giờ được bán. Nó độc lập với hóa đơn. Như vậy, item_descriptionkhông thỏa điều kiện của 2NF. item_qty là số lượng một mặt hàng được yêu cầu trong một hóa đơn. Rõ rang thuộc tính này phụ thuộc vào cả hai thuộc tính của khóa chính. Số lượng một hàng hóa được yêu cầu trong một hóa đơn không thể tồn tại không có hóa đơn. Như vậy thuộc tính này thỏa mãn 2NF. item_price tương tự như item_description. Nó chỉ phụ thuộc vào item_id mà không phụ thuộc vào order_id, nên nó không thỏa mãn 2NF. item_total_price hơi đặc biệt.
Chúng ta sẽ làm gì với một bảng không thỏa mãn 2NF như thế? Trước tiên, lấy ra nửa sau của khóa chính (item_id) và đưa nó vào một bảng khác. Các thuộc tính khác phụ thuộc vào item_id – đầy đủ hoặc không đầy đủ - cũng đưa luôn vào bảng mới này. Chúng ta sẽ gọi bảng mới này là order_items (xem Hình D). Các thuộc tính còn lại – gồm các thuộc tính chỉ phụ thuộc vào nửa đầu của khóa chính(order_id) và các thuộc tính chưa xác định – giữ nguyên. Hình D: Bảng orders và bảng mới: order_items Có một vài điểm cần chú ý:
Sau đây là cấu trúc các bảng (Hình E): Hình E: Cầu trúc bảng orders và order_items table **• Mỗi order có thể có một hoặc nhiều order-item, nhưng phải có ít nhất một; • Mỗi order-item có thể thuộc về một và chỉ một order 2.2 Dạng chuẩn thứ 2 (2NF): Pha thứ IIDạng chuẩn 2NF áp dụng cho các bảng có khóa chính hợp thành bởi hơn một thuộc tính. Bây giờ bảng orders có khóa chính là khóa đơn, bảng này đã dạt dạng chuẩn 2NF. Tuy nhiên, bây giờ, bảng order_items lại có khóa chính tạo bởi hai thuộc tính. Chúng ta lại phải phân tích xem nó đã đạt 2NF chưa. Chúng ta lại làm theo cách cũ, với mỗi thuộc tính, đặt ra câu hỏi: Liệu thuộc tính này có thể tồn tại mà không cần một hay nhiều thuộc tính nào đó nằm trong khóa chính không? Biểu diễn cấu trúc của bảng order_items. Bây giờ chúng ta lần lượt xem xét các thuộc tính không khóa. item_description phụ thuộc vào item_id, nhưng không phụ thuộc vào order_id. Do đó, thuộc tính này không đạt chuẩn 2NF. item_qty phụ thuộc vào cả hai thuộc tính của khóa chính nên thuộc tính này thỏa mãn chuẩn 2NF. item_price chỉ phụ thuộc vào item_id mà không phụ thuộc vào order_id, nên nó vi phạm điều kiện của chuẩn 2NF. Chúng ta có bảng phân tích như sau: Bây giờ, chúng ta lấy ra các thuộc tính không thỏa mãn điều kiện của chuẩn 2NF và đưa vào một bảng mới. Chúng ta gọi bảng mới này là bảng items: Hình G: Bảng order_items và bảng items Lần này, item_id không được đưa ra khỏi bảng order_items là do quan hệ nhiều-một giữa order-items và items. Do đó, vì item_qty không vi phạm chuẩn 2NF nên nó được giữ lại bảng có khóa chính gồm hai thuộc tính. Để hiểu rõ hơn, có thể xem ERD mới: Đường nối giữa bảng items và bảng order_items nghĩa là:
3. Dạng chuẩn thứ 3 (3NF): Không có phụ thuộc hàm vào thuộc tính không khóa.Với CSDL hiện tại, nếu một khách hàng có hơn một order, chúng ta sẽ phải nhập thông tin về khách hàng đó nhiều lần. Xảy ra hiện tượng này là do trong bảng order có tồn tại các thuộc tính phụ thuộc vào một thuộc tính không khóa. Để hiểu rõ hơn khái niệm này, xem xét thuộc tính order_date. Nó có thể tồn tại độc lập với thuộc tính order_id? Không: một "order date" sẽ là vô nghĩa nếu không có order. Khi đó, order_date được gọi là phụ thuộc vào thuộc tính khóa (vì order_id là một thuộc tính khóa). Còn thuộc tính customer_name có thể tồn tại một mình bên ngoài bảng orders. Có nghĩa khi nói về một khách hàng mà không đề cập tới yêu cầu mua hàng hay hóa đơn. Tương tự với các thuộc tính customer_address, customer_city, và customer_state. Bốn thuộc tính này chỉ phụ thuộc vào customer_id – một thuộc tính không khóa. Các trường này sẽ thuộc về một bảng khác, của riêng chúng, với customer_id làm khóa chính (xem Hình I). Hình I: Trong Hình I, chúng ta đã cắt đứt mối quan hệ giữa bảng Orders với các thông tin về khách hàng. Do vậy, chúng ta phải khôi phục mối quan hệ bằng cách tạo ra một khóa ngoại (Foreign key - FK) trong bảng Orders. Khóa ngoại về bản chất là một thuộc tính trỏ tới khóa chính của một bảng khác. Hình J là ERD hoàn thiện của chúng ta: Hình J: ERD hoàn chỉnh Quan hệ giữa orders và customers có thể được diễn giải như sau:
Tham khảo Website: http://www.phlonx.com/resources/nf3/ Sau đây là một số tài liệu tham khảo hữu ích: • The Art of Analysis, by Dr. Art Langer, devotes considerable space to normalization. Springer-Verlag Telos (January 15, 1997) ISBN: 0387949720 • Báo cáo khoa học năm 1969 của Dr. Codd's về chuẩn hóa CSDL: www.acm.org/classics/nov95 • The Wikipedia article on normalization bàn về 5 dạng chuẩn hóa: en.wikipedia.org/wiki/Database_normalization |