1
ĐẠI HỌC QUỐC GIA THÀNH PHỐ HỒ CHÍ MINH
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN
KHOA HỆ THỐNG THÔNG TIN
ĐẶC TẢ THUẬT TOÁN MÔN THIẾT KẾ CƠ SỞ DỮ LIỆU
Sinh viên thực hiện :
Trần Hưng Nghiệp – 07520245
Nguyễn Thành Phương – 07520285
Nguyễn Ngọc Linh – 07520194
GIÁO VIÊN HƯỚNG DẪN: Phan Nguyễn Thụy An
Thành phố Hồ Chí Minh, tháng 1 năm 20
2
CHƯƠNG 1: TỔNG QUAN
1. Đặt vấn đề:
Cơ sở dữ liệu quan hệ được xây dựng theo lý thuyết do E.F.Codd giới thiệu năm
1970. Mô hình quan hệ có nhiều ưu điểm hơn hẳn các mô hình trước nó và từ năm
1980 đã trở thành mô hình được dùng rộng rãi để phát triển hệ quản trị CSDL.
Cùng với sự phát triển của mô hình dữ liệu quan hệ, có nhiều vấn đề lý thuyết và
thực nghiệm nảy sinh và được giải quyết . Khi thiết kế CSDL quan hệ ta thường đứng
trước vấn đề lựa chọn giữa các lược đồ quan hệ: lược đồ nào tốt hơn? Tại sao? …
Có thể nói tổng quát một lược đồ quan hệ có cấu trúc tốt là lược đồ không chứa
đựng các vấn đề liệt kê sau đây:
a. Dư thừa dữ liệu
Là sự trùng lặp thông tin trong CSDL.
Ví dụ: Xét lược đồ quan hệ NHACC(Ten_NCC, Hang, DonGia, Diachi_NCC).
Nếu một nhà cung cấp cung cấp nhiều mặt hàng thì địa chỉ nhà cung cấp phải lặp lại
nhiều lần kéo theo dư thừa dữ liệu.
Ngoài việc gây lãng phí dung lượng lưu trữ, sự dư thừa dữ liệu có thể gây ra những hậu
quả nghiêm trọng đối với dữ liệu khi người dùng cập nhật dữ liệu làm cho dữ liệu không
tương thích, thiếu nhất quán.
Ví dụ: Xét lại lược đồ NHACC trên. Ta có thể sửa địa chỉ một nhà cung cấp tại một bộ
nào đó mà không sửa ở một bộ khác gây ra địa chỉ không nhất quán của cùng một nhà cung
cấp.
b. Dị thường do thêm dữ liệu
Không thể chèn bộ mới vào quan hệ nếu không có đầy đủ dữ liệu.
Ví dụ: Ta không thể ghi nhận địa chỉ một nhà cung cấp nếu nhà cung cấp đó không
cung cấp mặt hàng nào cả vì Ten_NCC, Hang tạo thành một khoá cho quan hệ.
c. Dị thường do xóa dữ liệu
3
Ngược lại với vấn đề c, khi ta xoá hết các mặt hàng do một hãng cung cấp, ta không thể
theo dõi được địa chỉ của hãng đó.
Trong ví dụ trên, vấn đề này sẽ không còn nữa khi ta thay quan hệ NHACC bằng hai
quan hệ:
NCC_ĐC(TÊN_NCC, ĐC_NCC)
NCC_HG(TÊN_NCC, TÊN_HG, GIA)
Cách giải quyết các vấn đề trên khi thiết kế lược đồ quan hệ là xây dựng lược đồ đạt các
dạng chuẩn.
2. Cơ sở kiến thức:
a. Phụ thuộc hàm:
Phụ thuộc hàm (functional dependancy) là một công cụ dùng để biểu diễn một cách hình
thức các ràng buộc toàn vẹn. Phương pháp biểu diễn này có rất nhiều ưu điểm, và đây là một
công cực kỳ quan trọng, gắn chặt với lý thuyết thiết kế cơ sở dữ liệu. Phụ thuộc hàm có ứng
dụng trong việc giải quyết các bài toán như: tìm khoá, tìm phủ tối thiểu, xác định dạng
chuẩn…
Định Nghĩa Phụ Thuộc Hàm:
Cho R(A
1
,…,A
n
) là một sơ đồ quan hệ với tập thuộc tính U={A
1
,…,A
n
}. X và Y là tập
con của U. Xét một quan hệ cụ thể r nao đó. Ta nói X Y (đọc là: X xác định hàm Y hoặc Y
phụ thuộc hàm vào X) nếu với mỗi cặp bộ u, v của r thỏa:
u[X] = v[X] u[Y] = v[Y]
Để chứng minh và suy ra các phụ thuộc hàm khác từ các phụ thuộc hàm đã có ta dùng hệ
tiên đề Armstrong:
Gọi R(U) là lược đồ quan hệ với U = {A
1
,…,A
n
} là tập các thuộc tính. X, Y, Z,
W U. Hệ tiên đề Armstrong bao gồm:
F1) Tính phản xạ:
Y X X Y
4
F2) Tính tăng trưởng:
X Y XZ YZ
F3) Tính bắc cầu:
X Y, Y Z X Z
b. Bao đóng:
Bao đóng (closure) của tập phụ thuộc hàm F (ký hiệu là F
+
) là tập hợp tất cả các
phụ thuộc hàm có thể suy ra từ F dựa vào các tiên đề Armstrong. Tức nó phải thoả hai tính
chất sau:
i) F
+
F
ii) Khi áp dụng các hệ tiên đề Armstrong cho F
+
ta không thu được phụ thuộc
hàm nào nằm ngoài F
+
.
Bao Đóng Của Tập Thuộc Tính : Cho tập phụ thuộc hàm F trên tập thuộc tính U và
X U. Bao đóng của tập thuộc tính X (đối với F), ký hiệu X
+
, là tập sau:
X
+
= {A | X A F
+
}
c. Bài toán thành viên:
Qua phần trên ta nhận thấy X
+
được định nghĩa thông qua F
+
. Vấn đề nảy sinh khi
nghiên cứu lý thuyết CSDL là: Cho trước tập các phụ thuộc hàm F và một phụ thuộc
hàm f, bài toán kiểm tra có hay không f ∈ F
+
gọi là bài toán thành viên.
d. Siêu khóa, khóa:
Cho quan hệ R(U, F), với U là tập thuộc tính, F là tập phụ thuộc hàm. Cho K ⊆ U.
Định nghĩa Siêu Khoá Của Quan Hệ :
K là một siêu khoá của R nếu thoả điều kiện sau:
K xác định hàm mọi thuộc tính trong U. Tức là K
+
= U.
Định nghĩa Khoá Của Quan Hệ :
5
K là một khoá của R nếu thỏa:
K là siêu khóa và không có siêu khóa nào nhỏ hơn K. Tức là K
+
= U và
H⊂K ⇒ H
+
≠ U.
Một lược đồ quan hệ có thể có nhiều siêu khoá, nhiều khoá.
e. Phủ tối thiểu:
Tập phụ thuộc hàm tối thiểu là tập phụ thuộc hàm thoả mãn các điều kiện sau:
1) Vế phải của mỗi phụ thuộc hàm trong F chỉ có 1 thuộc tính.
2) Mọi phụ thuộc hàm X A F đều không dư thừa, tức là tập phụ thuộc hàm
có từ F bằng sự loại bỏ phụ thuộc hàm X A: F \ {X A} không tương
đương với F.
3) Với mỗi phụ thuộc hàm X A F, mọi thuộc tính B X đều không dư
thừa, tức là tập phụ thuộc hàm có từ F bằng việc thay phụ thuộc hàm X A
bởi phụ thuộc hàm (X \{B}) A : (F \ {X A}) {X \ {B}) A} không
tương đương với F.
Tập phụ thuộc hàm tương đương của F:
Tập phụ thuộc hàm G được gọi là tương đương với F nếu và chỉ nếu F
+
= G
+
Ký hiệu: F ≡ G
Phủ tối thiểu của F:
Là tập phụ thuộc hàm tối thiểu và tương đương với F
Ký hiệu : PTT(F)
f. Các dạng chuẩn:
Như đã nói ở trên, một lược đồ quan hệ có thể bị dư thừa dữ liệu, dị thường do thêm,
dị thường do xóa. Những vấn đề trên đã được giải quyết qua việc xây dựng các dạng
chuẩn.
Xét lược đồ quan hệ R(U, F), với U là tập thuộc tính, F là tập phụ thuộc hàm.
6
i) Dạng chuẩn 1: R được xem là đạt dạng chuẩn 1 nếu mọi thuộc tính của R đều
khác rỗng, phụ thuộc hàm vào khoá và có miền trị nguyên tố (tức là không đa
hợp và đa trị).
ii) Dạng chuẩn 2: R được xem là đạt dạng chuẩn 2 nếu nó đạt dạng chuẩn 1 và
mọi thuộc tính không khóa phải phụ thuộc đầy đủ vào khóa.
iii) Dạng chuẩn 3: R được xem là đạt dạng chuẩn 3 nếu nó đạt dạng chuẩn 2 và
mọi thuộc tính không khóa đều không phụ thuộc bắc cầu vào khóa.
Một cách định nghĩa khác : R được xem là đạt dạng chuẩn 3 nếu mọi phụ
thuộc hàm không hiển nhiên trong F đều có vế trái chứa khóa hay vế phải nằm
trong khóa
iv) Dạng chuẩn B – C : R được xem là đạt dạng chuẩn B – C nếu mọi phụ thuộc
hàm không hiển nhiên trong F đều có vế trái chứa khóa.
3. Yêu cầu cho đề tài:
Đề tài phải trình bày rõ ràng các thuật toán sau và các thuật toán bổ trợ:
o Thuật toán tìm Bao đóng
o Thuật toán kiểm tra Phụ thuộc hàm thành viên
o Thuật toán tìm Khóa
o Thuật toán tìm Phủ tối thiểu
o Thuật toán xác định Dạng chuẩn
Cài đặt thử nghiệm các thuật toán trên trong phần mềm có giao diện đồ họa, nhập liệu
trực tiếp hay từ file dữ liệu nhập.
7
CHƯƠNG 2: CHI TIẾT CÁC THUẬT TOÁN
1. Thuật toán tìm Bao đóng cho tập thuộc tính:
Cho lược đồ quan hệ R(U, F), tập thuộc tính U, tập phụ thuộc hàm F. Tìm X
+
F
?
a. Ý tưởng:
- Bao đóng của X ít nhất có X.
- Duyệt qua tất cả các phụ thuộc hàm, nếu vế trái nằm trong Bao đóng thì thêm vế
phải vào Bao đóng.
- Lặp lại đến khi đi hết một lượt mà không có thêm thuộc tính nào được thêm vào
Bao đóng.
b. Mô hình hóa:
Input: Tập thuộc tính cần tìm bao đóng X, Tập phụ thuộc hàm F.
Output: Bao đóng X
+
F
.
8
TimBaoDong(X, F)
{
TapCu = null
TapMoi = X
While (TapCu <> TapMoi)
TapCu = TapMoi
for each (pth P->Q) in F
If P TapMoi Then
TapMoi = TapMoi Q
End If
Next (pth P->Q)
End While
Return TapMoi
}
c. Độ phức tạp, nhận xét, cải tiến:
Thuật toán trên có độ phức tạp tính toán O(n
2
) với n là số thuộc tính của lược
đồ quan hệ R.
Thuật toán có thể cải tiến bằng cách: Sau khi thêm Q vào TapMoi, ta loại bỏ
pth P->Q ra khỏi F. Vì ta đã thêm Q rồi nên không cần xét thêm nữa.
Ta có thể xây dựng thuật toán với độ phức tạp tuyến tính, sử dụng LIST.
2. Thuật toán kiểm tra phụ thuộc hàm thành viên:
Cho lược đồ quan hệ R(U, F), tập thuộc tính U, tập phụ thuộc hàm F. Cho phụ thuộc
hàm f: X->Y. Kiểm tra xem f có thuộc F
+
không?
a. Ý tưởng:
- X->Y F
+
X
+
F
Y
b. Mô hình hóa:
Input: Phụ thuộc hàm cần kiểm tra f: X→Y, Tập phụ thuộc hàm F.
Output: true nếu f là thành viên của F
+
, false nếu ngược lại.
KiemTraPTHThanhVien(X, Y, F)
{
X
+
F
= TimBaoDong(X, F)
9
if Y X
+
F
then
return true
else
return false
}
c. Độ phức tạp, nhận xét, cải tiến:
Thuật toán trên có độ phức tạp tính toán O(n
2
) với n là số thuộc tính của lược đồ
quan hệ R. Đó cũng là độ phức tạp của thuật toán tìm Bao đóng của tập thuộc tính,
là cốt lõi của thuật toán này.
3. Thuật toán tìm khóa:
Cho lược đồ quan hệ R(U, F), tập thuộc tính U, tập phụ thuộc hàm F. Tìm tất cả các
khóa của R?
a. Ý tưởng: (Tìm khóa Vét cạn)
- Tìm tất cả các siêu khóa :
o Liệt kê tất cả các tập con của U
o Tìm bao đóng của các tập con đó
o Nếu Bao đóng = U thì tập con đó là siêu khóa.
- So sánh các siêu khóa, loại bỏ cái lớn hơn đi được các khóa.
b. Mô hình hóa:
Input: Tập thuộc tính U, Tập phụ thuộc hàm F.
Output: Tập các khóa K.
TimKhoaVetCan(U,F)
{
Dim CacTapCon, CacSieuKhoa
CacTapCon = TimCacTapCon(U)
for each TapCon in CacTapCon
{
if TimBaoDong(TapCon, F) = U then
10
CacSieuKhoa = CacSieuKhoa {TapCon}
end if
}
'loại bỏ các siêu khóa không nhỏ hơn
for each SieuKhoa1 in CacSieuKhoa
for each SieuKhoa2 in CacSieuKhoa
{
if SieuKhoa2 SieuKhoa1 then
CacSieuKhoa = CacSieuKhoa \ SieuKhoa1
break;
end if
}
Return CacSieuKhoa ' Tập các khóa cuối cùng sau khi đã bỏ
các siêu khóa không nhỏ hơn đi
}
c. Độ phức tạp, nhận xét, cải tiến:
Thuật toán trên có độ phức tạp tính toán O(2
n
n
2
) với n là số thuộc tính của lược đồ
quan hệ R.
Bảo đảm tìm được tất cả các Siêu khóa và các Khóa.
Khi số thuộc tính trong U là lớn thì việc duyệt qua tất cả các tập con là không khả
thi. Nên ta đưa ra thuật toán tìm khóa bằng đồ thị sau để giới hạn số tập con sẽ
xét.
Thuật toán này chỉ để tham khảo, chương trình của nhóm không sử dụng thuật
toán này.
d. Ý tưởng: (Tìm khóa bằng đồ thị)
- Dựa trên biểu diễn đồ thị của R: Gốc là thuộc tính chỉ nằm bên vế trái, Cô lập là
thuộc tính không ở trong phụ thuộc hàm nào, Trung gian là thuộc tính nằm ở cả
hai vế, Lá là thuộc tính chỉ nằm bên vế phải.
- Các thuộc tính ở gốc và cô lập chắc chắn nằm trong khóa.
- Các thuộc tính trung gian có thể ở trong khóa hoặc không.
- Các thuộc tính ở lá chắc chắn không ở trong khóa.
e. Mô hình hóa:
11
Input: Tập thuộc tính U, Tập phụ thuộc hàm F.
Output: Tập các khóa K.
TimKhoaDoThi(U, F)
{
for each (pth P->Q) in F
{
VT = VT P
VP = VP Q
}
Goc = VT \ VP 'chi nam o ve trai
TrungGian = VT \ (VT \ VP) 'Nam o ca hai ve
CoLap = U \ VT \ VP
SK = Goc CoLap
If TimBaoDong(SK, F) = U Then
Return SK 'là khóa duy nhất
Else
Dim CacTapcon, CacSieuKhoa
CacTapcon = TimCacTapCon(TrungGian)
For Each TapCon In CacTapcon
{
SKK = SK TapCon
If TimBaoDong(SKK, F) = U Then
CacSieuKhoa = CacSieuKhoa {SKK}
End If
}
'loại bỏ các siêu khóa không nhỏ hơn
for each SieuKhoa1 in CacSieuKhoa
for each SieuKhoa2 in CacSieuKhoa
{
if SieuKhoa2 SieuKhoa1 then
CacSieuKhoa = CacSieuKhoa \ SieuKhoa1
break;
end if
}
Return CacSieuKhoa ' Tập các khóa cuối cùng sau khi
đã bỏ các siêu khóa không nhỏ hơn đi
}
f. Độ phức tạp, nhận xét, cải tiến:
Thuật toán trên có độ phức tạp tính toán tối đa O(2
n
n
2
) với n là số thuộc tính của
lược đồ quan hệ R. Nhưng thường đạt thấp hơn do giới hạn số tập con cần duyệt
không phải 2
n
nữa.
12
Bảo đảm tìm được tất cả các Khóa. Nhưng không bảo đảm tìm được tất cả các
siêu khóa.
4. Thuật toán tìm Phủ tối tiểu cho tập phụ thuộc hàm:
Cho lược đồ quan hệ R(U, F), tập thuộc tính U, tập phụ thuộc hàm F. Tìm PTT(F)?
d. Ý tưởng:
- Tách vế phải ra thành các thuộc tính đơn.
- Thay thế các phụ thuộc hàm không đầy đủ.
- Loại bỏ các phụ thuộc hàm dư thừa.
e. Mô hình hóa:
Input: tập phụ thuộc hàm F
Output: Phủ tối thiểu của F: PTT(F)
TimPTT(F)
{
F = TachPTH(F)
F = LoaiPTHDuThua(F)
F = ThayThePTHKhongDayDu(F)
Return F
}
'
TachPTH(F)
{
for each (pth P->Q) in F
{
CacPhanTu = TimTungPhanTu(Q)
F = F \ (P->Q)
For Each PhanTu in CacPhanTu
F = F (P->PhanTu)
}
}
ThayThePTHKhongDayDu(F)
{
for each (pth P->Q) in F
{
13
for each P
i
in P
1
P
2
…P
k
->Q
{
if F=(F-{P
1
…P
i
…P
k
-> Q}){P
1
…P
i-1
P
i+1
…P
k
->Q}then
P=P\P
i
end if
}
}
}
'
LoaiPTHDuThua(F)
{
for each (pth f = P->Q) in F
{
P
+
(F\f)
= TimBaoDong(P, (F \ f))
if P
+
(F\f)
Q then
F = F \ f
}
}
'
f. Độ phức tạp, nhận xét, cải tiến:
Thuật toán trên chỉ cho ta 1 PTT(F), các phủ tối thiểu khác có được khi ta thay đổi
thứ tự của các tập con khi thay thế các phụ thuộc hàm không đầy đủ.
5. Thuật toán xác định Dạng Chuẩn:
Cho lược đồ quan hệ R(U, F), tập thuộc tính U, tập phụ thuộc hàm F. Xác định dạng
chuẩn?
a. Ý tưởng:
- Tìm tất cả các khóa
- Kiểm tra dạng chuẩn BC
- Kiểm tra dạng chuẩn 3
- Kiểm tra dạng chuẩn 2
- Kiểm tra dạng chuẩn 1.
b. Mô hình hóa:
14
Input: Tập thuộc tính U, Tập phụ thuộc hàm F,
TatCaThuocTinhCoMienTriNguyenTo.
Output:
o Không đạt dạng chuẩn nào return 0
o Đạt dạng chuẩn 1 return 1
o Đạt dạng chuẩn 2 return 2
o Đạt dạng chuẩn 3 return 3
o Đạt dạng chuẩn BC return 4
XacDinhDangChuan(U, F, TatCaThuocTinhThoaMienTriNguyenTo)
{
TapKhoa = TimKhoaDoThi(U, F)
F’ = TachPTH(F)
If DCBC(TapKhoa, F’) then
Return 4
Else if DC3(TapKhoa, F’) then
Return 3
Else if DC2(TapKhoa, F’) then
Return 2
Else if TatCaThuocTinhCoMienTriNguyenTo then
Return 1
Else
Return 0
}
'
DCBC(TapKhoa, F’)
{
for each (fth P->Q) in F’
{
if (Q P) then
Re = false
for each K in TapKhoa
{
if (P K) then
Re = true
Break;
end if
}
If Re = false then
Return false
End If
end if
}
15
return true
}
'
DC3(TapKhoa, F’)
{
for each (fth P->Q) in F’
{
if (Q P) then
Re1 = false
Re2 = false
for each K in TapKhoa
{
if (P K) then
Re1 = true
Break;
end if
}
for each K in TapKhoa
{
if (Q K) then
Re2 = true
Break;
end if
}
If ((Re1 = false) AND (Re2 = false)) then
Return false
end if
end if
}
return true
}
'
DC2_New(TapKhoa, F’) 'F’ là F có vế phải 1 thuộc tính
{
for each (pth P->Q) in F'
for each K in TapKhoa
if (P K) AND (P <> K) then
return false
end if
return true
}
'
DC2_Old(TapKhoa, F, U)
{
TTKK = U
16
for each K in TapKhoa
TTKK = TTKK \ K
for each KK in TTKK
for each K in TapKhoa
{
TapCon = TimTapCon(K)
TapCon = TapCon \ K
for each TC in TapCon
if (TC
+
F
KK) then
return false
end if
}
return true
}
c. Độ phức tạp, nhận xét, cải tiến:
Thuật toán trên phụ thuộc nhiều vào các thuật toán thành phần của nó.
Thông thường thì các lược đồ quan hệ ta xét đều có miền trị nguyên tố và đạt
dạng chuẩn 1.
6. Các thuật toán hỗ trợ:
Tìm các tập con
a. Ý tưởng:
Xây dựng lần lượt các tập con có số thuộc tính tăng dần để không
phải sắp xếp.
b. Mô hình hóa:
Input: Tập thuộc tính U
Output: Tất cả tập con của U
17
U gồm n phần tử
TapCon gồm 2^n-1 phần tử
TapCon = U
For i = 0 to 2^n -1
For j = last(TapCon (i)) to n-1
TapCon.Add(TapCon (i) + U (j))
Next
Next
* ( last(AB) = vị trí của B trong U, last(AB)=1 , last(AC) =2)
Debug mẫu
a. A B C D
b. AB AC AD BC BD CD
c. ABC ABD ACD BCD
d. ABCD
CHƯƠNG 3: CÀI ĐẶT CÁC THUẬT TOÁN
I. Cấu trúc dữ liệu
List được dùng làm cấu trúc lưu trữ chính vì đây là cấu trúc động, sử dụng tối ưu cho
bộ nhớ, và có các hàm cần thiết hỗ trợ như : Add, Addrange, index, RemoveAt …
Tập thuộc tính U: Dim str_U As List(Of String)
18
Mục đích: Mỗi thuộc tính là 1 string riêng biệt, có thể có khoảng trắng ở giữa.
Phụ thuộc hàm : Class F
Class F
Public Left As New List(Of String) 'Vế trái
của PTH, gồm 1 danh sách các string
Public Right As New List(Of String) 'Vế phải
của PTH, gồm 1 danh sách các string
Tập phụ thuộc hàm : Dim lst_F As List(Of F)
Tập con (Tập hợp gồm nhiều tập thuộc tính):
Dim lst_Tap_Con As List(Of List(Of String))
Tập khóa (Tập hợp gồm nhiều tập khóa)
Dim lst_Khoa As List(Of List(Of String))
II. Các thuật toán
a. Tìm bao đóng
Public Function XPlusF(ByVal X As List(Of String), ByVal F As
List(Of F)) As List(Of String)
Dim str_old As New List(Of String)
Dim str_kq As New List(Of String)
Dim flag As Boolean
Dim count As Integer = F.Count - 1
For i As Integer = 0 To X.Count - 1
str_kq.Add(X(i))
Next
Do
str_old.Clear()
For i As Integer = 0 To str_kq.Count - 1
str_old.Add(str_kq(i))
Next
For dem As Integer = 0 To count
flag = True
19
For dem2 As Integer = 0 To F(dem).Left.Count -
1
If str_kq.Contains(F(dem).Left(dem2)) =
False Then
flag = False
End If
If flag = False Then
Exit For
End If
Next
If flag Then
For dem2 = 0 To F(dem).Right.Count - 1
If str_kq.Contains(F(dem).Right(dem2))
= False Then
str_kq.Add(F(dem).Right(dem2))
End If
Next
End If
Next
Loop Until str_old.Count = str_kq.Count
Return str_kq
End Function
b. Tìm khóa
Private Function Tim_Khoa(ByVal lst_U As List(Of String),
ByVal lst_F As List(Of F)) As List(Of List(Of String))
Dim lst_Goc As New List(Of String) 'Các thuộc tính gốc
(1)
Dim lst_TG As New List(Of String) ' Các thuộc tính
trung gian (3)
Dim lst_R As New List(Of String) ' Các thuộc tính cô
lập ( rời) (4)
Dim lst_key As New List(Of String) ' Kết quả
Dim lst_kq As New List(Of List(Of String))
Dim int_kt As Integer
'Thiết lập tập gốc, trung gian, rời rạc
For i As Integer = 0 To lst_U.Count - 1
int_kt = Kiem_Tra_TT(lst_U(i), lst_F)
If int_kt = 1 Then
lst_Goc.Add(lst_U(i))
ElseIf int_kt = 2 Then
lst_TG.Add(lst_U(i))
ElseIf int_kt = 4 Then
lst_R.Add(lst_U(i))
End If
Next
20
For i = 0 To lst_Goc.Count - 1
lst_key.Add(lst_Goc(i))
Next
For i = 0 To lst_R.Count - 1
lst_key.Add(lst_R(i))
Next
If lst_key.Count <> 0 Then
lst_kq.Add(lst_key)
End If
If XPlusF(lst_key, lst_F).Count = lst_U.Count Then
'Kiểm tra xem tập Gốc giao Rời có phải là khóa duy nhất không
Return lst_kq
Else
If lst_kq.Count > 0 Then
lst_kq.RemoveAt(0)
End If
Dim lst_Tap_Con As New List(Of List(Of String))
lst_Tap_Con = Tim_tap_Con_New(lst_TG)
Dim test As Integer
For i = 0 To lst_Tap_Con.Count - 1
test = 1
Dim lst_key_tmp As New List(Of String)
lst_key_tmp.AddRange(lst_key)
lst_key_tmp.AddRange(lst_Tap_Con(i)) 'Add
lần lượt các tập con vào khóa
If XPlusF(lst_key_tmp, lst_F).Count =
lst_U.Count Then
If lst_kq.Count = 0 Then
lst_kq.Add(lst_key_tmp)
Else 'Không add các siêu khóa
For j As Integer = 0 To lst_kq.Count -
1
If list_in(lst_kq(j), lst_key_tmp)
Then
test = 0
End If
Next
If test = 1 Then
lst_kq.Add(lst_key_tmp)
End If
End If
End If
Next
Return lst_kq
21
End If
End Function
c. Tìm phủ tối tiểu
Private Function Tim_Phu_TT(ByVal lst_F As List(Of F)) As
List(Of F)
'Chuyển về dạng vế phải 1 thuộc tính
Dim lst_tmp As New List(Of String)
Dim lst_F_tmp As New List(Of F)
Dim i, j As Integer
For i = 0 To lst_F.Count - 1
If lst_F(i).Right.Count > 1 Then
For j = 0 To lst_F(i).Right.Count - 1
Dim F_tmp As New F
F_tmp.Left.AddRange(lst_F(i).Left)
F_tmp.Right.Add(lst_F(i).Right(j))
lst_F.Add(F_tmp)
Next
lst_F.RemoveAt(i)
i -= 1
End If
Next
'Ta kiểm tra điều kiện không đầy đủ trước, điều kiện
dư thừa sau
'Kiểm tra và loại bỏ thuộc tính không đầy đủ
For i = 0 To lst_F.Count - 1
j = 0
While j < lst_F(i).Left.Count
lst_tmp.Clear()
lst_tmp.AddRange(lst_F(i).Left)
lst_tmp.RemoveAt(j)
If XPlusF(lst_tmp,
lst_F).Contains(lst_F(i).Right(0)) Then
lst_F(i).Left.RemoveAt(j)
j = -1
End If
j += 1
End While
Next
'Kiểm tra và loại bỏ phụ thuộc hàm dư thừa
i = 0
While i < lst_F.Count
lst_F_tmp.Clear()
lst_F_tmp.AddRange(lst_F)
lst_F_tmp.RemoveAt(i)
If XPlusF(lst_F(i).Left, lst_F_tmp).Count =
XPlusF(lst_F(i).Left, lst_F).Count Then
22
lst_F.RemoveAt(i)
i = -1
End If
i += 1
End While
Return lst_F
End Function
d. Xác định dạng chuẩn
Private Function KT_Dang_Chuan_2(ByVal lst_F As List(Of
F), ByVal lst_U As List(Of String)) As Integer
Dim lst_Khoa As New List(Of List(Of String))
lst_Khoa = Tim_Khoa(lst_U, lst_F)
lst_F = Tim_Phu_TT(lst_F)
Dim bool_in As Integer
For i As Integer = 0 To lst_F.Count - 1
For j As Integer = 0 To lst_Khoa.Count - 1
bool_in = 1
For k As Integer = 0 To lst_F(i).Left.Count -
1
If lst_Khoa(j).Contains(lst_F(i).Left(k))
= False Then
bool_in = 0
End If
Next
If bool_in = 1 And lst_F(i).Left.Count <>
lst_Khoa(j).Count Then
Return False
End If
Next
Next
Return True
End Function
Private Function KT_Dang_Chuan_3(ByVal lst_F As List(Of
F), ByVal lst_U As List(Of String)) As Integer
Dim lst_Khoa As New List(Of List(Of String))
lst_Khoa = Tim_Khoa(lst_U, lst_F)
Dim bool_test As Integer
lst_F = Tim_Phu_TT(lst_F)
For i As Integer = 0 To lst_F.Count - 1
bool_test = 0 ' Vế trái là siêu khóa
23
For j As Integer = 0 To lst_Khoa.Count - 1
If list_in(lst_Khoa(j), lst_F(i).Left) Then
bool_test = 1
Exit For
End If
Next
If bool_test = 0 Then
For j As Integer = 0 To lst_Khoa.Count - 1 'Vế
phải nằm trong khóa, vế phải chỉ chứa 1 tt
If lst_Khoa(j).Contains(lst_F(i).Right(0))
Then
bool_test = 1
Exit For
End If
Next
End If
If bool_test = 0 Then
Exit For
End If
Next
If bool_test = 0 Then
Return 0
Else
Return 1
End If
End Function
Private Function KT_Dang_Chuan_BC(ByVal lst_F As List(Of
F), ByVal lst_U As List(Of String)) As Integer
Dim lst_Khoa As New List(Of List(Of String))
lst_Khoa = Tim_Khoa(lst_U, lst_F)
Dim bool_test As Integer = 0
lst_F = Tim_Phu_TT(lst_F)
For i As Integer = 0 To lst_F.Count - 1
bool_test = 0
' Vế trái là siêu khóa
For j As Integer = 0 To lst_Khoa.Count - 1
If list_in(lst_Khoa(j), lst_F(i).Left) Then
bool_test = 1
Exit For
End If
Next
If bool_test = 0 Then
Exit For
End If
Next
If bool_test = 0 Then
24
Return 0
Else
Return 1
End If
End Function
CHƯƠNG 4: NHẬN XÉT, KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN
25
Ở trên chúng ta đã tìm hiểu các kiến thức cơ bản về mô hình cơ sở dữ liệu quan hệ,
các thuật toán nền tảng thao tác trên các thành phần của một lược đồ cơ sở dữ liệu quan hệ.
Các thuật toán trên chủ yếu tập trung vào phần thứ nhất của lý thuyết thiết kế cơ sở dữ liệu
quan hệ là xác định xem một lược đồ quan hệ có tốt không. Có tránh được các vấn đề nảy
sinh về dư thừa dữ liệu, bất thường khi thêm, xóa…
Tuy nhiên còn một phần vô cùng quan trọng của lý thuyết thiết kế cơ sở dữ liệu là xây
dựng các dạng chuẩn cao bằng cách phân rã các lược đồ quan hệ đã có khi chúng không đạt
dạng chuẩn cao.
Chúng ta cũng nên lưu ý một nguyên tắc là được cái này thì sẽ mất cái khác. Khi lược
đồ đạt dạng chuẩn càng cao thì sự dư thừa dữ liệu sẽ càng giảm xuống nhưng công việc xử lý
để lấy dữ liệu ra lại nhiều hơn. Lược đồ đạt dạng chuẩn BC sẽ không có dữ liệu dư thừa.
Nhưng khi đó dữ liệu sẽ bị phân tán ra nhiều quan hệ, việc lấy dữ liệu sẽ phải kết nhiều quan
hệ và chọn rồi chiếu. Nếu đạt dạng chuẩn thấp thì dữ liệu sẽ tập trung ở một chỗ và khi đó ta
chỉ cần chọn và chiếu chứ không cần thực hiện phép kết. Như vậy làm sao xác định phân rã
đến dạng chuẩn nào là có lợi? Làm thế nào tìm được một sự thay thế tốt đẹp cho một sơ đồ
quan hệ tồi tệ? Trong thực tế người ta thường chỉ phân rã các lược đồ quan hệ đến dạng
chuẩn 3 là đạt yêu cầu.
TÀI LIỆU THAM KHẢO
[1] Trịnh Minh Tuấn , “Giáo trình thiết kế cơ sở dữ liệu”. NXB Đại học Quốc gia TP Hồ Chí
Minh, 2009.
[2] “Giáo trình cơ sở dữ liệu”, Trường Cao đẳng Công nghiệp 4.
[3] Phạm Thị Xuân Lộc, “Bài giảng Cơ sở dữ liệu”. Khoa Công nghệ thông tin, Trường Đại
học Cần Thơ.
[4] Đỗ Trung Tuân, “Cơ sở dữ liệu”. NXB Đại học quốc gia Hà Nội.
[5] PGS.TSKH. Trần Quốc Chiến, “Giáo trình Cơ sở dữ liệu”. Đà Nẵng.
[5] Lê Tiến Vương, “Nhập môn Cơ sở dữ liệu quan hệ”. NXB Khoa học và Kỹ thuật, 1995.
[6] Jeffrey D. Ullman – Stanford University, “Principles of Database and Knowledge – Base
systems” (Volume 1&2). Computer Science Press.