Khái Niệm
- Thiết kế database là một quá trình phức tạp bao gồm nhiều bước từ việc xác định yêu cầu đến xây dựng cơ sở dữ liệu vật lý. Sơ lược về quy trình thiết kế database có thể tóm gọn như sau:
- Phân tích yêu cầu (Requirement Analysis): Thu thập và phân tích yêu cầu người dùng.
- Mô hình hóa dữ liệu (Data Modeling): Tạo mô hình thực thể - mối quan hệ (ERD) để biểu diễn các thực thể (entities), thuộc tính (attributes), và mối quan hệ (relationships), xác định khóa chính (primary key) và thuộc tính phụ.
- Thiết kế logic (Logical Design): Chuyển mô hình ERD thành mô hình quan hệ(relational model) và chuẩn hóa(1NF, 2NF, 3NF, BCNF…) để loại bỏ dư thừa dữ liệu và tăng cường tính toàn vẹn.
- Thiết kế vật lý (Physical Design): Thiết kế table, primary key, constraint key, index.. và cấu trúc lưu trữ.
- Triển khai (Implementation): Tạo database và testing data.
- Tối ưu hóa và bảo trì (Optimization & Maintenance): Tối ưu hiệu suất, sao lưu và bảo trì.
- Tài liệu hóa (Documentation): Ghi lại thiết kế và hướng dẫn sử dụng.
- Bài này chỉ bàn về chuẩn hóa(1NF, 2NF, 3NF, BCNF…) trong thiết kế database.
- Chuẩn hóa cơ sở dữ liệu (Database Normalization) là quá trình biểu diễn dữ liệu theo các tiêu chuẩn nhất định, nhằm loại bỏ dữ liệu trùng lặp, tối ưu hóa lưu trữ và đảm bảo tính nhất quán, độ tin cậy của dữ liệu. Khái niệm Database Normalization do 2 ông Computer Scientist Edgar F. Codd người Anh và Raymond F. Boyce người Mỹ đề xuất, như 1 phần của Database Relationship.
- Có các loại chuẩn hóa được sắp xếp từ thấp đến cao: 1NF, 2NF, 3NF, BCNF, 4NF, 5NF, 6NF. Để chuẩn hóa 2NF thì cơ sở dữ liệu của chúng ta phải đạt chuẩn 1NF, tương tự nếu muốn đạt chuẩn 3NF thì phải đạt chuẩn 1 NF và 2 NF. Chuẩn BCNF sẽ bao gồm 3 loại chuẩn là 1NF, 2NF và 3NF...
Các loại chuẩn hóa trong DBMS và ví dụ đi kèm
Dạng chuẩn 1NF - (First Normal Form)
Mỗi column table chứa 1 giá trị, mỗi row record là duy nhất không trùng nhau
StudentID StudentName Courses
1 John Smith Math, Science, History
2 Jane Doe English, Math
3 Emily Clark History, Art - Vấn đề là column Course đang chứa nhiều giá trị trong cùng 1 ô, chuẩn phải là: StudentID StudentName Course
1 John Smith Math
1 John Smith Science
1 John Smith History
2 Jane Doe English
2 Jane Doe Math
3 Emily Clark History
3 Emily Clark Art
Dạng chuẩn 2NF (Second Normal Form)
loại bỏ sự phụ thuộc từng phần vào primary key khi primary key là composite key. Mọi thuộc tính phải phụ thuộc hoàn toàn vào primary key(Loại bỏ sự phụ thuộc từng phần)
OrderID ProductID ProductName Quantity Price
1 101 Laptop 2 1500
1 102 Mouse 1 20
2 101 Laptop 1 1500
3 103 Keyboard 1 50 - Table này có primary key là OrderID&ProductID(composite key), vấn đề là thuộc tính ProductName chỉ phụ thuộc vào ProductID không phụ thuộc vào cả OrderID và ProductID. chuẩn phải là: OrderID ProductID Quantity
1 101 2
1 102 1
2 101 1
3 103 1
Dạng chuẩn 3NF (Third Normal Form)
Mọi thuộc tính không khóa(non-key attribute) phải phụ thuộc trực tiếp vào primary key và không phụ thuộc vào các thuộc tính không khóa khác.
StudentID StudentName ClassID ClassName 1 John Smith 101 Math 2 Jane Doe 101 Math 3 Emily Clark 102 History - Table này có StudentID(primary key) và ClassID(foreign key), vấn đề là ClassName không phụ thuộc trực tiếp vào StudentID, chuẩn phải là: StudentID StudentName ClassID
1 John Smith 101
2 Jane Doe 101
3 Emily Clark 102
Dạng chuẩn BCNF (Boyce-Codd Normal Form)
Chỉ có key (hoặc composite key) mới có thể xác định các thông tin khác, chứ không phải ngược lại.
Teacher Subjects
Nga Toán
Thu Văn - Trong table này mỗi Teacher chỉ dạy một Subjects duy nhất, nên chỉ cần biết tên Teacher là có thể xác định được Subjects mà họ dạy. Vấn đề là "Teacher" không phải là primary key của table, nhưng lại có thể xác định thuộc tính khác là "Subjects". Điều này vi phạm nguyên tắc BCNF vì theo BCNF, chỉ các key (hoặc composite key) mới có thể xác định các thông tin khác trong table, chuẩn phải là: TeacherCode TeacherName
GV01 Nga
GV02 Thu SubjectsCode Subjects
MH01 Toán
MH02 Văn TeacherCode SubjectsCode
GV01 MH01
GV02 MH02
Dạng chuẩn 4NF (Fourth Normal Form)
Tập trung vào việc loại bỏ sự dư thừa dữ liệu do các phụ thuộc đa trị(hiểu nôm na là loại bỏ sự trùng lặp các thuộc tính phụ thuộc vào khóa chính mà không liên quan tới nhau nhưng vẫn được lưu trong cùng một table.)
- Phụ thuộc đa trị (Multi-valued Dependency - MVD) xảy ra khi một thuộc tính trong table có thể có nhiều giá trị không phụ thuộc vào nhau nhưng liên quan đến cùng một primary key. Điều này có thể dẫn đến sự dư thừa dữ liệu khi các giá trị đó được lưu trữ trong cùng một table.
Nghệ sĩ Bài hát Nhạc cụ
John Song A Guitar
John Song A Piano
John Song B Guitar
John Song B Piano Ở Table này đang là:
. Một thuộc tính (ví dụ: Bài hát) có thể có nhiều giá trị tương ứng với một primary key (ví dụ: Nghệ sĩ).
. Một thuộc tính khác (ví dụ: Nhạc cụ) cũng có thể có nhiều giá trị cho cùng một primary key.
. Các giá trị này hoàn toàn độc lập với nhau nhưng lại được lưu trữ cùng nhau, tạo ra sự dư thừa dữ liệu.
Chuẩn 4NF phải tách ra là: Table ArtistSong: Lưu trữ thông tin nghệ sĩ và bài hát mà họ trình diễn.
Nghệ sĩ Bài hát
John Song A
John Song B Table ArtistInstrument: Lưu trữ thông tin nghệ sĩ và nhạc cụ mà họ chơi.
Nghệ sĩ Nhạc cụ
John Guitar
John Piano
Dạng chuẩn 5NF (Fifth Normal Form)
Nếu một table có thể được chia nhỏ thành nhiều table nhỏ hơn mà khi nối lại vẫn tái tạo được dữ liệu ban đầu, thì table đó cần được tách ra. Đảm bảo rằng table không chứa sự dư thừa do các phụ thuộc phức tạp.
CourseID TeacherID MaterialID
Math101 T1 M1
Math101 T2 M1
Math101 T2 M2
History T3 M3 Table này có thể được chia nhỏ hơn nữa để loại bỏ sự dư thừa. Ví dụ, thông tin về khóa học và tài liệu có thể không cần phải được lưu trữ trùng lặp cho mỗi giáo viên, chuẩn là tách thành 3 Table: CourseID TeacherID
Math101 T1
Math101 T2
History T3 CourseID MaterialID
Math101 M1
Math101 M2
History M3 TeacherID MaterialID
T1 M1
T2 M1
T2 M2
T3 M3
Dạng chuẩn 6NF (Sixth Normal Form)
Chuẩn 6NF đảm bảo rằng mỗi table chỉ chứa một primary key và tối đa một thuộc tính không khóa (key or non-key attribute)
- Mục tiêu của 6NF là
- Loại bỏ hoàn toàn các vấn đề về NULL trong table.
- Đảm bảo rằng dữ liệu được tách rời đến mức không thể phân chia thêm nữa.
- Thường áp dụng trong các hệ thống rất phức tạp hoặc dữ liệu có tính chất tạm thời(temporal data - tức là dữ liệu có sự biến đổi theo thời gian).
- Ví dụ loại bỏ hoàn toàn các vấn đề về NULL trong table. ProductID ProductName ProductType Description Price
1 Laptop Electronics High-end 1200
2 Mouse Accessories Wireless 30
3 Monitor Electronics 24-inch 200 Table này có ProductID là primary key. Các thuộc tính như ProductName, ProductType, Description và Price có thể chứa NULL tùy thuộc vào loại sản phẩm, điều này làm cho việc quản lý dữ liệu phức tạp và dễ phát sinh lỗi. Theo chuẩn 6NF tách table này thành nhiều table nhỏ, mỗi table chỉ chứa khóa chính và một thuộc tính duy nhất.
Table Product (chỉ chứa ProductID và ProductName):
ProductID ProductName
1 Laptop
2 Mouse
3 Monitor Table ProductType (chỉ chứa ProductID và ProductType):
ProductID ProductType
1 Electronics
2 Accessories
3 Electronics Table ProductDescription (chỉ chứa ProductID và Description):
ProductID Description
1 High-end
2 Wireless
3 24-inch Table ProductPrice (chỉ chứa ProductID và Price):
ProductID Price
1 1200
2 30
3 200 Việc tách table giúp loại bỏ hoàn toàn các giá trị NULL, tối ưu hóa việc lưu trữ và truy vấn dữ liệu. Nhưng đánh đổi là sự bùng nổ số lượng table khi mỗi thuộc tính lại được đặt trong table riêng sẽ làm tăng độ phức tạp của hệ thống và yêu cầu việc tạo các VIEW để tổng hợp lại thông tin. - Ví dụ về xử lý dữ liệu thời gian (temporal data)
Temporal data - là loại dữ liệu lưu trữ các trạng thái hoặc sự kiện xảy ra trong một khoảng thời gian cụ thể, chẳng hạn như thông tin lịch sử, trạng thái thay đổi qua từng thời điểm ví dụ: lịch sử thay đổi lương của nhân viên qua các năm, thông tin về các địa điểm làm việc của một nhân viên thay đổi theo thời gian.
Giả sử ta có một table lưu trữ thông tin lịch sử lương và chức vụ của nhân viên như sau:
EmployeeID Position Salary StartDate EndDate
1 Developer 1000 01-01-2020 31-12-2020
1 Manager 1500 01-01-2021 NULL Trong chuẩn 6NF, ta sẽ phân tách dữ liệu này thành các table đơn giản hơn. Chúng ta có thể chia table trên thành hai table : Table 1: Thông tin về chức vụ theo thời gian
EmployeeID Position StartDate EndDate
1 Developer 01-01-2020 31-12-2020
1 Manager 01-01-2021 NULL Table 2: Thông tin về lương theo thời gian
EmployeeID Salary StartDate EndDate
1 1000 01-01-2020 31-12-2020
1 1500 01-01-2021 NULL Mỗi table chỉ chứa một loại thông tin đơn lẻ (về chức vụ hoặc về lương), giúp việc truy vấn và quản lý dữ liệu trở nên linh hoạt hơn trong các hệ thống có dữ liệu lịch sử.
Với những thông tin trên thì hầu hết các ứng dụng thông thường, chuẩn hóa đến 5NF là đủ, và việc triển khai 6NF có thể không cần thiết trừ khi có lý do cụ thể.