Professional Documents
Culture Documents
GT Cơ Sở Dữ Liệu - Học Phần 1
GT Cơ Sở Dữ Liệu - Học Phần 1
Tập rỗng là tập con của mọi tập hợp, tức là ∅ ⊆ B với B là tập hợp bất kỳ.
Định nghĩa 4: Cho hai tập hợp A và B. Tích Đề các (Descartes) của A và B và
kí hiệu là A× B, là tập hợp của tất cả các cặp (a, b) với a∈A và b∈B. Do đó,
B×A = {(a, 1); (b, 1); (c, 1); (a, 2); (b, 2); (c, 2); (a, 3); (b, 3); (c, 3)}
∏ A =A1× A2×
i =1
i …× An={ (a1, a2, …, an) ai∈Ai , i=1, 2, …, n}
Người ta cũng dùng kí hiệu luỹ thừa để biểu diễn tích Đề các của cùng một tập
hợp :
A n
= A × A × . . .× A
n lÇ n A
A×B×C = {(1, a, 3); (1, a, 4); (1, b, 3); (1, b, 4); (1, c, 3);(1, c, 4);
(2, a, 3); (2, a, 4); (2, b, 3); (2, b, 4); (2, c, 3);(2, c, 4) }
Định nghĩa 6: Cho hai tập hợp A và B. Hợp của hai tập hợp A và B được kí
hiệu là A ∪ B, là tập chứa tất cả các phần tử hoặc thuộc A hoặc thuộc B. Tức là:
A ∪ B = { x x∈A ∨ x∈B}
Ví dụ: A = {1, 2, 4, 5, 6}, B = {3, 4, 6, 8, 9}.
Khi đó: A ∪ B = {1, 2, 3, 4, 5, 6, 8, 9}
Định nghĩa 7: Cho hai tập hợp A và B. Giao của hai tập hợp A và B được kí
hiệu là A ∩ B, là tập chứa tất cả các phần tử thuộc cả A và B. Tức là:
A ∩ B = { x x∈A ∧ x∈B}
Ví dụ: A = {1, 2, 4, 5, 6}, B = {3, 4, 6, 8, 9}.
Khi đó: A ∩ B = {4, 6}
Định nghĩa 8: Hai tập hợp A và B được gọi là rời nhau (không giao nhau) nếu
giao của chúng bằng tập rỗng. Tức là
A không giao với B ⇔ A ∩ B = ∅
Định nghĩa 9: Cho hai tập hợp A và B. Hiệu của hai tập hợp A và B được kí
hiệu là A\ B, là tập chứa tất cả các phần tử thuộc A mà không thuộc B. Tức là:
A \ B = { x x∈A ∧ x ∉ B}
Ví dụ: A = {1, 2, 4, 5, 6}, B = {3, 4, 6, 8, 9}.
Khi đó: A \ B = {1, 2, 5}
1.1.1.2 Hàm
Định nghĩa 1: Cho A và B là hai tập hợp. Một hàm f từ A đến B là một phép
tương ứng với mỗi phần tử a của A một phần tử duy nhất b của B mà ta kí hiệu là f(a)
và gọi là ảnh của a bởi f. Ta viết
f : A → B
a ֏ b = f (a)
Khi đó, ta cũng gọi a là nghịch ảnh của b. Tập A được gọi là miền xác định
của f. Tập B được gọi là miền giá trị của f.
Ví dụ: Giả sử f là hàm từ tập Z vào tập N mà ta cho tương ứng với mỗi phần
tử z ∈ Z với phần tử n ∈ N sao cho n= z , tức f(z)= z . Khi đó, miền xác định của f là
tập số nguyên Z, miền giá trị của f là tập số tự nhiên N.
Định nghĩa 2: Cho hàm g từ tập A đến tập B và hàm f từ tập B đến tập C. Hợp
thành của các hàm f và g, được kí hiệu là fοg, được định nghĩa bởi:
(fοg)(a) = f(g(a)), với ∀a ∈ A
Ví dụ: Cho hai hàm f, g : Z → Z xác định bởi f(x)=3x+4 và g(x)=7x+5. Khi
đó ta có:
(fοg)(x) = f(g(x)) = f(7x+5) = 3(7x+5) +4 = 21x+19
(gοf)(x) = g(f(x)) = g(3x+4) = 7(3x+4) +5 = 21x+33
Chúng ta thấy rằng: mặc dù tồn tại cả hai hợp thành fοg và gοf nhưng chúng
không bằng nhau.
1.1.1.3 Quan hệ
Định nghĩa 1: Một quan hệ giữa tập hợp A và tập hợp B là một tập con R của
A×B. Nếu (a, b) ∈ R , ta viết aRb. Một quan hệ giữa A và A được gọi là một quan hệ
trên A.
Ví dụ: Quan hệ “≤” trên tập số Z . Khi đó aRb ⇔ a ≤ b
Định nghĩa 2: Một quan hệ trên các tập hợp A1, A2, …, An, là một tập hợp con
n
của ∏ A =A1× A2×
i =1
i …× An.
1.1.2 Cơ sở dữ liệu
Trong mọi hoạt động của con người, nhu cầu tích lũy và xử lý các dữ liệu luôn
nảy sinh. Để giải quyết một vấn đề nhỏ cũng cần tới dữ liệu, nhưng không nhất thiết
phải quản lí những dữ liệu này theo các phương pháp khoa học. Vì khả năng tổng hợp
của người xử lí mà các dữ liệu được lấy ra, được xử lí không vấp phải khó khăn nào.
Tuy nhiên khi gặp phải một vấn đề, một bài toán với khối lượng dữ liệu cần xử lí lớn
thì tất yếu dữ liệu cần được quản lí tốt, có khoa học. Khi đó, manh nha công tác tự
động hóa dữ liệu. Ban đầu, người ta dùng hệ quản lí tệp với các tệp dữ liệu chứa các
thông tin và dùng chương trình để tìm kiếm, thao tác dữ liệu của tệp đó. Điều này đẫn
tới một số nhược điểm:
- Dư thừa dữ liệu và tính không nhất quán dữ liệu: Do các tệp được tạo ra bởi
các nhà lập trình khác nhau, trên các ngôn ngữ lập trình khác nhau nên một dữ liệu có
thể lưu trữ ở nhiều tệp khác nhau. Điều này dẫn tới dư thừa dữ liệu. Hơn nữa, dữ liệu
trong các tệp có thể được thay đổi một cách độc lập do các chương trình ứng dụng sử
dụng nó. Vì vậy, cùng một khoản mục dữ liệu, nhưng trong mỗi chương trình ứng
dụng lại khác nhau, dẫn tới tính không nhất quán dữ liệu.
- Khó khăn trong việc truy cập dữ liệu
- Sự cô lập dữ liệu: Do dữ liệu nằm ở nhiều tệp với các khuôn dạng khác nhau
nên khó viết các chương trình ứng dụng mới để tìm kiếm dữ liệu thích hợp.
- Các vấn đề về toàn vẹn:
- Các vấn đề về độ tin cậy:
- Các dị thường truy nhập tương tranh
- Các vấn đề về an toàn
Để khắc phục các nhược điểm trên và tổ chức việc xử lí dữ liệu một cách khoa
học hơn thì các hệ cơ sở dữ liệu đã xuất hiện.
Định nghĩa: Một cơ sở dữ liệu (CDSL) là tập hợp các dữ liệu có liên quan đến
nhau chứa thông tin về một tổ chức nào đó, được lưu trữ trên các thiết bị nhớ thứ cấp
để đáp ứng nhu cầu khai thác thông tin của nhiều người sử dụng với các mục đích
khác nhau.
Từ định nghĩa trên ta thấy, một cơ sở dữ liệu thỏa mãn hai tính chất dưới và
được làm rõ trong phần 1.2.3:
- Tính độc lập dữ liệu
- Tính chia xẻ dữ liệu
Cách khác, có thể hiểu một hệ cơ sở dữ liệu là một hệ thống gồm bốn thành
phần:
- Cơ sở dữ liệu phải hợp nhất: Cơ sở dữ liệu phải thỏa mãn hai yêu cầu sau:
Không dư thừa (trong thực tiễn dữ liệu dư thừa ít nhất)
Chia xẻ dữ liệu
- Người sử dụng: Là người có yêu cầu truy cập cơ sở dữ liệu để thực hiện một
thao tác nào đó.
+ Người sử dụng đầu cuối (End-User): là những người sử dụng truy
cập vào cơ sở dữ liệu từ một trạm nào đó để tìm kiếm, tra cứu thông tin.
+ Người viết chương trình ứng dụng
+ Người quản trị cơ sở dữ liệu: là người có nhiệm vụ điều khiển toàn
bộ hệ cơ sở dữ liệu, là người có quyền cao nhất, chịu trách nhiệm thực hiện
các nhiệm vụ sau:
Quyết định nội dung thông tin: (dữ liệu nào sẽ được lưu trữ
trong cơ sở dữ liệu)
Quyết định cấu trúc lưu trữ, chiến lược truy cập
Xác định những thao tác sao cho đảm bảo tính đúng đắn và an
toàn của dữ liệu.
Xác định các phương án sao lưu, dự phòng.
- Hệ quản trị cơ sở dữ liệu: Đây chính là phần mềm của hệ cơ sở dữ liệu.
- Phần cứng: Là các thiết bị được sử dụng để sao lưu dữ liệu.
Để tổng quan về hệ cơ sở dữ liệu chúng ta sẽ phân chia các hệ cơ sở dữ liệu
thành hai loại cơ bản: các hệ cơ sở dữ liệu tập trung và các hệ cơ sở dữ liệu phân tán.
1. Các hệ cơ sở dữ liệu tập trung: là các hệ cơ sở dữ liệu mà trong đó phần cơ
sở dữ liệu được lưu trữ tại một nơi, một vị trí nhất định.
a) CSDL mang tính cá nhân (Personal DataBase): Là một hệ CSDL nhỏ gồm
4 thành phần (NSD, Máy trạm, DBMS, CSDL) như hình vẽ. Ở đây người viết chương
trình, người sử dụng cuối, người quản trị là một. Và do đó, hệ này chỉ đảm bảo cho
một chức năng nhỏ lẻ mà thôi.
1. Mức Vật lí: Đây là mức thấp nhất của sự trừu tượng mô tả dữ liệu được lưu
trữ thực sự như thế nào trong cơ sở dữ liệu. Tại mức này, cơ sở dữ liệu được nhìn theo
cấu trúc lưu trữ.
2. Mức Khái niệm: Là mức cao hơn tiếp theo của sự trừu tượng mô tả những
dữ liệu nào được lưu trữ trong cơ sở dữ liệu và các mối quan hệ nào tồn tại giữa các
dữ liệu này. Do vậy cơ sở dữ liệu được nhìn theo cấu trúc chính quy của dữ liệu và sẽ
mô tả:
- Dạng dữ liệu cơ bản, nhằm xác định các thuộc tính của đối tượng.
- Các dạng dữ liệu thành phần, cho phép nhóm các thuộc tính lại để mô tả một
thực thể của thế giới thực ở mức gộp lớn hơn.
- Các dạng dữ liệu thành phần cho phép nhóm các thuộc tính để mô tả các liên
kết (quan hệ) trong thế giới thực.
3. Mức khung nhìn: Là mức cao nhất của sự từu tượng mô tả chỉ một phần của
toàn bộ cơ sở dữ liệu. Mức khung nhìn là cách người dùng cảm nhận về dữ liệu và do
vậy hệ thống có thể cung cấp nhiều khung nhìn đối với cùng một cơ sở dữ liệu.
lược đồ con). Thông thường các hệ cơ sở dữ liệu hỗ trợ một lược đồ vật lí, một lược
đồ logic và nhiều lược đồ ngoài. Khi thiết kế cơ sở dữ liệu thường dùng lược đồ logic
để mô tả mức độ cao về thế giới thực. Sau đó, dịch lược đồ logic sang lược đồ vật lí.
Theo thời gian, các cơ sở dữ liệu sẽ thay đổi khi dữ liệu được thêm vào, xóa đi
hay sửa đổi. Toàn bộ dữ liệu lưu trữ trong cơ sở dữ liệu tại một thời điểm nhất định
được gọi là một thể hiện của cơ sở dữ liệu (DataBase Instance). Như thế, tương ứng
với một lược đồ cơ sở dữ liệu có thể có nhiều thể hiện của cơ sở dữ liệu đó.
Mức vật lí
- Độc lập dữ liệu vật lí: là khả năng các thay đổi tại mức vật lí nhiều khi là cần
thiết để tăng hiệu năng hệ thống.
- Độc lập dữ liệu logic: là khả năng sửa đổi lược đồ logic mà không làm thay
đổi các lược đồ ngoài và như vậy không cần đòi hỏi viết lại chương trình ứng dụng.
Cơ sở dữ liệu có tính độc lập logic sẽ có các ưu điểm:
Cho phép mỗi nhóm người sử dụng thấy dữ liệu họ mong muốn
Cho phép phát triển các khung nhìn của nhóm công tác
Phát triển khung nhìn mà không cần tác động đền khung nhìn khác
…
Do vậy độc lập dữ liệu logic là khó đạt được hơn so với độc lập dữ liệu vật lí.
- Một tập các quan hệ là một tập các quan hệ cùng kiểu. Một cách toán học,
tập các quan hệ R là tập các quan hệ ri, trong đó ri thể hiện mối liên hệ của n thực thể
(e1, e2, …, en) với ej trong ri thuộc tập thực thể Ej (1≤ j ≤ n). Vậy nên thấy ngay tập
quan hệ R là tập con của tích Descartes E1× E2× …× En và khi đó n được gọi là cấp
của kiểu liên kết
1.4.1.2 Sơ đồ thực thể - liên kết
Cấu trúc logic tổng thể của một cơ sở dữ liệu có thể được biểu diễn bởi một sơ
đồ ER. Để biểu thị các thành phần của mô hình ER thông qua đồ thị, sơ đồ người ta sử
dụng các kí hiệu sau:
Ví dụ:
Để thể hiện liên kết giữa các đoạn, mô hình phân cấp dùng khái niệm quan hệ
cha con. Các đoạn được nối với nhau bằng quan hệ 1:n, tức ứng với một đoạn cha sẽ
trỏ đến n đoạn con. Tập các đoạn nối nhau bởi quan hệ cha con tổ chức dưới dạng
phân cấp gọi là cây các đoạn. Khi đó, cơ sở dữ liệu phân cấp được hiểu là cơ sở dữ
liệu được tạo bởi rừng các đoạn.
Từ đây ta hiểu, mô hình phân cấp có cả rừng các đoạn hay là tập các cây của
các đoạn. Mỗi đoạn cha chứa n đoạn con và đoạn con này lại có thể chứa m đoạn con
khác.
1
CODASYL – Conference On Data Systems Languages – là tổ chức được thành lập bởi bộ quốc phòng
Mỹ. Nó chuyên phát triển các hệ thống quản trị dữ liệu và hệ thống.
Rõ ràng các đối tượng được mô tả thông qua các bản ghi và qua các mối quan
hệ giữa chúng. Trong mô hình này, chỉ có thể xác định quan hệ qua một bản ghi gọi là
chủ và n bản ghi gọi là bản ghi thành phần. Và, tập(set) là quan hệ giữa một bản ghi
chủ và n bản ghi thành phần. Khi đó, cơ sở dữ liệu mạng (Network DataBase) là cơ sở
dữ liệu gồm các bản ghi được nối với nhau qua các tập.
Đối tượng (Object) là tập các phần tử của các dữ liệu có cấu trúc, tham chiếu
duy nhất qua tên.
Ví dụ: …………..
Mỗi một đối tượng có các thuộc tính (còn gọi là các thể hiện). một thuộc tính
mang giá trị cho phép xác định đặc tính của đối tượng. Giá trị này có thể là dữ liệu cơ
bản như số nguyên, số thực, kí tự hay dữ liệu phức tạp như một cấu trúc, các giá trị
lặp, và có thể dung con trỏ để trỏ đến đối tượng khác. Vậy, thuộc tính (Attribute) là
tính chất của đối tượng được gán tên, cho phép tương ứng với một giá trị hay một
tham chiếu đến một đối tượng khác.
Trong mô hình đối tượng còn cho phép quản lý cấu trúc của các đối tượng
theo chức năng mà được gọi là phương thức. Phương thức (Method) là thủ tục đặc
trưng bởi tên đầu thủ tục, các tham số gọi và các tham số trả về dùng để áp lên một
đối tượng có tên. Và như thế, một đối tượng được các phương phức xử lí.
Chương này sẽ giới thiệu cơ sở dữ liệu theo mô hình quan hệ. Thế hệ thứ nhất
của các hệ quản trị cơ sở dữ liệu (gồm mô hình mạng và mô hình phân cấp) là mô
hình truy cập vì sự phụ thuộc của chúng vào hệ điều hành. Thế hệ thứ hai của các hệ
quản trị cơ sở dữ liệu được đánh dấu từ năm 1970. Khi đó, Codd E.F. tại công ty IBM
ở SanJoe, Mỹ đã đề xuất mô hình dữ liệu quan hệ. Từ đó các hệ thống sử dụng mô
hình dữ liệu quan hệ trở nên phổ biến.
Việc nghiên cứu lí thuyết về mô hình dữ liệu quan hệ chủ yếu nhắm vào lí
thuyết chuẩn hóa quan hệ. Và mục đích chính là bỏ đi các phần tử không bình thường
của quan hệ khi thực hiện các phép cập nhật, loại bỏ các dữ liệu dư thừa, hiểu quan hệ
ngữ nghĩa giữa các dữ liệu.
Bảng trên thể hiện dữ liệu của tập thực thể là SINHVIEN. Mỗi dòng của bảng
chứa giá trị tương ứng với dữ liệu của một thực thể và có một hoặc nhiều giá trị dùng
để phân biệt giữa các dòng. Trên mỗi cột, các giá trị có cùng một kiểu dữ liệu. Trong
lí thuyết mô hình dữ liệu quan hệ, thuật ngữ quan hệ để chỉ bảng, thuộc tính để chỉ
tên của mỗi cột, miền để chỉ kiểu dữ liệu của một cột, bộ để chỉ một hàng trong bảng.
1. Miền(Domain):
Một miền D là tập các giá trị nguyên tố. (Giá trị nguyên tố là giá trị mà không
thể phân chia được trong phạm vi mô hình quan hệ).
Để đặc tả một miền người ta cần chỉ ra một tên miền, một kiểu dữ liệu và
khuôn dạng dữ liệu.
Ví dụ: Miền mã sinh viên (MSV) là tập các dãy kí tự có độ dài 10. Và miền
này thường kí hiệu là Dom(MSV).
Chú ý: Tương ứng với mỗi thuộc tính có một miền, nhưng không nhất thiết
các thuộc tính khác nhau có các miền khác nhau.
2. Quan hệ (Relation):
Một quan hệ r trên tập các thuộc tính U={A1, A2, …, An} nếu r là tập con của
Dom(A1)×Dom(A2)× …× Dom(An), trong đó Dom(Ai) là miền của thuộc tính Ai –
tức là tập các giá trị có thể có của thuộc tính Ai. Khi đó, ta gọi U là sơ đồ quan hệ và
nói quan hệ r xác định trên sơ đồ quan hệ U.
3. Bộ dữ liệu, Lược đồ quan hệ
Cho quan hệ r trên U={A1, A2, …, An}. Bộ t của quan hệ r là phần tử thuộc r
và viết t∈r.
Một lược đồ quan hệ R là cặp có thứ tự R=(U, F), trong đó U là tập hữu hạn
các thuộc tính của quan hệ, F là tập các điều kiện giữa các thuộc tính (F còn gọi là tập
các ràng buộc toàn vẹn). Bậc của R là số lượng thuộc tính của lược đồ. Như vậy, lược
đồ quan hệ được sử dụng để mô tả về cấu trúc và các ràng buộc toàn vẹn của một
quan hệ. Khi không quan tâm đến các RBTV thì lược đồ quan hệ được viết
R(A1, A2, …, An)
trong đó, R là quan hệ, A1, A2, …, An là danh sách các thuộc tính.
Một quan hệ (hoặc trạng thái quan hệ) r của lược đồ quan hệ R được ký hiệu là
r(R), là tập hợp các bộ t và gọi là một thể hiện của lược đồ R. Ta sẽ kí hiệu t[X], với
X⊆U, là bộ t chỉ chứa các giá trị của các thuộc tính trong X và kí hiệu t[Ai] để chỉ giá
trị của bộ t tương ứng với thuộc tính Ai của quan hệ r(R).
Các tính chất đặc trưng của một quan hệ
• Thứ tự của các bộ trong một quan hệ
Một quan hệ được xem như một tập hợp các bộ, mà các phần tử trong một tập
hợp thì không có thứ tự. Vì vậy, các bộ không có một thứ tự bắt buộc trong một quan
hệ. Tuy nhiên, trong một tệp, các bộ được lưu trữ một cách vật lý trên đĩa vì vậy luôn
có một thứ tự giữa các bộ. Thứ tự này chỉ rõ bộ thứ nhất, bộ thứ hai, …. Một cách
tương tự, khi ta biểu diễn một quan hệ như là một bảng, các hàng được hiển thị theo
một thứ tự nhất định. Tóm lại, về mặt lí thuyết, thứ tự các bộ không quan trọng.
• Thứ tự của các giá trị bên trong một bộ
Theo định nghĩa quan hệ, dễ thấy, thứ tự thuộc tính trong một lược đồ quan hệ
là quan trọng, từ đó suy ra thứ tự của các giá trị trong một bộ cũng quan trọng. Tuy
nhiên, ở mức logic, thứ tự của các thuộc tính và các giá trị của nó là không thực sự
quan trọng khi giữ được sự tương ứng giữa các thuộc tính và các giá trị.
Có thể đưa ra một định nghĩa khác về quan hệ, định nghĩa này sẽ làm cho thứ
tự của các giá trị trong một bộ là không cần thiết. Theo định nghĩa này, một lược đồ
quan hệ R = {A1, A2,…, An} là một tập hợp các thuộc tính và một quan hệ r(R) là
một tập hợp hữu hạn các hàm r = {t1, t2, …., tm}, trong đó mỗi ti là một hàm từ R vào
t2[SK]. Tập hợp thuộc tính SK như vậy được gọi là một siêu khoá của lược đồ quan hệ
R. Hình thức hóa ta có thể đưa ra định nghĩa:
Một tập con SK ⊆ U được gọi là siêu khóa của lược đồ quan hệ R nếu với mọi
quan hệ r của lược đồ R, và với bất kỳ hai bộ t1, t2 ∈ r, t1 ≠ t2 thì t1[SK] ≠ t2[SK]
Thấy ngay mỗi quan hệ đều có ít nhất một siêu khóa, đó là tập U – tập tất cả
các thuộc tính của quan hệ. Nếu có một siêu khóa SK là tập con thực sự của U thì
SK∪{A}, A∈U\SK, cũng là một siêu khóa. Vậy, một lược đồ quan hệ có thể có nhiều
siêu khóa. Tuy nhiên, trong một lược đồ quan hệ , một siêu khóa mà mọi tập con thực
của nó không là siêu khóa thì được gọi là khóa của lược đồ quan hệ đó. Như vậy,
khóa là một siêu khóa tối tiểu và do đó một lược đồ quan hệ cũng có thể có nhiều
khóa. Các thuộc tính tham gia vào khóa được gọi là thuộc tính khóa, ngược lại được
gọi là thuộc tính không khóa.
Ví dụ: Cho lược đồ quan hệ sau:
SINHVIEN(CMND, MASV, HO, TEN, NGAYSINH, GIOI)
Siêu khóa: (CMND, HO,TEN), (MASV, HO, TEN), …
Khóa: (CMND), (MASV)
Thuộc tính khóa: CNMD, MASV
Thuộc tính không khóa: HO, TEN, NGAYSINH, GIOI
Thực tế, người ta thường lựa một khóa tối tiểu tốt nhất làm khóa chính của
quan hệ, các khóa tối tiểu khác được coi là khóa dự phòng.
Giả sử có hai quan hệ r(R) và s(S). Ta nói rằng có một mối liên hệ một – nhiều
giữa r và s nếu mỗi bộ t∈r tương ứng (liên quan) nhiều bộ u∈s và mỗi bộ u∈s chỉ
tương ứng (liên quan) với duy nhất một bộ t∈r. Quan hệ r(R) được gọi là quan hệ chủ
(bảng chủ), s(S) được gọi là quan hệ liên kết.
Ví dụ: Cho hai lược đồ quan hệ sau:
HANG_BAN(NGAY, MAHANG, SLG, DG)
HANG(MAHANG, TENHANG, DVT)
Ta thấy, trong quan hệ HANG ứng với mỗi mã hàng (MAHANG) sẽ xác
định duy nhất một bộ. Ngược lại, trong quan hệ HANG_BAN, mỗi mã hàng
(MAHANG) sẽ tương ứng với nhiều bộ. Khi này tồn tại mối liên hệ một - nhiều giữa
HANG VÀ HANG_BAN.
3. Mối liên hệ nhiều – nhiều
Giả sử có hai quan hệ r(R) và s(S). Ta nói rằng có một mối liên hệ nhiều –
nhiều giữa r và s nếu mỗi bộ t∈r tương ứng (liên quan) nhiều bộ u∈s và ngược lại.
Ví dụ:
Trong quá trình phân tích thiết kế một CSDL, người phân tích cần lập bảng
tầm ảnh hưởng cho một ràng buộc toàn vẹn nhằm xác định thời điểm cần phải tiến
hành kiểm tra các ràng buộc toàn vẹn đó. Các thời điểm cần phải kiểm tra RBTV
chính là những thời điểm cập nhật dữ liệu (thêm/sửa/ xóa)
Phân loại RBTV
Khi phân tích thiết kế cơ sở dữ liệu, người phân tích phải phát hiện tất cả các
ràng buộc toàn vẹn tiềm ẩn trong CSDL đó. Để tránh bỏ sót, khi xác định các ràng
buộc phải dựa trên bản chất của mô hình, tìm các ràng buộc dựa trên lược đồ và dựa
trên ứng dụng. Khi đó có các loại ràng buộc: ràng buộc miền, ràng buộc khoá, ràng
buộc toàn vẹn thực thể và ràng buộc toàn vẹn tham chiếu.
• Các ràng buộc miền
Ràng buộc miền trên thuộc tính A là mỗi giá trị của thuộc tính A phải thuộc
miền giá trị Dom(A). Các kiểu dữ liệu liên kết với các miền bao gồm: các kiểu dữ liệu
số chuẩn cho các số nguyên (short integer, integer, long integer), các số thực (float,
double precision float). Ngoài ra còn các kiểu dữ liệu ký tự (dãy ký tự với độ dài cố
định, dãy ký tự với độ dài thay đổi), ngày, thời gian và tiền tệ. Các loại miền khác có
thể là các miền con của một kiểu dữ liệu hoặc một kiểu dữ liệu đếm được trong đó
mọi giá trị có thể được liệt kê rõ ràng
• Ràng buộc khoá và ràng buộc trên các giá trị không xác định (null)
Một khoá K xác định rõ một ràng buộc về tính duy nhất, phát biểu rằng không
có hai bộ khác nhau trong một trạng thái r của R có cùng một giá trị cho K. Giá trị của
một thuộc tính khoá có thể được sử dụng để xác định một cách duy nhất mỗi bộ trong
một quan hệ. Ví dụ, giá trị 45150202 của MASV xác định một cách duy nhất bộ giá
trị tương ứng với sinh viên Hoàng Ngọc Lan trong quan hệ SINHVIEN. Chú ý rằng
một tập hợp thuộc tính tạo nên một khoá là một tính chất của lược đồ quan hệ. Điều
ràng buộc là tính chất đó phải thỏa mãn trên mọi trạng thái của lược đồ. Một khoá
được xác định từ ý nghĩa của các thuộc tính và tính chất là bất biến, tính chất đó phải
thỏa mãn khi chúng ta chèn thêm các bộ mới vào quan hệ. Ví dụ, ta không thể và
không được chỉ định cặp thuộc tính (HO, TEN) của quan hệ SINHVIEN là khoá bởi
vì không có gì đảm bảo rằng không tồn tại hai sinh viên có cùng họ tên.
Một ràng buộc khác trên các thuộc tính chỉ rõ khi nào thì cho phép các giá trị
null. Những thuộc tính luôn luôn phải có một giá trị xác định và hợp lệ thì bị ràng
buộc là NOT NULL.
• Cơ sở dữ liệu quan hệ và lược đồ cơ sở dữ liệu quan hệ
Ở trên, chúng ta đã nói đến các lược đồ quan hệ đơn lẻ và các quan hệ đơn lẻ.
Một cơ sở dữ liệu quan hệ thường gồm nhiều quan hệ với các bộ giá trị trong các quan
hệ được liên kết với nhau theo nhiều cách. Trong phần này chúng ta sẽ định nghĩa một
cơ sở dữ liệu quan hệ và một lược đồ cơ sở dữ liệu quan hệ. Một lược đồ cơ sở dữ liệu
quan hệ S là một tập hợp các lược đồ quan hệ
S = {R1, R2,…, Rn} và một tập các ràng buộc toàn vẹn.
Một trạng thái cơ sở dữ liệu quan hệ (hoặc một cơ sở dữ liệu quan hệ) DB của
S là một tập hợp các trạng thái quan hệ:
cơ sở dữ liệu. Các ràng buộc toàn vẹn quy chiếu thường nảy sinh từ các mối liên kết
giữa các thực thể được biểu diễn bằng các lược đồ quan hệ.
Chú ý rằng một khoá ngoài có thể tham chiếu đến quan hệ của chính nó. Trong
trường hợp đó, khoá ngoài biểu thị một liên kết đệ quy.
Chúng ta có thể biểu diễn các ràng buộc tham chiếu bằng sơ đồ. Để làm điều
đó ta vẽ một cạnh có hướng từ mỗi khoá ngoài đến quan hệ mà nó tham chiếu đến.
Ngoài các ràng buộc toàn vẹn ở trên, cơ sở dữ liệu còn phải thoả mãn một số
ràng buộc khác, như ràng buộc trạng thái, ràng buộc chuyển tiếp… Các ràng buộc
trạng thái xác định các ràng buộc mà một trạng thái vững chắc của cơ sở dữ liệu phải
thoả mãn. Ví dụ về các ràng buộc đó là: “ điểm cao nhất mà một sinh viên có thể đạt
được tại một môn là 10”. Các ràng buộc như vậy có thể được đặc tả và bắt tuân theo
bằng cách sử dụng một ngôn ngữ đặc tả ràng buộc. Người ta có thể sử dụng các cơ
cấu như là trigger hoặc assertion. Các ràng buộc chuyển tiếp có thể được định nghĩa
để làm việc với những thay đổi trạng thái trong cơ sở dữ liệu. Ví dụ về ràng buộc này
là: “học phí của một sinh viên chỉ có thể tăng”. Các ràng buộc như vậy thường được
định nghĩa bằng cách sử dụng các quy tắc hoặc bằng các trigger.
Khóa K có thể là dạng số hay số dạng chuỗi. Giả sử có 2 khóa phân biệt ki và kj
nếu h(ki)=h(kj) thì hàm băm bị đụng độ. Và một hàm băm tốt phải thỏa mãn các điều
kiện sau:
Tính toán nhanh.
Các khoá được phân bố đều trong bảng.
Ít xảy ra đụng độ.
Xử lý được các loại khóa có kiểu dữ liệu khác nhau
Hàm băm có thể là hàm băm sử dụng phương pháp chia, hàm băm sử dụng
phương pháp nhân và hàm băm phổ quát (universal hashing).
Với tổ chức tệp băm, tệp dữ liệu được chia thành các cụm (buckets). Mỗi cụm
bao gồm một hoặc nhiều khối, mỗi khối chứa cố định các bản ghi. Trong tệp băm các
bản ghi không được viết tuần tự trong tệp. Do vậy, cần có một hàm băm h lấy đối số
là giá trị khóa của tệp và tính toán địa chỉ của cụm chứa bản ghi.
Giả sử ta “băm” tệp dữ liệu thành M cụm và xác định hàm băm h(K) = K mod
M. Khi đó địa chỉ băm được đánh số từ 0 đến M-1. Ở đầu mỗi khối đều chứa con trỏ
tới khối kế tiếp trong cụm và khối cuối cùng trong cụm chứa con trỏ rỗng (NULL).
Có một bảng chỉ dẫn cụm chứa M con trỏ, mỗi con trỏ chứa một cụm và là địa chỉ của
khối đầu tiên trong cụm.
Ví dụ hình sau là một tổ chức tệp băm gồm 4 cụm. Cụm 0 không chứa khối
nào. Cụm 1 chứa hai khối B1, B2. Khối B1 chứa hai bản ghi có khóa K1 và K5 và
một con trỏ trỏ tới khối B2, khối B2 chứa một bản ghi có khóa K9 và một con trỏ
rỗng. Và tương tự đối với các cụm 2 và cụm 3.
Nếu bảng chỉ dẫn cụm có kích thước nhỏ thì có thể được lưu ở bộ nhớ trong.
Trong trường hợp ngược lại, phải lưu ở thiết bị nhớ ngoài. Khi đó, nếu một giá trị
băm được tính thì các khối của cụm có địa chỉ tương ứng sẽ được gọi vào bộ nhớ
trong.
Các thao tác trên tổ chức tệp băm
Tìm kiếm một bản ghi
Giả sử cần tìm một bản ghi nào đó có giá trị khóa là K. Đầu tiên tính hàm băm
h(K). Hàm băm này sẽ xác định địa chỉ cụm i trong khoảng từ 0 đến M-1 ứng với
các khối có thể chứa bản ghi này. Tại bảng chỉ dẫn cụm cho biết con trỏ trỏ tới khối
đầu tiên (nếu có). Ta sẽ duyệt từng khối cho đến khi tìm được bản ghi mong muốn
hoặc sẽ không tìm thấy bản ghi đó.
Thêm một bản ghi
Giả sử cần thêm một bản ghi có giá trị khóa là K vào tệp, thủ tục được tiến
hành qua các bước:
- Tìm xem trong tệp đã có bản ghi nào có giá trị khóa là K không? Nếu
trong tệp đã có một bản ghi có giá trị khóa là K thì việc thêm bản ghi mới
không hợp lệ (vì khóa là duy nhất).
- Nếu không có bản ghi nào có giá trị khóa là K thì thêm bản ghi này vào
khối đầu tiên trong cụm (có địa chỉ h(K)) còn chỗ trống. Nếu không có
khối nào trong cụm còn chỗ trống thì tạo thêm khối mới và để con trỏ
NULL của khối cuối cùng trỏ vào khối này. Theo đó bản ghi mới sẽ được
thêm vào vị trí đầu của khối này.
Xóa một bản ghi
Giả sử cần xóa một bản ghi có giá trị khóa là K. Đầu tiên, tìm xem trong tệp
có bản ghi nào có giá trị khóa là K không? Nếu bản ghi tìm thấy nằm trong khối chứa
nhiều bản ghi khác thì bản ghi đó sẽ bị loại bỏ. Nếu bản ghi đó là duy nhất trong khối
thì sẽ loại bỏ cả khối đó trong cụm.
Sửa đổi một bản ghi
Giả sử cần sửa đổi các giá trị của một hay nhiều trường của một bản ghi có giá
trị khóa là K. Có hai trường hợp sau:
- Trường cần sửa đổi có tham gia vào khóa. Khi đó, ta xóa bản ghi đó và
thêm bản ghi mới cho tệp theo các quy tắc trên.
- Trường cần sửa đổi không tham gia vào khóa. Đầu tiên sử dụng thủ tục tìm
bản ghi đó và tiến hành sửa đổi nếu tìm thấy.
Ví dụ: Cho quan hệ DS_LOP(stt, hoten, ngaysinh, quequan) được lưu trữ bởi
một tệp dữ liệu bao gồm một tập các bản ghi có cùng khuân dạng và có độ dài cố
định. Mỗi bản ghi gồm các trường:
• Stt: là trường khóa, có kiểu số nguyên và chiếm 2 Bytes.
• Hoten: là trường có kiểu kí tự và chiếm 30 Bytes.
• Ngaysinh: là trường có kiểu kí tự và chiếm 8 Bytes
• Quequan: là trường có kiểu kí tự và chiếm 80 Bytes
Để đơn giản ta giả sử các khối có kích thước là 256 Bytes. Nếu ta lưu trữ các
bản ghi của dữ liệu DS_LOP theo tổ chức tệp băm thì mỗi một khối cần có một con
trỏ 4 Bytes để móc nối tới khối khác. Do vậy mỗi khối có khả năng chứa được 2 bản
ghi của tệp này.
Giả sử tệp DS_LOP có 10 bản ghi và để tiết kiệm không gian chúng ta chỉ thể
hiện các giá trị của trường khóa cho mỗi bản ghi. Và tổ chức tệp băm với 4 cụm với
hàm băm h(K)= K mod 4. Khi đó tệp dữ liệu DS_LOP được thể hiện
Ta chỉ minh họa hai thao tác chính là thêm và xóa trong bốn thao tác trên. Vì
thao tác tìm kiếm luôn được thực hiện đầu tiên trong các thao tác này, còn thao tác
sửa đổi có thể quy về thực hiện một thao tác xóa và một thao tác thêm.
Giả sử cần thêm một bản ghi có giá trị khóa là 25. Đầu tiên chúng ta thực hiện
thủ tục tìm kiếm bản ghi có giá trị khóa là 25. Để tìm bản ghi này, ta tính hàm băm
h(25)= 25 mod 4 =1 và do đó địa chỉ cụm là 1. Tiếp đến chúng ta duyệt từng khối của
cụm này và không tìm thấy bản ghi nào có giá trị khóa là 25. Như vậy, bản ghi này
chưa có trong tệp dữ liệu và chúng ta thêm nó vào khối đầu tiên trong cụm còn chỗ
trống. Tác động của thao tác này được thể hiện
Bây giờ cần xóa một bản ghi có giá trị khóa là 14. Trước tiên chúng ta thực
hiện thủ tục tìm kiếm bản ghi có giá trị khóa là 14. Để tìm bản ghi này, ta tính hàm
băm h(14)= 14 mod 4 =2 và do đó địa chỉ cụm là 2. Tiếp đến chúng ta duyệt từng khối
của cụm này và tìm thấy bản ghi có giá trị khóa là 14 nằm tại khối đầu tiên của cụm.
Trong khối này có chứa các bản ghi khác nên bản ghi này bị loại bỏ. Tác động của
thao tác này được thể hiện
Mỗi khối trong tệp dữ liệu chính chứa cố định một lượng bản ghi và được đại
diện bởi một cặp (k, d). Trong đó, k là giá trị khóa của bản ghi đầu tiên trong khối và
d là địa chỉ của khối hay con trỏ khối.
Ví dụ với khối chứa được m bản ghi như hình dưới và thường thỏa mãn
K1<K1,2< … < K1,m
Khi đó, khối này được đại diện bởi cặp (K1, d1)
Với cách tổ chức trên, tệp chỉ dẫn bao gồm n bản ghi tương ứng với n cặp (k,
d) với k là giá trị khóa của bản ghi đầu tiên trong khối và d là địa chỉ của khối hay con
trỏ khối. Do vậy ta thấy tệp chỉ dẫn nhỏ hơn nhiều tệp dữ liệu chính và được sắp xếp
theo thứ tự tăng dần. Vì mỗi khối trong tệp dữ liệu chính tương ứng với một bản ghi
trong tệp chỉ dẫn. Như thế, một giá trị khóa của một bản ghi bất kỳ nào đó trong tệp
dữ liệu chính có thể không xuất hiện trong tệp chỉ dẫn. Khi cần tìm kiếm một bản ghi
trong tệp dữ liệu chính theo giá trị khóa, dựa vào tệp chỉ dẫn, chúng ta xác định vị trí
của khối (có thể) chứa bản ghi cần tìm. Giả sử, chúng ta cần tìm bản ghi có giá trị
khóa là K1 trong tệp dữ liệu chính. Dựa vào tệp chỉ dẫn, chúng ta sẽ xác định được
bản ghi (K2, d) với d là địa chỉ của khối có thể chứa bản ghi cần tìm. Dễ dàng thấy bản
ghi (K2, d) thỏa mãn K2 – là giá trị lớn nhất không vượt quá K1 và nói rằng K2 phủ
K1. Để tìm bản ghi (K2, d) trên trong tệp chỉ dẫn chúng ta có hai chiến lược tìm kiếm:
tìm kiếm tuần tự và tìm kiếm nhị phân.
Tìm kiếm trên tệp chỉ dẫn
Phương pháp tìm kiếm tuần tự: Duyệt tệp chỉ dẫn từ bản ghi đầu tiên, tìm
kiếm tại mỗi bản ghi cho tới khi tìm thấy một bản ghi có giá trị khóa K2 sao cho K2
phủ K1. Phương pháp này hoạt động khá chậm trên các tệp chỉ dẫn nên không được ưa
chuộng.
Phương pháp tìm kiếm nhị phân: Do tệp chỉ dẫn luôn được sắp xếp nên tìm
kiếm nhị phân rất hiệu quả. Giả sử tệp chỉ dẫn có n bản ghi (pK1, d1), (pK2, d2), …,
(pKn, dn). Ta so sánh K1 với giá trị khóa K2=pK[n/2]. Nếu K1 <K2 thì bản ghi cần tìm
nằm trong các bản ghi (pK1, d1), (pK2, d2), …, (pK[n/2]-1, d[n/2]-1). Ngược lại thì bản ghi
cần tìm nằm trong các bản ghi (pK[n/2], d[n/2]), …,(pKn, dn). Quá trình trên được lặp
cho đến khi còn một bản ghi và bản ghi đó là bản ghi cần tìm.
Thực tế, trong tệp chỉ dẫn cho phép nhiều bản ghi được xếp vào trong một
khối. Khi đó, ta lấy giá trị khóa bản ghi đầu tiên của khối ở giữa để so sánh với K1.
Thực hiện như trên cho đến khi còn một khối thì dùng phương pháp tuần tự để tìm.
Các thao tác trên tổ chức tệp chỉ dẫn
Tìm kiếm một bản ghi
Giả sử cần tìm một bản ghi nào đó có giá trị khóa là K1. Đầu tiên, dựa vào tệp
chỉ dẫn, tìm bản ghi (K2, d) sao cho K2 phủ K1. Tại tệp dữ liệu chính, tìm bản ghi có
khóa là K1 trong khối có địa chỉ là d. Trong khối có địa chỉ d, chúng ta có thể sử dụng
phương pháp tìm kiếm tuần tự hay nhị phân để tìm bản ghi thỏa mãn. Nếu không có
bản ghi nào trong khối thỏa mãn thì bản ghi cần tìm kiếm không tồn tại.
Thêm một bản ghi
Giả sử cần thêm một bản ghi có giá trị khóa là K1. Dùng thủ tục tìm kiếm trên,
xác định được bản ghi (K2, d) trong tệp chỉ dẫn thỏa mãn K2 phủ K1. Trong tệp dữ liệu
chính, khối có địa chỉ là d có thể chứa bản ghi cần thêm và nếu tìm kiếm thấy bản ghi
này thì việc thêm bản ghi mới không hợp lệ. Trong trường hợp ngược lại, bản ghi này
sẽ được thêm vào tệp dữ liệu chính như sau:
- Nếu trong khối có địa chỉ d còn trống thì thêm bản ghi này vào khối đó
đúng theo thứ tự sắp xếp của khóa. Chú ý rằng nếu bản này được thêm ở
đầu khối thì trong tệp chỉ dẫn, bản ghi (K2, d) được sửa thành (K1, d).
- Nếu trong khối có địa chỉ d không còn trống. Khi đó, nếu bản ghi có giá trị
khóa lớn nhất trong khối d (kể cả bản ghi sẽ thêm) sẽ chuyển sang làm bản
ghi đầu tiên của khối d +1 (nếu không có thì thành lập khối mới). Việc
thêm này kéo theo phải sửa các khóa tương ứng với các khối d, d +1, …
trong tệp chỉ dẫn cho phù hợp.
Xóa một bản ghi
Quá trình được thực hiện giống như thêm bản ghi. Nếu khi xóa một bản ghi
mà tạo nên một khối rỗng thì đồng thời xóa luôn khối này.
Sửa đổi một bản ghi
Để sửa một bản ghi nào đó, đầu tiên dùng thủ tục tìm kiếm bản ghi và định vị
vào bản ghi đó.
- Nếu các trường cần sửa không tham gia vào khóa thì việc sử dổi được tiến
hành bình thường, giá trị bản ghi sau khi được sửa sẽ ghi vào vị trí cũ.
- Nếu các trường cần sửa tham gia vào khóa thì quá trình sửa được coi là
quá trình xóa và thêm một bản ghi.
Chú ý: Tệp dữ liệu chính không nhất thiết phải được sắp xếp. Thấy ngay điều này nếu
tệp chỉ dẫn gồm các bản ghi (k, d) thỏa mãn:
- Tương ứng với mỗi bản ghi của tệp dữ liệu chính là một bản ghi của tệp chỉ
dẫn;
- Bản ghi (k, d) với k là giá trị khóa, d là địa chỉ của bản ghi trong tệp dữ liệu
chính.
Ví dụ: Chúng ta sẽ lưu trữ tệp DS_LOP trong ví dụ ở trên gồm10 bản ghi, mỗi
bản ghi chiếm 120 Bytes theo tổ chức tệp chỉ dẫn. Để đơn giản ta giả sử các khối có
kích thước là 256 Bytes. Nếu ta lưu trữ các bản ghi của dữ liệu DS_LOP theo tổ chức
tệp chỉ dẫn thì mỗi một khối cần có một con trỏ 4 Bytes để móc nối tới khối khác. Do
vậy mỗi khối có khả năng chứa được 2 bản ghi của tệp này. Để tiết kiệm không gian
chúng ta chỉ thể hiện các giá trị của trường khóa cho mỗi bản ghi. Và tổ chức chỉ dẫn
đối với tệp dữ liệu DS_LOP được thể hiện
Ta chỉ minh họa hai thao tác chính là thêm và xóa trong bốn thao tác trên. Vì
thao tác tìm kiếm luôn được thực hiện đầu tiên trong các thao tác này, còn thao tác
sửa đổi có thể quy về thực hiện một thao tác xóa và một thao tác thêm.
Giả sử cần thêm một bản ghi có giá trị khóa là 29 vào tệp dữ liệu trên. Đầu
tiên, dùng thủ tục tìm kiếm ta xác định bản ghi (14, 5) trong tệp chỉ dẫn có khóa phủ
khóa của bản ghi cần thêm. Theo con trỏ chỉ dẫn, chúng ta đi tới khối có thể chứa bản
ghi cần thêm. Tìm kiếm trong khối này, chúng ta không thấy bản ghi nào có giá trị
khóa là 29. Do khối này đã hết chỗ để thêm nên bản ghi có giá trị khóa lớn nhất sẽ
chuyển sang làm bản ghi của khối tiếp theo. Thêm bản ghi có giá trị khóa là 29 vào
khối 5 theo thứ tự sắp xếp của khóa, sửa lại bản ghi chỉ dẫn (78,6) thành (42,6). Tác
động của thao tác này có dạng
Tiếp theo, giả sử cần cần xóa bản ghi có giá trị khóa là 14. Bước đầu dùng thủ
tục tìm kiếm ta xác định bản ghi (14, 5) trong tệp chỉ dẫn có khóa phủ khóa của bản
ghi cần xóa. Theo con trỏ chỉ dẫn, chúng ta đi tới khối 5 có thể chứa bản ghi cần xóa.
Tìm kiếm trong khối này, chúng ta xác định được bản ghi có giá trị khóa là 14 nằm ở
đầu khối và khối này còn chứa bản ghi khác. Do vậy, xóa bản ghi này và điều chỉnh
bản ghi chỉ dẫn (14, 50 thành (29, 5). Tác động của thao tác này có dạng
A B-tree whose keys are the consonants of English. An internal node x containing n[x] keys
has n[x] + 1 children. All leaves are at the same depth in the tree. The lightly shaded nodes are
examined in a search for the letter R.
Tổng quát, cấu trúc một nút của B-cây có dạng:
P0 K1 P1 K2 …. Kn Pn
Trong đó, K1, K2, ..Kn là khóa và n +1 con trỏ P0, P1, …, Pn thỏa mãn: K1< K2
< ... <Kn.
Đối với các nút trong, các đặc điểm sau thể hiện tính chất của B-cây:
- Mọi khóa trong cây con được trỏ bởi con trỏ Pi đều nhỏ hơn Ki+1 với i=0,
1, … , n-1
- Mọi khóa trong cây con được trỏ bởi con trỏ Pn đều lớn hơn Kn
Ta thấy, các nút của B-cây thực chất là khối tệp chỉ dẫn. Các khối tệp chỉ dẫn
được phân theo từng mức, mức càng cao độ chi tiết càng lớn.
Các thao trên tổ chức B-cây
Tìm kiếm một bản ghi
Giả sử cần tìm kiếm bản ghi có giá trị khóa là x. Đầu tiên cần xác định đường
từ gốc tới nút lá có thể chứa bản ghi này. Ta sẽ duyệt liên tiếp các nút của B-cây kể từ
nút gốc. Tại mỗi nút sẽ xác định con trỏ đi tới nút tiếp theo. Giả sử tại nút đang xét có
dạng (p0, k1,p1,k2, …, kn, pn), ta sử dụng thủ tục sau:
So sánh x với các khóa k1,k2, …, kn. Tồn tại một chỉ số i sao cho ki lớn nhất
mà không vượt x (trong trường hợp ngược lại, tức x<k1 thì i chọn là 0). Khi đó chọn
con trỏ pi để xét tiếp nút được con trỏ này trỏ tới. Cho tới khi nút cần xét là nút lá thì
tìm bản ghi có giá trị khóa x theo phương pháp tuần tự. Nếu không tìm thấy bản ghi
nào có giá trị khóa là x thì không tồn tại bản ghi này trong tệp.
Thêm một bản ghi
Giả sử cần thêm một bản ghi có giá trị khóa là x. Đầu tiên cần xác định nút lá
sẽ chứa bản ghi này. Thủ tục xác định nút lá như thủ tục tìm kiếm một bản ghi và tìm
được nút lá là L.
Nếu nút lá L còn chỗ trống thì thêm bản ghi mới theo đúng trình tự sắp xếp
của giá trị khoá.
Nếu nút lá L hết chỗ trống, đầu tiên tạo thêm một nút lá L1 mới. Chuyển nửa
dữ liệu cuối của L sang L1 rồi bổ sung bản ghi có khoá x vào vị trí tương ứng trong L
hay L1.
Giả sử nút H là nút cha trực tiếp của nút L, khi đó phải thêm một cặp (p1, k1)
vào H trong đó p1 là con trỏ trỏ tới lá L1 và k1 là khoá bé nhất chứa trong L1. Nếu
trong H không có con trỏ rỗi thì việc thêm (p1, k1) vào H dẫn tới phải tách H thành 2
như nút L. Quá trình này có thể làm lan truyền tới tận nút gốc của cây dọc theo đường
dẫn đã chọn.
Xóa một bản ghi
Giả sử cần xoá bản ghi có giá trị khóa là x. Đầu tiên cần xác định nút lá sẽ
chứa bản ghi này. Thủ tục xác định nút lá như thủ tục tìm kiếm một bản ghi và tìm
được nút lá là L.
Nếu bản ghi cần xoá là bản ghi đầu tiên của L thì phải tìm tới nút H ngay trên
nút L để chỉnh lại giá trị khoá đầu tiên của L có trước đó. Nếu L lại là nút con đầu tiên
của H thì khoá đầu tiên của L không đặt được ở H, khi đó không cần thiết phải chỉnh
sửa nữa. Tuy nhiên có thể khoá đầu tiên đó của H lại xuất hiện ở một nút trên đó. Do
vậy việc tìm và chỉnh khoá này vẫn phải tiếp tục ngược lên cho tới tận gốc của cây
dọc theo đường dẫn đã chọn
Nếu sau khi loại bỏ khoá x của nút L, nút L trở thành một nút chứa số bản ghi
dưới m/2 , khi đó cần phải chỉnh lại cặp (p, k) ứng với L trong nút trên là nút H để
thể hiện sự thay đổi đã xảy ra. Việc thay đổi này có thể làm cho nút H có thể ít hơn
m/2 cặp (p, k), khi đó xem xét các nút anh em bên trái hoặc bên phải nó có hơn m/2
+1 cặp (p, k) để phân bổ lại các cặp này cho đúng thứ tự sao cho mỗi nút ít nhất có
m/2 cặp (k, p). Ngược lại, nếu nút bên trái (hoặc bên phải) có đúng m/2 cặp, khi đó
ghép p và p1 thành một nút mới với 2*m/2 -1cặp (k, p) và con trỏ ứng với nút trê.
Quá trình này có thể lan truyền ngược lên tới tận gốc.
Ví dụ: Chúng ta sẽ lưu trữ tệp DS_LOP trong ví dụ ở trên gồm 11 bản ghi, mỗi
bản ghi chiếm 120 Bytes theo tổ chức B-cây. Để đơn giản ta sẽ lưu trữ các bản ghi của
dữ liệu DS_LOP bởi một B-cây cấp 3. Mỗi khối ứng với nút lá chứa được tối đa 2
bản. B-cây cấp 3 đối với tệp DS_LOP được thể hiện:
Ta chỉ minh họa hai thao tác chính là thêm và xóa trong bốn thao tác trên. Vì
thao tác tìm kiếm luôn được thực hiện đầu tiên trong các thao tác này, còn thao tác
sửa đổi có thể quy về thực hiện một thao tác xóa và một thao tác thêm.
Giả sử cần thêm một bản ghi có giá trị khóa là 29 vào tệp dữ liệu trên. Đầu tiên,
dùng thủ tục tìm kiếm bản ghi này. Từ gốc của B-cây, tại khối B1, do 5<29<42 nên đi
theo con trỏ thứ hai trong B1 đến B3. Tại B3, do 13<29 nên đi theo con trỏ thứ hai
của B3 đến B8. Như vậy, đường dẫn mà chúng ta tìm được là B1, B3, B8. Tại B8,
theo thứ tự sắp xếp ta có 13, 14, 29, tuy nhiên, B8 không còn đủ không gian nhớ để
chứa thêm một bản ghi dữ liệu mới có giá trị khoá là 29. Do vây, chúng ta xin cấp
thêm một khối mới, khối B12, và đặt 29 vào B12.
Bây giờ, chúng ta phải thêm một bản ghi chỉ dẫn có giá trị khoá là 29 và con trỏ
trỏ tới B12 vào B3. Giá trị 29 được chọn vì nó là giá trị khoá bé nhất trong khối B12.
Thao tác thêm này dẫn tới có một con trỏ và ba bản ghi chỉ dẫn. Do B3 không có khả
năng chứa thêm được một bản ghi chỉ dẫn mới nên chúng ta lại xin cấp một khối mới,
khối B13. Các bản ghi chỉ dẫn với các con trỏ tới B7, B8 được xếp vào B3, còn bản
ghi chỉ dẫn tới B12, B9 được đặt vào B13.Tiếp theo chúng ta thêm một bản ghi chỉ
dẫn có giá trị khoá là 34 và con trỏ tới B13 vào B1. Do B1 không có khả năng chứa
thêm được một bản ghi chỉ dẫn mới nên chúng ta lại xin cấp một khối mới, khối B14.
Các bản ghi chỉ dẫn với các con trỏ tới B2 và B3 được xếp vào B1, còn bản ghi chỉ
dẫn tới B13, B4 được đặt vào B14. Cuối cùng, chúng ta tạo một khối mới, khối B15,
gốc của B-cây với hai con trỏ trỏ tới B1 và B14. Cây kết quả được chỉ ra ở hình dưới:
Giả sử cần xoá bản ghi có giá trị khóa là 5 ở tệp dữ liệu trên. Thủ tục tìm kiếm
bản ghi này cho ta biết đường dẫn từ nút gốc đến nút lá tương ứng với khối có khả
năng chứa bản ghi này là B15, B1, B3, B7. Chúng ta tìm thấy bản ghi này tại đầu khối
B7 và xoá nó. Do bản ghi này đứng đầu khối nên chúng ta phải lan truyền sự kiện này
ngược lên trên với giá trị nhỏ nhất trong B7 là 12. Vì B7 là nút con trái nhất của B3
nên không thay đổi tại nút này mà truyền tiếp đến khối B1. Do B3 không phải là nút
con trái nhất của B1 nên khoá trong B1 phải thay đổi và chúng ta thay 5 thành 12 ở
đó.
Các phép toán đại số quan hệ được chia thành hai nhóm. Một nhóm bao gồm
các phép toán tập hợp lấy từ lý thuyết tập hợp toán học. Các phép toán đó là phép
hợp, phép giao, phép trừ tập hợp và phép tích Đề các. Nhóm kia bao gồm các phép
toán được xây dựng đặc biệt cho các cơ sở dữ liệu quan hệ. Các phép toán đó là phép
chọn, phép chiếu, phép nối và một số các phép toán khác.
Giả sử ta có quan hệ
SINHVIEN MASV HO TEN LOP CSDL1
444101268 Lê Minh 41.01 5
444102156 Phan Thị Hoa 41.01 8
444103125 Trần Hải Yến 41.01 8
444105321 Võ Văn Tần 41.02 9
444105411 Vũ Thị Hoa 41.02 4
giá trị các dãy ký tự được xem như có thứ tự dựa trên việc so sánh các dãy ký tự. Nếu
miền giá trị của một thuộc tính là một tập hợp các giá trị không có thứ tự thì chỉ có
các phép so sánh trong tập hợp { =, ≠ } là có thể áp dụng được. Ngoài ra, có thể còn
các phép so sánh bổ sung, chẳng hạn như “ là một dãy con của…” hoặc “trong khoảng
từ… đến…”.
Kết quả một phép chọn được xác định như sau: <Điều kiện chọn> được áp
dụng cho mỗi bộ t trong R một cách độc lập. Điều đó được thực hiện bằng cách thay
thế mỗi thuộc tính Ai trong điều kiện chon bằng giá trị t[Ai] của nó trong bộ. Nếu điều
kiện chọn cho giá trị đúng thì bộ t sẽ được chọn. Tất cả các bộ được chọn xuất hiện
trong kết quả của phép chọn. Các phép toán logic AND, OR, NOT được thực hiện
theo quy tắc bình thường của chúng.
Phép chọn là phép toán một ngôi, nghĩa là nó được áp dụng cho một quan hệ.
Hơn nữa, phép chọn được áp dụng cho từng bộ một cách độc lập, vì vậy, các điều
kiện chọn không thể liên quan đến nhiều bộ. Quan hệ kết quả của phép chọn có cấp
giống như cấp của R. Số các bộ trong quan hệ kết quả luôn luôn nhỏ hơn hoặc bằng số
các bộ trong R.
Phép chọn là một phép toán có tính chất giao hoán, nghĩa là
R( < Điều kiện 1>) (< Điều kiện 2>) = R(< Điều kiện 2>)(< Điều kiện 1>)
Hơn nữa ta có thể kết hợp một loạt các phép chọn thành một phép chọn đơn
giản bằng cách sử dụng phép toán AND. Ví dụ:
R(< Điều kiện 1>) (< Điều kiện 2>) = R(< Điều kiện 2>AND< Điều kiện 1>)
hay đơn giản hơn ta có thể viết R(< Điều kiện 2>, < Điều kiện 1>)
Phép chiếu (PROJECT)
Nếu ta coi một quan hệ như một bảng thì phép chọn chọn một số hàng của
bảng thoả mãn điều kiện chọn và bỏ qua các hàng không thoả mãn điều kiện chọn.
Phép chiếu là phép toán chọn một số cột của bảng. Nếu chúng ta chỉ quan tâm đến
một số thuộc tính của quan hệ, chúng ta dùng phép chiếu để chiếu lên các thuộc tính
đó. Phép chiếu được ký hiệu là:
R[<danh sách các thuộc tính>]
trong đó <danh sách các thuộc tính> là một danh sách con các thuộc tính của
quan hệ R. Nói chung R là một biểu thức đại số quan hệ. Trường hợp đơn giản nhất
nó là tên của một quan hệ của cơ sở dữ liệu. Kết quả của phép chiếu là một quan hệ
chỉ có các thuộc tính nằm trong <danh sách các thuộc tính> và có cùng thứ tự như
thứ tự của chúng có trong danh sách. Như vậy, cấp của quan hệ kết quả là số các
thuộc tính có trong <danh sách các thuộc tính>.
Nếu <danh sách các thuộc tính> chỉ bao gồm các thuộc tính không phải thuộc
tính khoá của R thì quan hệ kết quả có thể có những bộ trùng nhau. Phép chiếu loại bỏ
mọi bộ trùng lặp, và như vậy, kết quả của phép chiếu là một tập hợp các bộ và là một
quan hệ đúng đắn.
Ví dụ, phép chiếu SINHVIEN(LOP, CSDL1) cho kết quả là một quan hệ có
các thuộc tính LOP, CSDL1 như sau:
SINHVIEN LOP CSDL1
41.01 5
41.01 8
41.02 8
41.02 4
Số các bộ trong quan hệ kết quả từ một phép chiếu luôn luôn nhỏ hơn hoặc
bằng số các bộ trong R. Nếu danh sách chiếu là một siêu khoá của R (nghĩa là nó chứa
một khoá nào đó của R) thì quan hệ kết quả có cùng một số bộ như R. Ngoài ra, nếu
<danh sách 2> chứa tất cả các thuộc tính có trong <danh sách 1> thì
R[< danh sách1>][< danh sách2> ] = R[< danh sách 1> ]
Phép chiếu không có tính giao hoán.
Phép đặt lại tên (RENAME)
Chúng ta có thể áp dụng nhiều phép toán quan hệ liên tiếp nhau. Trong trường
hợp đó hoặc chúng ta có thể viết các phép toán như là một biểu thức đại số quan hệ
đơn bằng cách xếp lồng các phép toán lại với nhau, hoặc chúng ta có thể áp dụng mỗi
phép toán tại một thời điểm và tạo ra các quan hệ kết quả trung gian. Trong trường
hợp tạo các quan hệ trung gian, ta phải đặt tên cho quan hệ đó. Ví dụ: Để đưa ra TEN
và điểm CSDL1 của các SINHVIEN lớp 41.01 phải áp dụng một phép chọn và một
phép chiếu. Chúng ta có thể viết một biểu thức đại số quan hệ đơn như sau :
SINHVIEN[ TEN, CSDL1](LOP=”41.01”)
Một cách khác, chúng ta có thể tạo ra kết quả trung gian và viết biểu thức trên
thành dãy các phép toán như sau:
KQTG ← SINHVIEN(LOP=”41.01”)
R ← KQTG[TEN, CSDL1]
Thông thường việc phân tích một dãy phức tạp các phép toán bằng cách chỉ ra
các quan hệ kết quả trung gian là dễ hơn việc viết một biểu thức đại số quan hệ đơn.
Chúng ta có thể dùng kỹ thuật này để đặt lại tên (Rename) cho các thuộc tính trong
các quan hệ trung gian và kết quả. Để đặt lại tên cho các thuộc tính của một quan hệ,
chúng ta liệt kê các tên mới của các thuộc tính trong cặp dấu ngoặc. Ví dụ:
KQTG{R(TEN,CSDL)} ← KQTG[ TEN, CSDL1]
Cho kết quả là quan hệ R, trong đó thuộc tính CSDL1 được đặt lại tên thành
CSDL.
Nếu không có việc đặt lại tên thì tên của các thuộc tính trong quan hệ kết quả
của một phép chọn là giống như các tên trong quan hệ ban đầu và có cùng một thứ tự
như thứ tự của các thuộc tính đó. Đối với phép chiếu, nếu không có việc đặt lại tên thì
quan hệ kết quả có các tên thuộc tính giống như các tên trong danh sách chiếu và có
cùng thứ tự như chúng xuất hiện trong danh sách.
Chúng ta có thể định nghĩa một phép toán đặt lại tên , nó có thể đặt lại tên cho
một tên quan hệ hoặc các tên thuộc tính hoặc cả hai. Phép đặt lại tên được ký hiệu là:
R{S(B1,B2,…Bn)} hoặc R(B1,B2,…Bn)
trong đó S là tên quan hệ mới, B1,B2,…Bn là các tên thuộc tính mới. Biểu
thức thứ nhất đặt lại tên quan hệ và các thuộc tính của nó. Nếu các thuộc tính của R là
A1,A2, ...An thì sau khi đặt lại tên, quan hệ có tên mới là S còn các thuộc tính có tên
mới là B1, B2, …, Bn. Biểu thức thứ hai chỉ đặt lại tên các thuộc tính, nếu các thuộc
tính của R là A1,A2, ...An thì sau khi đặt lại tên chúng có tên là B1, B2, ...Bn.
Các phép toán lý thuyết tập hợp
Nhóm tiếp theo của các phép toán đại số quan hệ là các phép toán toán học
thông thường trên các tập hợp. Đó là các phép toán hợp, giao và trừ tập hợp. Các phép
toán này là các phép toán hai ngôi, nghĩa là mỗi phép toán được áp dụng cho hai tập
hợp. Khi áp dụng các phép toán này cho cơ sở dữ liệu quan hệ, hai quan hệ tham gia
vào một trong các phép toán trên phải có kiểu của các bộ như nhau, hay nói cách
khác, chúng phải có cùng một cấu trúc. Điều kiện này được gọi là tương thích đồng
nhất (khả hợp). Hai quan hệ R(A1,A2,…, An) và S(B1, B2, …,Bn) được gọi là khả hợp
nếu chúng có cùng cấp n và dom(Ai) = dom(Bi) với 1<= i <= n. Điều đó có nghĩa là
hai quan hệ có cùng số các thuộc tính và mỗi cặp thuộc tính tương ứng có cùng miền
giá trị.
Các phép toán được định nghĩa như sau:
. Phép hợp: Hợp của hai quan hệ R và S, được ký hiệu là R + S, cho kết quả là
một quan hệ chứa tất cả các bộ có trong R hoặc ở trong S hoặc ở trong cả hai. Các bộ
trùng lặp bị loại bỏ.
. Phép giao: Giao của hai quan hệ R và S , được ký hiệu là R & S , cho kết quả
là một quan hệ chứa tất các các bộ có trong cả hai quan hệ R và S.
. Phép trừ quan hệ: Phép trừ quan hệ R và S , được ký hiệu là R - S, cho kết
quả là một quan hệ chứa tất cả các bộ có trong R nhưng không có trong S.
Ví dụ, xét hai quan hệ:
R HOTEN TUOI GIOI S HOTEN TUOI GIOI
AA 20 Nam BB 18 Nữ
BB 18 Nữ EE 20 Nam
CC 21 Nam DD 25 Nữ
DD 25 Nữ FF 21 Nam
dụng trên đó không phải là tương thích đồng nhất. Phép toán này được sử dụng để nối
các bộ của hai quan hệ vào một kiểu kết hợp. Kết quả của
R(A1, A2, .. , An)× S(B1, B2, …,Bm)
là một quan hệ Q với n+m thuộc tính Q(A1, A2,…, An, B1, B2,…,Bm). Quan
hệ kết quả Q có các bộ được tạo thành do sự kết hợp một bộ của R và một bộ của S.
Ví dụ, xét hai quan hệ R và S như sau:
R A1 A2 A3 S B1 B2 B3
aa bb cc dd da db
ab ba ac cd cb ac
R×S A1 A2 A3 B1 B2 B3
aa bb cc dd da db
aa bb cc cd cb ac
ab ba ac dd da db
ab ba ac cd cb ac
Như vậy, nếu R có nR bộ và S có nS bộ thì R× S có nR*nS bộ. Phép toán này
nếu áp dụng một mình thì không có ý nghĩa mấy. Nó chỉ có lợi khi tiếp theo bằng một
phép chọn các giá trị tương thích của các thuộc tính xuất phát từ các quan hệ thành
phần. Tích Đềcác kết hợp với một phép chọn cho ta một phép nối.
Phép nối (JOIN)
Phép nối được ký hiệu là và được dùng để kết hợp các bộ có liên hệ với
nhau từ hai quan hệ thành một bộ. Phép toán này rất quan trọng đối với cơ sở dữ liệu
quan hệ có nhiều bảng bởi vì nó cho phép ta xử lý các mối liên kết giữa các quan hệ.
Dạng tổng quát của phép nối trên hai quan hệ R(A1, A2,…,An) và S(B1,B2,…, Bm) là
R S(< Điều kiện nối>)
Kết quả của phép nối là một quan hệ Q(A1,A2,…,An,B1,B2,…,Bm) có n+m
thuộc tính. Mỗi bộ của Q là một sự kết nối giữa một bộ của R và một bộ của S khi
chúng thoả mãn điều kiện nối. Sự khác nhau giữa tích Đề các và phép nối là ở chỗ
trong phép nối, chỉ có các bộ thoả mãn điều kiện nối mới xuất hiện trong kết quả,
trong khi đó trong tích Đề các mọi tổ hợp của các bộ đều có trong kết quả. Điều kiện
nối được chỉ ra trên các thuộc tính của hai quan hệ R và S và được tính toán cho mỗi
tổ hợp các bộ. Mọi tổ hợp bộ mà điều kiện nối là đúng được chứa trong quan hệ kết
quả Q như là một bộ đơn. Một điều kiện nối tổng quát có dạng
<điều kiện> AND <điều kiện> AND … AND <điều kiện>
trong đó mỗi điều kiện có dạng Ai θ Bj, Ai là một thuộc tính của R, Bj là một
thuộc tính của S, Ai và Bj có cùng miền và θ là một trong các dấu phép toán so sánh
{<, <=, =, >=, >, ≠}. Một phép toán nối với điều kiện tổng quát như vậy gọi là một
phép nối tê-ta. Các bộ có các thuộc tính nối là null không xuất hiện trong kết quả.
Theo nghĩa đó, phép toán không nhất thiết phải xử lý mọi thông tin trong các quan hệ
tham gia. Ví dụ :
Giả sử ta có hai quan hệ R và S như sau:
R A1 A2 A3 S B1 B2 B3
Aa Ca Ba Ba Aaa Bbb
Ab Cb Bb Bb Ccc Ddd
Ac Ca Ba
Ad Cc Null
Ae Cd Bb
Khi đó kết quả của phép nối tê-ta R và S với điều kiện A3 = B1 sẽ cho kết quả
là:
R S(A3=B1) A1 A2 A3 B1 B2 B3
Aa Ca Ba Ba Aaa Bbb
Ab Cb Bb Bb Ccc Ddd
Ac Ca Ba Ba Aaa Bbb
Ae Cd Bb Bb Ccc Ddd
Phần lớn các phép nối chỉ cho phép các điều kiện nối với các so sánh bằng.
Những phép nối chỉ sử dụng phép so sánh bằng được gọi là nối bằng (equi join). Ví
dụ trên là một phép nối bằng. Chú ý rằng trong kết quả của phép nối bằng chúng ta
thấy luôn luôn có một hoặc nhiều cặp thuộc tính có các giá trị như nhau trong mỗi bộ.
Việc có các cặp thuộc tính có giá trị như nhau là thừa, vì vậy người ta đề nghị một
phép nối mới gọi là nối tự nhiên, ký hiệu là *. Phép nối tự nhiên nhằm loại bỏ thuộc
tính thứ hai (thuộc tính thừa) trong điều kiện nối bằng. Định nghĩa chuẩn của nối tự
nhiên đòi hỏi hai thuộc tính nối (hoặc mỗi cặp thuộc tính nối) phải có tên như nhau
trong cả hai quan hệ. Nếu các thuộc tính đó không cùng tên thì trước khi nối phải áp
dụng phép toán đặt lại tên. Ví dụ, ta cần nối tự nhiên hai quan hệ R(A1,A2,A3) và
S(B1,B2,B3) như trong ví dụ trên. Để có thể thực hiện được phép nối tự nhiên với điều
kiện so sánh bằng, ta phải đổi tên thuộc tính B1 thành A3, nghĩa là ta phải viết:
R * S(A3, B2,B3)
Phép nối sẽ có kết quả như sau:
R*S A1 A2 A3 B2 B3
Aa Ca Ba Aaa Bbb
Ab Cb Bb Ccc Ddd
Ac Ca Ba Aaa Bbb
Ae Cd Bb Ccc Ddd
Nếu các thuộc tính mà trên đó nối tự nhiên được chỉ ra có tên như nhau thì
việc đặt lại tên là không cần thiết.
Chú ý rằng nếu không có một tổ hợp các bộ nào thoả mãn điều kiện nối thì kết
quả của một phép nối là một quan hệ rỗng không chứa bộ nào. Nói chung, nếu R có
nR bộ và S có nS bộ thì kết quả của phép nối R với S sẽ có số các bộ lớn hơn 0 và
nhỏ hơn nR.nS. Cỡ của một kết quả nối chia cho cỡ cực đại nR.nS tạo nên một tỷ lệ
gọi là chọn lựa nối, đó là một tính chất của mỗi điều kiện nối. Nếu không có điều kiện
nối, mọi tổ hợp các bộ sẽ được chọn và phép nối trở thành một tích Đề các.
Phép nối được sử dụng để kết hợp các dữ liệu từ nhiều quan hệ sao cho các
thông tin có liên hệ với nhau có thể được biểu diễn trong một bảng. Đôi khi phép nối
được áp dụng nối một bảng với chính nó. Chúng ta có thể áp dụng phép nối tự nhiên
và nối bằng để nối nhiều bảng với nhau. Nếu ta nối n bảng với nhau thì phải chỉ ra n-1
điều kiện nối.
Tập hợp đầy đủ các phép toán quan hệ
Người ta đã chỉ rằng tập hợp các phép toán đại số quan hệ {(), [], +, −, ×} là
một tập đầy đủ, nghĩa là mọi phép toán đại số quan hệ khác có thể được biểu diễn
thông qua các phép toán của tập hợp này. Ví dụ, phép giao có thể được biểu diễn bằng
cách sử dụng các phép hợp và trừ tập hợp như sau:
R & S = (R + S) − ((R- S) + (S − R))
Như vậy, nói một cách chính xác là không cần phải có phép giao. Mỗi khi cần
thực hiện một phép giao, ta chỉ cần đưa ra biểu thức phức tạp này là đủ.
Một ví dụ khác, một phép nối có thể được chỉ ra như một tích Đề các và sau
đó là một phép chọn:
R S(< Điều kiện nối>) = R × S(< Điều kiện chọn> )
Một cách tương tự, ta có thể thay thế phép nối tự nhiên bằng một tích Đề các
đi sau một phép đặt lại tên và sau đó là các phép toán chọn và chiếu. Như vậy các
phép toán nối cũng không cần thiết. Tuy nhiên các phép toán đó rất quan trọng bởi vì
chúng tiện dùng và rất thường xuyên được áp dụng trong các cơ sở dữ liệu. Các phép
toán đó được đưa vào trong đại số quan hệ là do tiện dụng hơn là do cần thiết. Một
phép toán khác cũng được đưa vào, đó là phép chia.
Phép chia
Phép chia có lợi cho một loại truy vấn đặc biệt đôi khi có các ứng dụng trong
cơ sở dữ liệu. Phép chia được áp dụng cho hai quan hệ R(Z) và S(X) và được ký hiệu
là R(Z) ÷ S(X), trong đó X ⊂ Z . Giả sử Y = Z - X (như vậy Z = X ∪ Y). Kết quả
của phép chia là quan hệ T(Y) chứa một bộ t nếu các bộ tR xuất hiện trong R với
tR[Y] = t và với tR[X] = tS với mọi bộ tS trong S. Điều đó có nghĩa là để một bộ t
xuất hiện trong kết quả T của phép chia, các giá trị trong t phải xuất hiện trong R
trong sự kết nối với mọi bộ của S.
Ví dụ: Xét phép chia quan hệ R(A,B) cho quan hệ S(A) như hình vẽ dưới đây.
Ta thấy chỉ có các thuộc tính B1 và B4 là kết nối với tất cả các bộ của S ở trong R. Vì
vậy kết quả nhận được là một quan hệ T(B) với hai giá trị của B là B1 và B4.
Phép chia có thế được biểu diễn thông qua các phép toán [], ×, − như sau:
T1←R[Y] ; T2 ← ((S × T1) − R )[Y] ; T ← T1 − T2
R A B S A
A1 B1 A1
A2 B1 A2
A3 B1 A3
A4 B1
A1 B2
A3 B2
A2 B3 T B
A3 B3 B1
A4 B3 B4
A1 B4
A2 B4
A3 B4
Phép chia T(B) = R(A,B) ÷ S(A).
T1 B T1×S A B T1×S-R A B
B1 A1 B1 A1 B3
B2 A1 B2 A2 B2
B3 A1 B3
B4 A1 B4 T2 B
A2 B1 B2
A2 B2 B3
A2 B3
A2 B4 T B
A3 B1 B1
A3 B2 B4
A3 B3
A3 B4
trong đó ℑ là ký hiệu phép toán hàm nhóm, <các thuộc tính nhóm> là một
danh sách các thuộc tính của quan hệ được chỉ ra trong R, <danh sách hàm> là danh
sách các cặp (<hàm>(<thuộc tính>)). Trong các cặp như vậy, <hàm> là một trong các
hàm cho phép như SUM, AVERAGE, MAX, MIN, COUNT, và <thuộc tính> là một
thuộc tính của quan hệ được chỉ ra trong R. Quan hệ kết quả có các thuộc tính nhóm
cộng với một thuộc tính cho mỗi phần tử trong danh sách hàm. Ví dụ, để lấy ra theo
LOP các sinh viên và học phí trung bình của các sinh viên theo từng LOP, ta có thể
viết:
SINHVIEN(LOP ℑ COUNT ( ), AVERAGE(HP))
Kết quả được minh hoạ
LOP COUNT() AVERAGE(HP)
44/41.01 32 127
44/41.02 36 129
44/41.03 33 135
Nếu không chỉ ra thuộc tính nhóm thì các hàm được áp dụng cho các giá trị
thuộc tính của tất cả các bộ trong quan hệ, vì vậy quan hệ kết quả chỉ có một bộ. Cần
chú ý rằng, nói chung, các trùng lặp không được loại bỏ khi hàm nhóm được áp dụng.
Kết quả của việc áp dụng một hàm nhóm là một quan hệ chứ không phải là một đại
lượng vô hướng, thậm chí nếu nó chỉ có một giá trị.
Các phép toán khép kín đệ quy
Một kiểu phép toán khác, nói chung, không chỉ ra được trong các phép toán
đại số quan hệ cơ sở là phép toán khép kín đệ quy. Phép toán này được áp dụng cho
mối liên kết đệ quy giữa các bộ cùng kiểu.Với các phép toán này chúng ta phải sử
dụng kỹ thuật lặp.
Các phép toán nối ngoài (outer join), hợp ngoài (outer union)
Trong phần này chúng ta thảo luận một vài mở rộng của phép toán nối và hợp.
Các phép toán nối mô tả ở trên liên kết các bộ thoả mãn điều kiện nối. Như vậy, các
bộ không có bộ liên kết sẽ bị loại khỏi kết quả nối. Các bộ với giá trị null trong các
thuộc tính nối cũng bị loại. Một tập hợp các phép toán gọi là nối ngoài có thể được sử
dụng khi chúng ta muốn giữ các bộ trong R hoặc S hoặc trong cả hai quan hệ trong
kết quả của phép nối dù chúng có những bộ liên kết trong quan hệ kia hay không. Có
ba phép nối ngoài gọi là nối ngoài trái (left outer join), nối ngoài phải (right outer
join) và nối ngoài đầy đủ (full outer join), được ký hiệu tương ứng là:
R A B C S D E
A1 B1 1 1 7
A1 B2 5 2 7
A2 B2 12 12 3
A2 B3 23 23 10
R S(C<D) A B C D E
A1 B1 1 2 7
A1 B1 1 12 3
A1 B1 1 23 10
A1 B2 5 12 3
A1 B2 5 23 10
A2 B2 12 23 10
A2 B3 23 null null
R S(C>D) A B C D E
A1 B2 5 1 7
A1 B2 5 2 7
A2 B2 12 1 7
A2 B2 12 2 7
A2 B3 23 1 7
A2 B3 23 2 7
A2 B3 23 12 3
null null null 23 10
R S(C=D) A B C D E
A1 B1 1 1 7
A2 B2 12 12 3
A2 B3 23 23 10
A1 B2 5 null null
null null null 2 7
Phép toán hợp ngoài được mở rộng để lấy hợp của các bộ từ các quan hệ nếu
các bộ không tương thích đồng nhất. Phép toán này chỉ lấy hợp của các quan hệ mà
chúng chỉ tương thích bộ phận, nghĩa là chỉ một vài thuộc tính của chúng là tương
thích phép hợp. Điều phải tôn trọng là danh sách các thuộc tính tương thích phải chứa
một khoá cho cả hai quan hệ. Các bộ từ các quan hệ thành phần với cùng một khoá
chỉ được biểu diễn một lần trong kết quả và có giá trị cho tất cả các thuộc tính trong
kết quả. Các thuộc tính không tương thích phép hợp từ bất kỳ quan hệ nào cũng được
giữ trong kết quả và các bộ không có giá trị cho các thuộc tính này cũng được lấp đầy
bằng những giá trị null.
Một số ví dụ về truy vấn trong đại số quan hệ
Tạo tệp chỉ dẫn CREATE INDEX <tên chỉ dẫn> ON <tên bảng> (tên cột)
[ ASC | DSC]
Bổ sung vào bảng INSERT INTO <Tên bảng> [(<danh sách cột>)]
các dữ liệu từ bảng
<câu truy vấn>
khác
Xoá các bản ghi DELETE FROM <tên bảng> [WHERE <điều kiện> ]
trong bảng
Ví dụ:
Thêm Địa chỉ khách hàng
INSERT INTO KhachHang VALUES ("A000", "Trần Thu Thuỷ", "70/42/132 - Ngọc Khánh")
INSERT INTO KhachHang VALUES ("A001", "Nguyễn Thị Oanh", "34 - Trường Chinh")
INSERT INTO KhachHang VALUES ("A002", "Hoàng Anh Tuấn", "75 - Hàng Bồ")
INSERT INTO KhachHang VALUES ("A003", "Lê Thị Thuý Kiều", "1A - Yết Kiêu")
INSERT INTO KhachHang VALUES ("A004", "Dương Đăng Doanh", "167/12/6 - Đường Thành")
INSERT INTO KhachHang VALUES ("A005", "Hồ Mai Thước", "42 - Giảng Võ")
INSERT INTO KhachHang VALUES ("A006", "Vũ Thanh Bình", "92/132 - Võ Văn Tần")
INSERT INTO Ct_HoaDon VALUES (1, "Q1/A002", "B01", 1000, 2000, "156")
INSERT INTO Ct_HoaDon VALUES (2, "Q1/A002", "B02", 6000, 1000, "156")
INSERT INTO Ct_HoaDon VALUES (3, "Q1/A002", "P01", 1000, 2000, "156")
INSERT INTO Ct_HoaDon VALUES (1, "Q1/A003", "P01", 20, 15000000, "156")
INSERT INTO Ct_HoaDon VALUES (2, "Q1/A003", "P02", 20, 10000000, "156")
thể hoặc một kiểu liên kết thì ý nghĩa trở nên rõ ràng. Ngược lại, một quan hệ tương
ứng với một hỗn hợp các thực thể và liên kết thì ý nghĩa trở nên không rõ ràng.
Ở đây có sự dư thừa thông tin. Nếu một đơn vị có nhiều nhân viên làm việc thì
thông tin về đơn vị (Mã số, Tên đơn vị, Mã số người quản lý) được lưu giữ nhiều lần
trong bảng. So với việc dùng hai bảng NHÂNVIÊN và ĐƠNVỊ riêng rẽ như trong
lược đồ “CÔNG TY”, việc sử dụng bảng này làm lãng phí không gian nhớ.
Ngoài việc lãng phí không gian nhớ nó còn dẫn đến một vấn đề nghiêm trọng là
sự dị thường cập nhật. Dị thường cập nhật bao gồm: Dị thường Chèn, dị thường Xoá,
dị thường Sửa đổi. Những dị thường cập nhật này sẽ đưa vào cơ sở dữ liệu những
thông tin “lạ” và làm cho cơ sở dữ liệu mất tính đúng đắn.
Dị thường Chèn: Gây ra khó khăn khi chèn các bộ giá trị vào bảng hoặc dẫn đến
vi phạm ràng buộc. Ví dụ:
Để chèn một bộ giá trị cho một nhân viên mới vào bảng NHÂNVIÊN_ĐƠNVỊ
ngoài các thông tin về nhân viên, ta phải đưa vào các thông tin về đơn vị mà anh ta
làm việc hoặc các giá trị null (nếu nhân viên không làm việc cho đơn vị nào cả). Các
thông tin về đơn vị phải được đưa vào một cách đúng đắn, phù hợp với các thông tin
của đơn vị đó trong các bộ khác. Trong lúc đó, với lược đồ cơ sở dữ liệu “CÔNGTY”
chúng ta không phải lo lắng gì, vì các thông tin về một đơn vị chỉ được lưu trữ một
lần.
Rất khó chèn một đơn vị mới vào quan hệ NHÂNVIÊN_ĐƠNVỊ nếu đơn vị đó
không có nhân viên nào làm việc. Cách giải quyết duy nhất là điền các giá trị null vào
các thuộc tính của nhân viên. Điều đó làm nảy sinh vấn đề về ràng buộc bởi vì
MãsốNV là khóa chính của quan hệ.
Dị thường Xóa: Gây ra việc mất thông tin khi xóa. Ví dụ khi ta xóa một bộ giá
trị trong bảng NHÂNVIÊN_ĐƠNVỊ. Nếu nhân viên tương ứng với bộ giá trị đó là
người cuối cùng làm việc cho đơn vị thì phép xóa sẽ kéo theo việc làm mất thông tin
về đơn vị.
Dị thường Sửa đổi: Gây ra việc sửa đổi hàng loạt khi ta muốn sửa đổi một giá trị
trong một bộ nào đó. Ví dụ, ta muốn sửa giá trị của thuộc tính MãsốNQL của đơn vị
5. Điều đó kéo theo ta phải sửa giá trị của thuộc tính này trong tất cả các bộ ứng với
đơn vị 5. Dựa trên các dị thường ở trên, chúng ta có thể phát biểu nguyên tắc sau:
Nguyên tắc 2: Thiết kế các lược đồ quan hệ cơ sở sao cho không sinh ra những
dị thường cập nhật trong các quan hệ. Nếu có xuất hiện những dị thường cập nhật thì
phải ghi chép lại một cách rõ ràng và phải đảm bảo rằng các chương trình cập nhật dữ
liệu sẽ thực hiện một cách đúng đắn.
Bây giờ ta nối tự nhiên hai quan hệ trên với nhau, ta có quan hệ
MãsốNV MãsốDA Sốgiờ TênDA Địađiểm Tên
NV001 1 32 DA01 Hànội Vân
*** NV001 1 32 DA01 Hànội Giang
NV001 2 7 DA02 Namđịnh Vân
NV016 3 40 DA03 Bắcninh Sơn
*** NV018 1 20 DA01 Hànội Vân
NV018 1 20 DA01 Hànội Giang
Ta thấy các dòng đánh dấu * là các bộ “giả”. Đấy là các bộ giá trị không có trên
thực tế.
Nguyên tắc 4: Thiết kế các lược đồ quan hệ sao cho chúng có thể được nối với
điều kiện bằng trên các thuộc tính là khoá chính hoặc khoá ngoài theo cách đảm bảo
không sinh ra các bộ “giả”. Đừng có các quan hệ chứa các thuộc tính nối khác với các
tổ hợp khoá chính-khoá ngoài. Nếu không tránh được những quan hệ như vậy thì
đừng nối chúng trên các thuộc tính đó, bởi vì các phép nối có thể sinh ra các bộ “giả”.
Như vậy, X xác định hàm Y trong lược đồ quan hệ R khi và chỉ khi nếu hai bộ
của r(R) bằng nhau trên các giá trị của X thì chúng nhất thiết phải bằng nhau trên các
giá trị của Y. Ta có các nhận xét sau:
• Nếu có một ràng buộc trên các trạng thái của R là chỉ có một bộ giá trị duy
nhất của X trong mọi thể hiện quan hệ r(R) thì điều đó kéo theo X → Y với mọi tập
con các thuộc tính Y của R.
• Nếu X → Y thì không thể nói gì về Y → X.
Một phụ thuộc hàm là một tính chất ngữ nghĩa của các thuộc tính. Những người
thiết kế cơ sở dữ liệu sẽ dùng hiểu biết của họ về ý nghĩa của các thuộc tính của R để
chỉ ra các phụ thuộc hàm có thể có trên mọi trạng thái quan hệ của r(R) của R. Khi
ngữ nghĩa của hai tập thuộc tính trong R chỉ ra rằng có thể có một phụ thuộc hàm,
chúng ta sẽ đặc tả phụ thuộc hàm như một ràng buộc. Các trạng thái quan hệ r(R) thoả
mãn các ràng buộc phụ thuộc hàm được gọi là các trạng thái hợp pháp của R, bởi vì
chúng tuân theo các ràng buộc phụ thuộc hàm. Như vậy, việc sử dụng chủ yếu của các
phụ thuộc hàm là dùng để mô tả một lược đồ quan hệ R bằng việc chỉ ra các ràng
buộc trên các thuộc tính phải thoả mãn ở mọi thời điểm.
Một phụ thuộc hàm là một tính chất của lược đồ quan hệ R chứ không phải là
tính chất của một trạng thái hợp pháp r của R. Vì vậy, một phụ thuộc hàm không thể
được phát hiện một cách tự động từ một trạng thái r mà phải do một người hiểu biết
ngữ nghĩa của các thuộc tính xác định một cách rõ ràng. Ví dụ, ta có quan hệ sau
DẠY Giáoviên Mônhọc Tàiliệu
AA Mônhọc1 XX
AA Mônhọc2 YY
BB Mônhọc3 ZZ
CC Mônhọc4 TT
Mới nhìn qua, chúng ta có thể nói có một phụ thuộc hàm Tàiliệu → Mônhọc,
tuy nhiên chúng ta không thể khẳng định được vì điều đó chỉ đúng với trạng thái quan
hệ này, biết đâu trong trạng thái quan hệ khác có thể có hai môn học khác nhau sử
dụng cùng một tài liệu tham khảo. Với một trạng thái cụ thể, chúng ta chỉ có thể
khẳng định là không có một phụ thuộc hàm giữa nhóm thuộc tính này và nhóm thuộc
tính khác. Để làm điều đó chúng ta chỉ cần đưa ra một phản ví dụ. Chẳng hạn, ở trong
quan hệ trên chúng ta có thể khẳng định rằng không có phụ thuộc hàm giữa Giáoviên
và Mônhọc bằng cách chỉ ra ví dụ là AA dạy hai môn học “ Mônhọc1” và “Mônhọc2”
vậy Giáo viên không thể xác định duy nhất Môn học.
Để biểu diễn các phụ thuộc hàm trong một lược đồ quan hệ, chúng ta sử dụng
khái niệm sơ đồ phụ thuộc hàm. Mỗi FD được biểu diễn bằng một đường nằm ngang.
Các thuộc tính ở vế trái của FD được nối với đường biểu diễn FD bằng các đường
thẳng đứng, các thuộc tính ở vế phải của FD được nối với đường biểu diễn FD bằng
mũi tên chỉ đến các thuộc tính.
Ví dụ: Ta có lược đồ quan hệ
2. Các quy tắc suy diễn đối với các phụ thuộc hàm
Chúng ta ký hiệu F là tập các phụ thuộc hàm được xác định trên một lược đồ
quan hệ R. Một phụ thuộc hàm X → Y được gọi là suy diễn được từ một tập các phụ
thuộc hàm F được xác định trên R nếu X → Y đúng trong mỗi trạng thái quan hệ r là
mở rộng hợp pháp của R, nghĩa là mỗi khi r làm thoả mãn mọi phụ thuộc hàm trong
F, X→ Y cũng đúng trong r. Tập hợp tất cả các phụ thuộc hàm suy diễn được từ F
được gọi là bao đóng của F và được ký hiệu là F+. Để xác định một cách suy diễn các
phụ thuộc hàm có hệ thống, chúng ta phải phát hiện một tập hợp các quy tắc suy diễn.
Tập quy tắc này sẽ được sử dụng để suy diễn các phụ thuộc hàm mới từ một tập các
phụ thuộc hàm cho trước. Ta sử dụng ký hiệu F |= X→ Y để ký hiệu phụ thuộc hàm
X→ Y được suy diễn từ tập các phụ thuộc hàm F. Để cho tiện, ta viết tắt phụ thuộc
hàm có dạng {X,Y}→ Z thành XY → Z ( nghĩa là ta nối các biến và bỏ dấu ngoặc
nhọn đi). Có 6 quy tắc suy diễn đối với các phụ thuộc hàm:
QT1 (quy tắc phản xạ) : Nếu X ⊃ Y thì X → Y
QT2 (quy tắc tăng) : { X→ Y } |= XZ →YZ
QT3 (quy tắc bắc cầu) : { X→ Y, Y→ Z } |= X→ Z
QT4 (quy tắc chiếu) : { X→ YZ } |= X→ Y và X→ Z
QT5 (quy tắc hợp) : { X→ Y , X→ Z } |= X→ YZ
QT6 (quy tắc tựa bắc cầu) : { X→ Y, WY→ Z } |= WX→ Z
Quy tắc phản xạ phát biểu rằng một tập hợp các thuộc tính luôn luôn xác định
chính nó hoặc một tập con bất kỳ của nó. Vì QT1 tạo ra các phụ thuộc luôn luôn đúng,
những phụ thuộc như vậy được gọi là tầm thường. Một cách hình thức, một phụ thuộc
hàm X → Y là tầm thường nếu X ⊃Y, ngược lại, nó được gọi là không tầm thường.
Quy tắc tăng nói rằng việc thêm cùng một tập thuộc tính vào cả hai vế của một phụ
thuộc hàm sẽ tạo ra một phụ thuộc hàm đúng đắn. Theo quy tắc 3, các phụ thuộc hàm
là bắc cầu. Quy tắc chiếu (QT4) nói rằng chúng ta có thể bỏ bớt các thuộc tính ra khỏi
vế phải của phụ thuộc hàm. Việc áp dụng nhiều lần quy tắc này có thể tách phụ thuộc
hàm X → {A1, A2,…, An} thành một tập hợp phụ thuộc hàm { X→ A1, X→ A2, ...,
X→ An}. Quy tắc hợp cho phép chúng ta làm ngược lại, ta có thể gộp các phụ thuộc
hàm { X→ A1, X→A2, ..., X→ An} thành một phụ thuộc hàm đơn X→ {A1, A2, ...,
An}.
Có thể chứng minh các quy tắc suy diễn ở trên một cách trực tiếp hoặc bằng
phản chứng dựa trên định nghĩa của phụ thuộc hàm. Để chúng minh phản chứng, ta
giả thiết một quy tắc là không đúng và chỉ ra rằng điều đó là không thể. Sau đây là
chứng minh các quy tắc.
Quy tắc 1:
Giả sử rằng X ⊃ Y và hai bộ t1 và t2 trong một thể hiện quan hệ r của R sao cho
t1[X] = t2[X]. Khi đó t1[Y] = t2[Y] bởi vì X ⊃ Y, như vậy X→ Y phải xảy ra trong r.
Quy tắc 2: (chứng minh phản chứng)
Giả sử rằng X→Y đúng trong một thể hiện quan hệ r của R nhưng XZ→ YZ
không đúng. Khi đó phải có hai bộ t1 và t2 trong r sao cho:
(1) t1[X] = t2[X],
(2) t1[Y] = t2[Y],
(3) t1[XZ] = t2[XZ] và
(4) t1[YZ] ≠ t2[YZ]. Điều đó là không thể bởi vì từ (1) và (3) chúng ta suy ra
(5) t1[Z] = t2[Z], và từ (2) và (5) ta suy ra t1[YZ] = t2[YZ], mâu thuẫn với (4).
Quy tắc 3: Giả sử rằng
(1) X→ Y và (2) Y→ Z cả hai đúng trong một quan hệ r. Khi đó với mọi bộ t1
và t2 trong r sao cho t1[X] = t2[X] ta phải có (3) t1[Y] = t2[Y] theo giả thiết (1). Như
vậy chúng ta cũng phải có (4) t1[Z] = t2[Z] theo (3) và giả thiết (2). Vậy X→ Z phải
đúng trong r.
Chúng ta có thể chứng minh các quy tắc từ quy tắc 4 đến quy tắc 6 theo phương
pháp trên. Tuy nhiên ta có thể lợi dụng các quy tắc đã được chứng minh là đúng để
chứng minh chúng. Sau đây ta chứng minh theo cách đó.
Quy tắc 4:
1. X→ YZ (cho trước)
2. YZ → Y (sử dụng QT1 và YZ ⊃ Y)
3. X→ Y (sử dụng QT3 trên 1. và 2.)
Quy tắc 5:
1. X→ Y (cho trước)
2. X→ Z (cho trước)
3. X→ YX (sử dụng QT2 trên 1. bằng cách thêm vào cả hai vế X, và XX=X)
4. YX→ YZ (sử dụng QT2 trên 2. bằng cách thêm vào cả hai vế Y)
5. X→YZ (sử dụng QT3 trên 3. và 4.)
Quy tắc 6:
1. X→Y (cho trước )
quan hệ bằng cách trước tiên xem X+ có chứa tất cả các thuộc tính của quan hệ hay
không sau đó kiểm tra không có một tập con S nào được lập từ X bằng cách loại bỏ
một thuộc tính của X thỏa mãn S+chứa tất cả các thuộc tính của quan hệ (nghĩa là X là
siêu khóa tối thiểu). Ví dụ:
Xét lược đồ quan hệ R( A,B,C,D,E,F) và tập phụ thuộc hàm
F ={ A,B → F ; A→ C,D; B → E }
Ta có {A,B}+ = {A,B,C,D,E,F}, A+ = {A,C,D}, B+ = {B,E} , vậy AB là khóa
của quan hệ.
Với mỗi X → Y trong F, xét các dòng của bảng, nếu có giá trị bằng nhau trên
tập thuộc tính X (ví như có t1, t2 mà t1[X]=t2[X]) thì làm bằng giá trị của chúng trên Y
(ví dụ t1[Y]=t2[Y]) theo quy tắc:
- Nếu một trong hai kí hiệu có dạng ai thì kí hiệu kia sẽ được thay bằng ai
- Nếu cả hai kí hiệu đều có dạng bij thì lấy tùy ý một trong hai kí hiệu đó gán
chung cho cả hai.
Sau khi biến đổi bảng, nếu có một dòng gồm toàn kí hiệu dạng ai thì phép tách
là kết nối không mất mát thông tin, còn ngược lại phép tách đó làm tổn thất thông tin.
Ví dụ: cho lược đồ sách trên thư viện
MUON(Masv, HoTen, MaSach, TenSach, NgayMuon) với các phụ thuộc hàm
Masv → Hoten, Masach → TenSach, {Masv, Masach} → NgayMuon
Lược đồ MUON được tách thành ba lược đồ:
SV(Masv, HoTen),
SACH(MaSach, TenSach),
MS(Masv, MaSach, NgayMuon)
Lập bảng ban đầu:
Masv MaSach HoTen TenSach NgayMuon
Masv, HoTen a1 b12 a3 b14 b15
MaSach, TenSach b21 a2 b23 a4 b25
Masv, MaSach, NgayMuon a1 a2 b33 b34 a5
Áp dụng phụ thuộc hàm Masv → Hoten cho ba dòng của bảng ta có
Masv MaSach HoTen TenSach NgayMuon
Masv, HoTen a1 b12 a3 b14 b15
MaSach, TenSach b21 a2 b23 a4 b25
Masv, MaSach, NgayMuon a1 a2 a3 b34 a5
Áp dụng phụ thuộc hàm Masach → TenSach cho ba dòng của bảng ta có
Masv MaSach HoTen TenSach NgayMuon
Masv, HoTen a1 b12 a3 b14 b15
MaSach, TenSach b21 a2 b23 a4 b25
Masv, MaSach, NgayMuon a1 a2 a3 a4 a5
Bảng cuối có dòng thứ ba toàn các giá trị là a, do đó kết nối trên không mất
mát thông tin.
Định lí 1: Thuật toán trên là đúng đắn.
Định lí 2: Giả sử ρ=(R1, R2) là một phép tách của lược đồ quan hệ R, F là tập
các phụ thuộc hàm trên R. Khi đó, ρ là phép tách – kết nối không mất mát thông tin
đối với F khi và chỉ khi
U1∩U2 → U1-U2 hoặc U1∩U2 → U2-U1
quan hệ có một khoá chính. Trong phần này chúng ta sẽ nghiên cứu các dạng chuẩn
và quá trình chuẩn hoá các lược đồ quan hệ.
Trước khi định nghĩa các dạng chuẩn chúng ta xem lại định nghĩa các khóa của một
quan hệ. Một siêu khóa (superkey) của một lược đồ quan hệ R = {A1, A2, .., An} là
một tập con S các thuộc tính của R, S ⊆ R, có tính chất là không có hai bộ t1, t2 trong
một trạng thái quan hệ hợp pháp r nào của R mà t1[S] = t2[S]. Một khóa K là một siêu
khóa có tính chất là nếu bỏ đi bất kỳ thuộc tính nào ra khỏi K thì K không còn là siêu
khóa nữa. Điều đó có nghĩa là khóa là một siêu khóa tối thiểu. Nếu một lược đồ quan
hệ có nhiều hơn một khóa thì các khóa đó được gọi là các khóa dự tuyển. Một trong
những khóa dự tuyển sẽ được chỉ định làm khóa chính và các khóa còn lại được gọi là
các khóa phụ (secondary key). Một lược đồ quan hệ phải có một khóa chính. Một
thuộc tính của một lược đồ quan hệ R được gọi là một thuộc tính khóa của R nếu nó là
một thành phần của khóa chính của R. Một thuộc tính được gọi là thuộc tính không
khóa nếu nó không phải là một thuộc tính khóa.
2. Dạng chuẩn 1
Một quan hệ được gọi là ở dạng chuẩn 1 (1NF) nếu miền giá trị của một thuộc
tính chỉ chứa các giá trị nguyên tử (đơn, không phân chia được) và giá trị của mỗi
thuộc tính trong một bộ phải là một giá trị đơn lấy từ miền giá trị của thuộc tính đó.
Như vậy, 1NF không cho phép quan hệ có các thuộc tính đa trị hoặc có các nhóm
thuộc tính lặp (quan hệ trong quan hệ). Nó chỉ cho phép các giá trị của các thuộc tính
là nguyên tử.
Ví dụ, xét các quan hệ ĐƠNVỊ và NHÂNVIÊN_DỰÁN như hình dưới đây. Các
quan hệ này không thỏa mãn điều kiện 1NF. Quan hệ ĐƠNVỊ chứa thuộc tính đa trị
Địađiểm, quan hệ NHÂNVIÊN_DỰÁN chứa nhóm các thuộc tính lặp (Tênnhânviên,
Sốgiờ).
ĐƠNVỊ MãsốĐV TênĐV Mã sốNQL Địađiểm
1 DA01 Vân 15
Nam 20
2 DA02 Nam 10
Thanh 12
Bằng 28
3 DA03 Thanh 20
Để đạt đến dạng chuẩn 1 đối với các quan hệ ở trên chúng ta dùng phương pháp
sau:
Loại bỏ các thuộc tính vi phạm dạng chuẩn 1 và đặt chúng vào một bảng riêng
cùng với khoá chính của quan hệ ban đầu. Khoá chính của bảng này là một tổ hợp của
khoá chính của quan hệ ban đầu và thuộc tính đa trị hoặc khoá bộ phận của nhóm lặp.
Các thuộc tính còn lại lập thành một quan hệ với khóa chính là khóa chính ban đầu.
Áp dụng : Lược đồ quan hệ ĐƠNVỊ ở trên sẽ được tách thành hai:
ĐƠNVỊ (Mã sốĐV, TênĐV, Mã sốNQL)
ĐƠNVỊ_ĐỊAĐIỂM ( MãsốĐV, Địađiểm)
Lược đồ quan hệ NHÂNVIÊN_DỰÁN cũng được tách thành hai:
DỰÁN (MãsốDA, TênDA)
NHÂNVIÊN_DỰÁN(MãsốDA, Tênnhânviên, Sốgiờ)
3. Dạng chuẩn 2
Dạng chuẩn 2 (2NF) dựa trên khái niệm phụ thuộc hàm đầy đủ. Một phụ thuộc
hàm X → Y là một phụ thuộc hàm đầy đủ nếu loại bỏ bất kỳ thuộc tính A nào ra khỏi
X thì phụ thuộc hàm không còn đúng nữa. Điều đó có nghĩa là, với thuộc tính A bất
kỳ, A ∈ X, (X – {A}) không xác định Y. Một phụ thuộc hàm X → Y là phụ thuộc bộ
phận nếu có thể bỏ một thuộc tính A∈ X, ra khỏi X phụ thuộc hàm vẫn đúng, điều đó
có nghĩa là với A∈ X, (X – {A}) → Y.
Ví dụ, xét lược đồ quan hệ
NHÂNVIÊN_DỰÁN(MãsốNV, MãsốDA, Sốgiờ, HọtênNV, TênDA, ĐịađiểmDA)
MãsốNV, MãsốDA → Sốgiờ là phụ thuộc hàm đầy đủ
MãsốNV, MãsốDA → HọtênNV là phụ thuộc hàm bộ phận, bởi vì có phụ thuộc
hàm
MãsốNV →HọtênNV
Việc kiểm tra đối với 2NF bao gồm việc kiểm tra đối với các phụ thuộc hàm có
các thuộc tính ở vế trái của nó là một bộ phận của khoá chính. Nếu khoá chính chứa
một thuộc tính đơn thì không cần phải kiểm tra. Một lược đồ quan hệ R là ở dạng
chuẩn 2 nếu nó thỏa mãn dạng chuẩn 1 và mỗi thuộc tính không khoá A trong R là
phụ thuộc hàm đầy đủ vào khoá chính của R.
Nếu một quan hệ không thoả mãn điều kiện 2NF ta có thể chuẩn hoá nó để có
các quan hệ 2NF như sau: Loại bỏ các thuộc tính không khoá phụ thuộc vào một bộ
phận khoá chính và tách thành ra một bảng riêng, khoá chính của bảng là bộ phận
khoá mà chúng phụ thuộc vào. Các thuộc tính còn lại lập thành một quan hệ, khóa
chính của nó là khóa chính ban đầu.
Ví dụ, xét lược đồ quan hệ:
NHÂNVIÊN_DỰÁN(MãsốNV, MãsốDA, Sốgiờ, HọtênNV, TênDA, ĐịađiểmDA) với
các phụ thuộc hàm:
MãsốNV, MãsốDA → Sốgiờ
MãsốNV →HọtênNV
MãsốDA→TênDA, ĐịađiểmDA
Ta thấy ở đây có những thuộc tính không khoá phụ thuộc vào một bộ phận của
khoá chính, như vậy nó không thoả mãn điều kiên 2NF.
Áp dụng phương pháp chuẩn hoá trên, lược đồ được tách thành các lược đồ như
sau:
N_D1(MãsốDA, TênDA, ĐịađiểmDA)
N_D2(MãsốNV , HọtênNV)
N_D3(MãsốNV, MãsốDA, Sốgiờ)
4. Dạng chuẩn 3
Dạng chuẩn 3 (3NF) dựa trên khái niệm phụ thuộc bắc cầu. Một phụ thuộc hàm
X → Y trong một lược đồ quan hệ R là một phụ thuộc hàm bắc cầu nếu có một tập
hợp thuộc tính Z không phải là một khoá dự tuyển cũng không phải là một tập con của
một khoá nào và cả hai X → Z và Z →Y đều đúng. Theo định nghĩa nguyên thuỷ của
Codd, một lược đồ quan hệ R là ở 3NF nếu nó thoả mãn 2NF và không có thuộc tính
không khoá nào của R là phụ thuộc bắc cầu vào khoá chính.
Nếu một lược đồ quan hệ không thoả mãn điều kiện 3NF, ta có thể chuẩn hoá
nó để có được các lược đồ 3NF như sau: Loại bỏ các thuộc tính phụ thuộc bắc cầu ra
khỏi quan hệ và tách chúng thành một quan hệ riêng có khoá chính là thuộc tính bắc
cầu. Các thuộc tính còn lại lập thành một quan hệ có khóa chính là quan hệ ban đầu.
Ví dụ: Xét lược đồ quan hệ
NHÂNVIÊN_ĐƠNVỊ(HọtênNV, MãsốNV, Ngàysinh, Địachỉ, MãsốĐV, TênĐV, MãsốNQL)
Với các phụ thuộc hàm:
MãsốNV→ HọtênNV, Ngày sinh, Địachỉ, MãsốĐV, TênĐV, MãsốNQL
MãsốDV→ TênĐV, Mã sốNQL
Các thuộc tính TênĐV, MãsốNQL phụ thuộc bắc cầu vào khoá chính, lược đồ
quan hệ không thoả mãn điều kiện 3NF.
Áp dụng phương pháp chuẩn hoá ở trên, lược đồ được tách ra như sau:
NV_DV1(HọtênNV, MãsốNV, Ngàysinh, Địachỉ, MãsốĐV)
NV_DV2(MãsốĐV, TênĐV, MãsốNQL)
Nếu một lược đồ quan hệ không thoả mãn điều kiện BCNF, ta có thể chuẩn hoá
nó để có được các lược đồ BCNF như: Loại bỏ các thuộc tính khóa phụ thuộc hàm
vào thuộc tính không khóa ra khỏi quan hệ và tách chúng thành một quan hệ riêng có
khoá chính là thuộc tính không khóa gây ra phụ thuộc.
Áp dụng phương pháp chuẩn hóa ở trên, lược đồ được tách ra như sau:
R1( A4, A2)
R2(A1, A4, A3, A5)
Ví dụ áp dụng:
Cho lược đồ quan hệ R = {A,B,C,D,E,F,G,H,I,J} có khóa chính là A,B
Với tập các phụ thuộc hàm :
A,B → C,D,E,F,G,H,I,J
A→ E,F,G,H,I,J
F → I, J
D →B
Do có có phụ thuộc hàm A→ E,F,G,H,I,J mà A là một bộ phận của khóa chính
nên quan hệ R là vi phạm 2NF. Ta tách R thành R1(A,E,F,G,H,I,J) và R2(A,B,C,D).
Trong R1, do có phụ thuộc hàm F→ I, J, nên ta có I,J phụ thuộc bắc cầu vào khóa
chính, R1 là quan hệ vi phạm 3NF. Trong R2 ta có phụ thuộc hàm D → B trong đó B
là một thuộc tính khóa, R2 vi phạm BCNF. Tách R1 và R2 ta có:
R11( F,I,J) , R12( A,E,F,G,H), R21(D,B), R22( A,D,C)
Trong phần này chúng ta chủ yếu trình bày cách tiếp cận thứ hai. Trước tiên
chúng ta sẽ định nghĩa lại các dạng chuẩn một cách tổng quát, sau đó trình bày các
thuật toán chuẩn hóa và các kiểu phụ thuộc khác. Chúng ta cũng sẽ trình bày chi tiết
hơn về hai tính chất cần có là nối không phụ thêm (mất mát) và bảo toàn phụ thuộc.
Các thuật toán chuẩn hóa thường bắt đầu bằng việc tổng hợp một lược đồ quan hệ rất
lớn, gọi là quan hệ phổ quát (universal relation), chứa tất cả các thuộc tính của cơ sở
dữ liệu. Sau đó chúng ta thực hiện lặp đi lặp lại việc tách (decomposition)
dựa trên các phụ thuộc hàm và các phụ thuộc khác do người thiết kế cơ sở dữ liệu chỉ
ra cho đến khi không còn tách được nữa hoặc không muốn tách nữa.
Do có phụ thuộc hàm D → E trong đó D không phải thuộc tính khóa, E cũng
không phải là thuộc tính khóa, nên R1 vi phạm chuẩn 3NF
Định nghĩa dạng chuẩn Boyce- Codd: Một lược đồ quan hệ là ở dạng chuẩn
Boyce-Codd (BCNF) nếu khi một phụ thuộc hàm X → A thỏa mãn trong R thì X là
một siêu khóa của R.
Ví dụ: Xét lược đồ R = {A, B, C, D} có A là khóa chính và {B,C} là khóa dự
tuyển. Nếu có tồn tại một phụ thuộc hàm D → B thì lược đồ này vi phạm BCNF vì B
là một thuộc tính khóa (chú ý rằng trong trường hợp định nghĩa dạng chuẩn dựa trên
khóa chính, lược đồ này không vi phạm BCNF).
buộc trong cơ sở dữ liệu. Nếu như một trong các phụ thuộc không được thể hiện trong
một quan hệ riêng rẽ Ri nào đó của phép tách, chúng ta không thể ép buộc ràng buộc
này đối với quan hệ riêng rẽ, thay vào đó, chúng ta nối hai hoặc nhiều quan hệ trong
phép tách và sau đó kiểm tra rằng phụ thuộc hàm thỏa mãn trong kết quả của phép
nối. Rơ ràng đó là một thủ tục không hiệu quả và không thực tiễn.
Việc các phụ thuộc chính xác được chỉ ra ở trong F xuất hiện trong các quan hệ
riêng rẽ của phép tách D là không cần thiết. Chỉ cần hợp của các phụ thuộc thỏa mãn
trên các quan hệ riêng rẽ trong D là tương đương với F là đủ. Bây giờ chúng ta định
nghĩa các khái niệm này một cách hình thức.
Cho trước một tập hợp các phụ thuộc F trên R, phép chiếu của F trên Ri, kí hiệu
là F[Ri] trong đó Ri là một tập con của R, là một tập hợp các phụ thuộc hàm X→Y
trong F+ sao cho các thuộc tính trong X ∪ Y đều được chứa trong Ri. Như vậy, phép
chiếu của F trên mỗi lược đồ quan hệ Ri trong phép tách D là tập hợp các phụ thuộc
hàm trong F+, bao đóng của F, sao cho các thuộc tính ở vế trái và vế phải của chúng
đều ở trong Ri. Ta nói rằng phép tách D = {R1, R2, …, Rm} của R bảo toàn phụ thuộc
đối với F nếu hợp của các phép chiếu của F trên mỗi Ri trong D là tương đương với F.
Điều đó có nghĩa là:
( F[R1] ∪ F[R2] ∪ … ∪ F[Rm])+ = F+
Nếu một phép tách là không bảo toàn phụ thuộc, một vài phụ thuộc sẽ bị mất
trong phép tách. Để kiểm tra xem một phụ thuộc hàm X→ B, trong đó X là tập thuộc
tính thuộc về Ri, B là một thuộc tính thuộc Ri có thỏa mãn trong Ri hay không ta làm
như sau: Trước hết tính X+ , sau đó với mỗi thuộc tính B sao cho
1. B là một thuộc tính của Ri
2. B là ở trong X+
3. B không ở trong X
Khi đó phụ thuộc hàm X → B thỏa mãn trong Ri.
Một ví dụ về phép tách không bảo toàn phụ thuộc. Xét lược đồ quan hệ:
R = { A,B,C,D} với các phụ thuộc hàm:
A → BCD; BC → DA; D →B
Lược đồ này có hai khóa dự tuyển là A và BC. Lược đồ này vi phạm BCNF. Nó
được tách thành:
R1 = {D,B}, lược đồ này chứa phụ thuộc hàm D → B
R2 = {A,C,D}, lược đồ này chứa phụ thuộc hàm A → CD
Rơ ràng sau khi tách, phụ thuộc hàm BC → DA bị mất.
Định lý: Luôn luôn tìm được một phép tách bảo toàn phụ thuộc D đối với F sao
cho mỗi quan hệ Ri trong D là ở 3NF. Phép tách D đựơc thực hiện theo thuật toán sau
đây:
Thuật toán 1: Tạo một phép tách bảo toàn phụ thuộc D = {R1,R2, …,Rm} của
một quan hệ vũ trụ R dựa trên một tập phụ thuộc hàm F sao cho mỗi Ri trong D là ở
3NF. Thuật toán này chỉ đảm bảo tính chất bảo toàn phụ thuộc, không đảm bảo tính
chất nối không mất mát.
Input: Một quan hệ vũ trụ R và một tập phụ thuộc hàm F trên các thuộc tính của
R.
1) Tìm phủ tối thiểu G của F.
2) Với mỗi vế trái X của một phụ thuộc hàm xuất hiện trong G, hăy tạo một
lược đồ trong D với các thuộc tính {X ∪ {A1} ∪ {A2} ∪… ∪{Ak}} trong đó X→A1,
X→A2,…, X→Ak chỉ là các phụ thuộc hàm trong G với X là vế trái (X là khóa của
quan hệ này).
3) Đặt các thuộc tính còn lại (những thuộc tính chưa được đặt vào quan hệ
nào) vào một quan hệ đơn để đảm bảo tính chất bảo toàn thuộc tính.
Ví dụ áp dụng:
Xét lược đồ: R = { A,B,C,D} , với các phụ thuộc hàm:
F = {A → BCD; BC → DA; D →B}
Lược đồ này có hai khóa dự tuyển là A và BC.
Ta thực hiện thuật toán như sau: Trước tiên ta Tìm G là phủ tối thiểu của F.
Theo thuật toán Tìm phủ tối thiểu, đầu tiên ta làm cho các vế phải trong G chỉ chứa
một thuộc tính, ta có:
G = {A → B; A → C; A→ D; BC → D; BC → A; D → B}
Sau đó ta bỏ đi các phụ thuộc hàm thừa (là các phụ thuộc hàm có thể suy diễn
được từ các phụ thuộc hàm khác). Ta thấy A →B là thừa vì có A →D, D →B. Vậy G
còn lại là:
G = {A → C; A→ D; BC → D; BC → A; D → B}. Lược đồ R sẽ được tách
thành:
R1( A,C,D); R2(B,C,D,A); R3(D,B) với các khóa chính được gạch dưới.
Rõ ràng rằng tất cả các phụ thuộc hàm trong G đều được thuật toán bảo toàn bởi
vì mỗi phụ thuộc xuất hiện trong một trong các quan hệ của phép tách D. Bởi vì G
tương đương với F, tất cả các phụ thuộc của F cũng được bảo toàn hoặc trực tiếp bằng
thuật toán hoặc được suy diễn từ những phụ thuộc hàm trong các quan hệ kết quả, như
vậy tính chất bảo toàn phụ thuộc được đảm bảo.
Ví dụ áp dụng 1:
R = ( MãsốNV, TênNV, MãsốDA, TênDA, ĐịađiểmDA, Sốgiờ)
R1= ( TênNV, ĐịađiểmDA)
R2 = ( MãsốNV, MãsốDA, Sốgiờ, TênDA, ĐịađiểmDA )
F= { Mă sốNV→ TênNV, MãsốDA → {TênDA, ĐịađiểmDA}, {MãsốNV,
Mă sốDA}→ Sốgiờ}
MãsốNV TênNV MãsốDA TênDA ĐịađiểmDA Sốgiờ
R1 0 1 0 0 1 0
R2 1 0 1 1 1 1
Xét lần lượt phụ thuộc hàm MãsốNV → TênNV, MãsốDA → {TênDA,
ĐịađiểmDA}, {MãsốNV, Mă sốDA} → Sốgiờ. Ta thấy không có trường hợp nào các
thuộc tính tương ứng với các vế trái đều có giá trị bằng 1, vì vậy ta không thể làm gì
để biến đối ma trận. Ma trận không chứa một hàng gồm toàn kí hiệu “1”. Phép tách là
mất mát.
Ví dụ áp dụng 2:
R = (MãsốNV, TênNV, MãsốDA, TênDA, ĐịađiểmDA, Sốgiờ)
R1= (MãsốNV, TênNV)
R2 = (MãsốDA, TênDA, ĐịađiểmDA)
R3 = (MãsốNV, MãsốDA, Sốgiờ)
F= {MãsốNV→ TênNV, MãsốDA → {TênDA, ĐịađiểmDA}, {MãsốNV,
MãsốDA} → Sốgiờ}
MãsốNV TênNV Mă sốDA TênDA ĐịađiểmDA Sốgiờ
R1 1 1 0 0 0 0
R2 0 0 1 1 1 0
R3 1 0 1 1 1 0
(Giá trị ban đầu của ma trận S)
- Hoặc phụ thuộc hàm ((R1∩ R2) → (R2 − R1)) ở trong F+.
Với tính chất này, chúng ta có thể kiểm tra lại các phép tách chuẩn hóa trong 4.3
và sẽ thấy rằng các phép tách đó là thỏa mãn tính chất nối không mất mát.
Tính chất 2: Nếu một phép tách D = {R1, R2, …, Rm} của R có tính chất nối
không mất mát đối với một tập phụ thuộc hàm F trên R và nếu một phép tách D1 =
{Q1, Q2, …,Qk} của Ri có tính chất nối không mất mát đối với phép chiếu của F trên
Ri thì phép tách D2 = { R1, R2,…, Ri-1, Q1, Q2,…,Qk, Ri+1,…, Rm} của R có tính chất
nối không mất mát đối với F.
Tính chất này nói rằng nếu một phép tách D đã có tính chất nối không mất mát
đối với một tập F và chúng ta tiếp tục tách một trong các quan hệ Ri trong D thành
phép tách khác D1 (l = 1,2,..k) có tính chất nối không mất mát đối với πRi(F) thì việc
thay Ri trong D bằng D1 (l = 1,2,..k) cũng tạo ra một phép tách có tính chất nối không
mất mát đối với F.
Thuật toán 3 sau đây sử dụng hai tính chất trên để tạo ra một phép tách D = {R1,
R2, …, Rm} của một quan hệ vũ trụ R dựa trên một tập các phụ thuộc hàm F sao cho
mỗi Ri là BCNF.
Thuật toán 3: Tách quan hệ thành các quan hệ BCNF với tính chất nối không
mất mát.
Input: Một quan hệ vũ trụ R và một tập hợp các phụ thuộc hàm F trên các thuộc
tính của R.
1. Đặt D := {R} ;
2. Khi có một lược đồ quan hệ Q trong D không phải ở BCNF, thực hiện
vòng lặp: Với mỗi một lược đồ quan hệ Q trong D không ở BCNF hăy Tìm một phụ
thuộc hàm X→ Y trong Q vi phạm BCNF và thay thế Q trong D bằng hai lược đồ
quan hệ (Q-Y) và (X∪Y). Quá trình lặp dừng khi không còn quan hệ nào trong D vi
phạm BCNF.
Mỗi lần đi vào vòng lặp trong thuật toán 5.3, chúng ta tách một quan hệ Q
không phải BCNF thành hai lược đồ quan hệ. Theo các tính chất 1 và 2, phép tách D
có tính chất nối không mất mát. Kết thúc thuật toán, tất cả các quan hệ trong D sẽ ở
BCNF.
Trong bước 2 của thuật toán 5.3, cần xác định xem một lược đồ quan hệ Q có ở
BCNF hay không. Một phương pháp để làm điều đó là kiểm tra. Với mỗi phụ thuộc
hàm X → Y trong Q, ta tính X+. Nếu X+ không chứa tất cả các thuộc tính trong Q thì
X → Y vi phạm BCNF bởi vì X không phải là một siêu khóa.
Một kỹ thuật nữa dựa trên quan sát rằng khi một lược đồ quan hệ Q vi phạm
BCNF thì có tồn tại một cặp thuộc tính A,B trong Q sao cho {Q – {A,B}} → A. Bằng
việc tính bao đóng {Q – {A,B}}+ cho mỗi cặp thuộc tính {A,B} của Q và kiểm tra
xem bao đóng có chứa A (hoặc B) hay không, chúng ta có thể xác định được Q có ở
BCNF hay không.
Ví dụ áp dụng: Xét lược đồ quan hệ
R = { A, B, C, D, E, F)
Với các phụ thuộc hàm:
A → BCDEF, BC → ADEF, B→ F, D→ E, D→ B
Lược đồ quan hệ này có hai khóa dự tuyển là A và BC.
Ta có B → F vi phạm BCNF vì B không phải là siêu khóa, R được tách thành:
R1(B,F) với phụ thuộc hàm B→ F
R2(A,B,C,D,E) với các phụ thuộc hàm A→BCDE, BC→ADF, D→E, D→B
Do D→ E vi phạm BCNF ( D là một thuộc tính không khóa ), R2 được tách
thành:
R21(D,E) với phụ thuộc hàm D → E
R22(ABCD) với các phụ thuộc hàm A → BCD, BC→ AD, D→ B
Do D→ B vi phạm BCNF (D không phải là thuộc tính khóa), R22 được tách
thành:
R221(D,B)
R222(A,B,D) với phụ thuộc hàm A → BD (phụ thuộc hàm BC → AD bị mất)
Tóm lại, ta có phép tách D = {R1, R21, R221, R222}. Phép tách này có tính
chất nối không mất thông tin nhưng không bảo toàn phụ thuộc.
Nếu chúng ta muốn có một phép tách có tính chất nối không mất mát và bảo
toàn phụ thuộc thì ta phải hài lòng với các lược đồ quan hệ ở dạng 3NF. Thuật toán
sau đây là cải tiến của thuật toán 1, tạo ra một phép tách thỏa mãn :
- Bảo toàn phụ thuộc.
- Có tính chất nối không mất mát.
- Mỗi lược đồ quan hệ kết quả là ở dạng 3NF.
Thuật toán 4: Thuật toán tổng hợp quan hệ với tính chất bảo toàn phụ thuộc và
nối không mất mát.
Input: Một quan hệ vũ trụ R và một tập các phụ thuộc hàm F trên các thuộc tính
của R.
1) Tìm phủ tối thiểu G cho F.
2) Với mỗi vế trái X của một phụ thuộc hàm xuất hiện trong G hãy tạo ra
một lược đồ quan hệ trong D với các thuộc tính {X∪{A1}∪{A2}∪…∪ {Ak}}, trong
đó X →A1, X→A2,…, X→ Ak chỉ là các phụ thuộc hàm ở trong G với X là vế trái (X
là khóa của quan hệ này).
3) Nếu không có lược đồ quan hệ nào trong D chứa một khóa của R thì
hăy tạo ra thêm một lược đồ quan hệ trong D chứa các thuộc tính tạo nên một khóa
của R.
Bước 3 của thuật toán 4 đòi hỏi phải xác định một khóa K của R. Để xác định
một khóa K của R, ta sử dụng thuật toán sau
Thuật toán xác định khóa: Tìm một khóa K của R dựa trên tập F các phụ thuộc
hàm.
1) Đặt K := R;
các giá trị này của Y phải được lặp lại trong các bộ riêng rẽ với mỗi giá trị khác nhau
của Z có mặt với cùng giá trị của X. Điều đó tương ứng một cách không hình thức với
Y là một thuộc tính đa trị của các thực thể được biểu diễn bằng các bộ trong R.
Ví dụ về phụ thuộc đa trị:
NHÂNVIÊN TênNV TênDA TênconNV
2. Các quy tắc suy diễn đối với các phụ thuộc hàm và phụ thuộc đa trị
Các quy tắc từ Qt1 đến Qt8 sau đây tạo nên một tập hợp đúng đắn và đầy đủ cho
việc suy diễn các phụ thuộc hàm và phụ thuộc đa trị từ một tập các phụ thuộc cho
trước. Giả thiết rằng tất cả các thuộc tính được chứa trong một lược đồ quan hệ “vũ
trụ” R = {A1, A2, …,An} và X, Y, Z, W là các tập con của R.
Qt1) (quy tắc phản xạ cho FD): Nếu X ⊇ Y thì X → Y
Qt2) (quy tắc tăng cho FD): {X →Y} |= XZ → YZ
Qt3) (quy tắc bắc cầu cho FD): { X → Y, Y→ Z } |= X→ Z
Qt4) (quy tắc bù cho MVD): {X →→Y } |= {X→→ (R-(X∪ Y))}
Qt5) (quy tắc tăng cho MVD): Nếu X →→Y và W ⊇ Z thì WX →→ YZ
Qt6) (quy tắc bắc cầu cho MVD): {X→→ Y, Y→→ Z } |= X→→ (Z – Y)
Qt7) (quy tắc tái tạo cho FD và MVD): {X →Y} |= X→→ Y
Qt8) (quy tắc liên hợp cho FD và MVD): Nếu X →→ Y và có tồn tại W với các
tính chất a) W ∩Y = ∅, b) W →Z và c) Y ⊇ Z thì X → Z.
Qt1 đến Qt3 là các quy tắc suy diễn Amstrong đối với các phụ thuộc hàm. Qt4
đến Qt6 là các quy tắc suy diễn chỉ liên quan đến các phụ thuộc đa trị. Qt7 và Qt8 liên
kết các phụ thuộc hàm và các phụ thuộc đa trị. Đặc biệt, Qt7 nói rằng một phụ thuộc
hàm là một trường hợp đặc biệt của một phụ thuộc đa trị. Điều đó có nghĩa là mỗi phụ
thuộc hàm cũng là một phụ thuộc đa trị bởi vì nó thỏa mãn định nghĩa hình thức của
phụ thuộc đa trị. Về cơ bản, một phụ thuộc hàm X →Y là một phụ thuộc đa trị X →→
Y với một hạn chế phụ rằng có nhiều nhất là một giá trị của Y được kết hợp với mỗi
giá trị của X. Cho trước một tập hợp các phụ thuộc hàm và phụ thuộc đa trị chỉ ra trên
R = {A1, A2, …, An}, chúng ta có thể sử dụng các quy tắc từ Qt1 đến Qt8 để suy ra
tập hợp đầy đủ các phụ thuộc (hàm và đa trị) F+ đúng trong mọi trạng thái quan hệ r
của R thỏa mãn F. Chúng ta lại gọi F+ là bao đóng của F.
3. Dạng chuẩn 4
Định nghĩa: Một lược đồ quan hệ R là ở dạng chuẩn 4 (4NF) đối với một tập
hợp các phụ thuộc F (gồm các phụ thuộc hàm và phụ thuộc đa trị) nếu với mỗi phụ
thuộc đa trị không tầm thường X→→Y trong F+ , X là một siêu khóa của R.
Như vậy, một lược đồ quan hệ vi phạm 4NF nếu nó chứa các phụ thuộc hàm đa
trị không mong muốn. Ví dụ, lược đồ quan hệ NHÂNVIÊN ở ví dụ trên là vi phạm
4NF bởi vì trong các phụ thuộc hàm đa trị TênNV→→TênDA và TênNV→→
Têncon, TênNV không phải là một siêu khóa .
Giả sử chúng ta tách bảng NHÂNVIÊN thành hai bảng như sau:
NV_DA TênNV TênDA NV_CON TênNV TênconNV
Nam DA01 Nam Lan
Nam DA02 Nam Hoa
Hai bảng này là ở 4NF bởi vì các phụ thuộc đa trị TênNV→→TênDA và
TênNV→→TênconNV là các phụ thuộc đa trị tầm thường. Trong hai bảng này không
có các phụ thuộc đa trị không tầm thường cũng như không có các phụ thuộc hàm.
4. Tách có tính chất nối không mất mát thành các quan hệ 4NF
Khi chúng ta tách một lược đồ quan hệ R thành R1 = (X∪Y) và R2 = (R-Y) dựa
trên phụ thuộc hàm đa trị X→→Y đúng trong R, phép tách có tính chất nối không mất
mát. Đó cũng là điều kiện cần và đủ cho một phép tách một lược đồ thành hai lược đồ
có tính chất nối không mất mát. Ta có tính chất sau:
Tính chất 1’: Các lược đồ quan hệ R1 và R2 tạo thành một phép tách có tính chất
nối không mất mát của R khi và chỉ khi (R1∩ R2)→→ (R1 –R2) (hoặc (R1∩R2)
→→(R1 –R2)).
Áp dụng tính chất trên chúng ta có thuật toán tạo một phép tách có tính chất nối
không mất mát thành các lược đồ quan hệ ở dạng 4NF.
Thuật toán 5: Tách quan hệ thành các quan hệ 4NF với tính chất nối không mất
mát.
Input: Một quan hệ vũ trụ R và một tập phụ thuộc hàm và phụ thuộc đa trị F.
1. Đặt D := {R};
2. Khi có một lược đồ quan hệ Q trong D không ở 4NF, thực hiện:
{Chọn một lược đồ quan hệ Q trong D không ở 4NF;
Tìm một phụ thuộc đa trị không tầm thường X→→Y trong Q vi phạm 4NF;
Thay thế Q trong D bằng hai lược đồ quan hệ (Q – Y) và (X ∪ Y)};
Ví dụ áp dụng:
Xét lược đồ NHÂNVIÊN(TênNV, TênDA, TênconNV). Ta có phụ thuộc hàm
đa trị TênNV→→TênDA trong đó TênNV không phải là một siêu khóa, vậy nó vi
phạm 4NF. Ta tách thành NV_DA(TênNV, TênDA), NV_CON(TênNV, TênconNV).
Giả thiết rằng ràng buộc phụ thêm sau đây luôn đúng: Khi một nhà cung cấp S
cung cấp hàng P VÀ một dự án J sử dụng hàng P VÀ nhà cung cấp S cung cấp ít nhất
là một hàng cho dự án J THÌ nhà cung cấp S cũng sẽ cung cấp hàng P cho dự án J.
Ràng buộc này chỉ ra một phụ thuộc nối JD(R1,R2,R3) giữa ba phép chiếu
R1(Tênnhàcungcấp,Tênhàng), R2(Tênnhàcungcấp,Têndựán),R3(Tênhàng,TênDựán)
của quan hệ CUNGCẤP. Quan hệ CUNGCẤP được tách thành ba quan hệ R1, R2, R3
ở dạng chuẩn 5. Chú ý rằng nếu ta áp dụng phép nối tự nhiên cho từng đôi quan hệ
một thì sẽ sinh ra các bộ giả, nhưng nếu áp dụng phép nối tự nhiên cho cả ba quan hệ
thì không sinh ra các bộ giả.
R1 R2 R3
Tênnhàcungcấp Tênhàng Tênnhàcungcấp Têndựán Tênhàng Têndựán
Ncc1 Bulong Ncc1 Dựán1 Bulong Dựán1
Ncc1 Đaiốc Ncc1 Dựán2 Đaiốc Dựán2
Ncc2 Bulong Ncc2 Dựán2 Bulong Dựán2
Ncc3 Đaiốc Ncc3 Dựán3 Đaiốc Dựán3
Ncc2 Đinh Ncc2 Dựán1 Đinh Dựán1
Việc phát hiện các phụ thuộc nối trong các cơ sở dữ liệu thực tế với hàng trăm
thuộc tính là một điều rất khó khăn. Vì vậy, thực tiễn thiết kế cơ sở dữ liệu hiện nay
thường không chú ý đến nó.
Nói chung, trong thực tế thiết kế cơ sở dữ liệu, người ta chỉ chuẩn hóa các bảng
đến 3NF, BCNF là đủ
• Loại ký tự (Character): Loại này có thể chứa các chữ cái, chữ số
không tính toán và các ký tự đặc biệt.
• Loại số (Numeric): Dùng để chứa các số có thể tham gia vào các
phép toán số học.
• Loại ngày (Date): Để lưu trữ một ngày tháng năm cụ thể.
• Loại logic (Logical): Để chứa các thông tin có hai giá trị trái ngược
nhau của một thuộc tính.
• Loại ký ức (Memo): Thường để ghi các thông tin của các thuộc
tính dùng để tra cứu.
+ Độ rộng trường (Width): Để xác định số ký tự nhiều nhất ghi được
trong trường đó.
Trong FoxPro:
• Trường ký tự có độ rộng không quá 254 ký tự
• Trường số có độ rộng không quá 20 chữ số
• Trường ngày tháng có độ rộng 8
• Trường logic có độ rộng là 1
• Trường ký ức có độ rộng không quá 5000
+ Số chữ số thập phân (Deciman): Để xác định số chữ số thập phân được
dùng đối với các trường số. Nếu số chữ số thập phân là 0 thì đó là số nguyên.
Khi xây dựng một tệp dữ liệu trong FoxPro, cần chú ý:
• Mỗi tệp không quá 256 trường và 1 tỷ bản ghi ;
• Tệp dữ liệu có phần mở rộng là DBF (DataBase File).
Ví dụ: Để quản lý kết quả học tập của 100 sinh viên, mỗi sinh viên cần
biết: Họ tên, số báo danh, điểm thi môn 1, điểm thi môn 2 thì phải tổ chức một
tệp gồm 100 bản ghi, mỗi bản ghi chứa thông tin về một học sinh, gồm 4
trường, chẳng hạn như:
HOTEN SBD DIEM 1 DIEM 2
Nguyễn A 1 8 9
Trần B 2 9 7
1.2. Khái niệm cơ sở dữ liệu.
Hệ quản trị cơ sở dữ liệu chính là một hệ thống các chương trình dùng để
thực hiện các thao tác trên một cơ sở dữ liệu. Để xây dựng các chương trình và
tạo các tệp dữ liệu ta phải sử dụng các ngôn ngữ của một hệ quản trị nào đó.
Hiện nay có nhiều ngôn ngữ quản trị dữ liệu, chẳng hạn như: các hệ dBase,
FoxPro, Access, SQL Server, Oracle,...Trong các bài toán quản lý hiện nay,
FoxPro là một trong các ngôn ngữ được sử dụng phổ biến nhất.
FoxPro được cải tiến từ Foxbase đến Foxpro rồi lên Visual FoxPro theo
hướng tương thích đi lên. Trong chương trình này chúng tôi sẽ giới thiệu hệ
quản trị dữ liệu FoxPro và chủ yếu dựa trên nền là cái lõi của Visual FoxPro
2. HỆ QUẢN TRỊ CƠ SỞ DỮ LIỆU FOX.
Ngoài cửa sổ lệnh là nơi người sử dụng có thể đưa lệnh vào, còn có một
hệ thống thực đơn mà thông qua đó, người sử dụng có thể thực hiện được một
số các lệnh cơ bản của Fox. Trong tài liệu này sẽ hướng dẫn làm việc với Fox
thông qua các lệnh vào từ cửa sổ lệnh.
Trong đó: <tên tệp> là tên tệp chương trình cần chạy. Khi đó các
lệnh trong chương trình sẽ được thực hiện theo đúng cấu trúc của nó đã có.
Ví dụ: Giải phương trình bậc hai: ax2 + bx + c = 0 (a ≠ 0)
Để soạn chương trình ta gõ lệnh:
Modify command GPTB2. PRG
Sau đó trên màn hình soạn thảo ta đưa vào các dòng lệnh sau
INPUT ‘vào a’ TO A
INPUT ‘vào b’ TO B
INPUT ‘ vào c’ TO C
D =B*B -4*A*C
IF D<0
? ‘phương trình vô nghiệm’
ELSE
IF D = 0
? ‘Phương trình có nghiệm kép X =’ , - B / (2 * A)
ELSE
? ‘X1 =’ , ( - B - SQRT(D))/ (2 * A)
? ‘X2 =’ , ( - B + SQRT(D))/ (2 * A)
ENDIF
ENDIF
^W
Các lệnh trên tạo thành một chương trình và được ghi lên đĩa với tên tệp
là GPTB2.PRG đặt tại thư mục làm việc.
Để thực hiện chương trình trên tại cửa sổ lệnh ta đưa lệnh:
DO GPTB2
Khi đó máy sẽ thực hiện các lệnh trong chương trình.
2.3. Các loại tệp chủ yếu dùng trong Fox.
Trong khi viết tên các tệp của FOX, ta chỉ việc viết phần tên chính, còn
phần mở rộng sẽ được Fox tự gán chính xác.
Trong đó: Tên biến đặt giống như tên biến nhớ, các chỉ số viết cách nhau
dấu phảy.
Tuy vậy, FOX là hệ quản trị để xử lý các bảng 2 chiều nên ở đây sẽ có
không quá hai chỉ số.
Ví dụ: Biến Viết trong FOX
a1 A(1)
xi j X(I,J)
Muốn sử dụng biến có chỉ số, trước hết phải tạo ra nó (xem lệnh
DIMENSION).
3.3.4. Hàm.
Cũng như mọi ngôn ngữ khác, FOX có một hệ thống các hàm, song hàm
trong FOX rất phong phú và thiên về xử lý các bài toán quản lý. Trong chương
trình này chúng tôi xin giới thiệu một số hàm chính thường dùng là:
3.3.4.1. Các hàm thao tác trên xâu ký tự.
a. Hàm LEN
Dùng để xác định độ dài một xâu ký tự.
Dạng hàm: LEN(<BT xâu>)
Hàm cho giá trị là độ dài của xâu xác định bởi <BT xâu>.
Ví dụ:
? LEN(‘INFORMATION’)
11
? LEN(‘’)
0
b. Hàm TYPE
Dùng để cho biết kiểu của một biểu thức kiểu ký tự.
Dạng hàm : TYPE( <BT xâu> )
Hàm cho biết kiểu của giá trị của biểu thức ghi trong <BT xâu>, giá trị
của hàm là một trong các ký tự sau:
C nếu là biểu thức kiểu ký tự
N nếu là biểu thức kiểu số
c. Hàm LEFT
Dùng để trích ra một xâu con ở phía trái từ một xâu ký tự.
Dạng hàm: LEFT(<BT xâu>,<n>)
Trong đó: n là một biểu thức số.
Hàm cho giá trị là một xâu con gồm n ký tự trái nhất trích ra từ <BT
xâu>.
Nếu giá trị của n lớn hơn độ dài của giá trị biểu thức xâu, giá trị của hàm
sẽ là toàn bộ biểu thức xâu.
Nếu giá trị của n nhỏ hơn hoặc bằng 0 thì giá trị của hàm là một xâu rỗng.
Nếu giá trị của n không nguyên thì FOX sẽ lấy giá trị là phần nguyên của
biểu thức n.
Ví dụ:
? LEFT(‘ABCDE’,2)
AB
? LEFT(‘ABCDE’,5+2)
ABCDE
? LEFT(‘ABCDE’,-2)
? LEFT(‘ABCDE’,3.7)
ABC
d. Hàm RIGHT
Dùng để trích ra một xâu con ở phía phải từ một xâu ký tự.
Dạng hàm: RIGHT(<BT xâu>,<n>)
Trong đó: n là một biểu thức số.
Hàm cho giá trị là một xâu con gồm n ký tự phải nhất trích ra từ <BT
xâu>.
Nếu giá trị của n lớn hơn độ dài của giá trị biểu thức xâu, giá trị của hàm
sẽ là toàn bộ biểu thức xâu.
Nếu giá trị của n nhỏ hơn hoặc bằng 0 thì giá trị của hàm là một xâu rỗng.
Nếu giá trị của n không nguyên thì FOX sẽ lấy giá trị là phần nguyên của
biểu thức n.
Ví dụ:
? RIGHT(‘ABCDE’,2)
DE
? RIGHT(‘ABCDE’,5+2)
ABCDE
? RIGHT(‘ABCDE’,-2)
? RIGHT(‘ABCDE’,3.7)
CDE
e. Hàm SUBSTR
Dùng để trích ra một xâu con trong một xâu ký tự bắt đầu từ một vị trí
nào đó.
Dạng hàm: SUBSTR(<BT xâu>,<n> [,m] )
Trong đó: n, m là các biểu thức số để chỉ vị trí bắt đầu trích và số ký tự
cần trích ra ở BT xâu.
Hàm cho giá trị là một xâu con gồm m ký tự bắt đầu từ ký tự thứ n tính
về phía cuối của BT xâu.
Nếu giá trị của n lớn hơn độ dài của giá trị biểu thức xâu, FOX sẽ báo lỗi
“ Beyond string”.
Nếu giá trị của m nhỏ hơn hoặc bằng 0 thì giá trị của hàm là một xâu
rỗng.
Nếu giá trị của m không nguyên thì FOX sẽ lấy giá trị là phần nguyên
của biểu thức m.
Nếu không viết m hoặc giá trị của m lớn hơn chiều dài của BT xâu thì giá
trị của hàm là một xâu gồm tất cả các ký tự từ vị trí n về cuối BT xâu.
Ví dụ:
? SUBSTR(‘ABCDE’,2,3)
BCD
? SUBSTR(‘ABCDE’,3,6)
CDE
? SUBSTR(‘ABCDE’,2,-2)
? SUBSTR(‘ABCDE’,2,3.7)
BCD
? SUBSTR(‘ABCDE’,4)
DE
f. Hàm REPLICATE
Dùng để lặp lại giá trị của một xâu ký tự.
Dạng hàm: REPLICATE(<BT xâu>,<n>)
Trong đó: n là một biểu thức số.
Hàm cho giá trị là một xâu gồm giá trị của BT xâu được lặp n lần.
Nếu giá trị của n nhỏ hơn hoặc bằng 0 thì giá trị của hàm là một xâu rỗng.
Nếu giá trị của n không nguyên thì FOX sẽ lấy giá trị là phần nguyên của
biểu thức n.
Ví dụ:
? REPLICATE(‘ABCDE’,2)
ABCDEABCDE
? REPLICATE(‘ABCDE’,-10)
? REPLICATE(‘ABCDE’,2.9)
ABCDEABCDE
h. Hàm AT
Dùng để tìm kiếm vị trí một xâu con chứa trong một xâu ký tự.
Dạng hàm: AT(<BT xâu 1>, <BT xâu 2>)
Trong đó : BT xâu 1, BT xâu 2 là các xâu ký tự.
Hàm này tìm kiếm giá trị của BT xâu 1 trong xâu xác định bởi giá trị của
BT xâu 2. Giá trị của hàm là một số chỉ ra vị trí bắt đầu của xâu 1 trong xâu 2.
Nếu giá trị của BT xâu 1 không có trong giá trị của BT xâu 2 ( không là xâu
con) thì hàm cho giá trị là số 0.
Ví dụ:
? AT(‘ABC’,’123ABCD’)
4
? AT(‘Hương’, ‘NGUYỄN THỊ HƯƠNG’)
0
i. Hàm LOWER
Dùng để chuyển tất cả các chữ cái trong xâu ký tự thành chữ thường.
Dạng hàm: LOWER(<BT xâu>)
Hàm sẽ cho giá trị là một xâu là kết quả của giá trị BT xâu đã chuyển tất
cả các chữ cái thành chữ thường.
Ví dụ :
? LOWER(‘123aBcD’)
123abcd
j. Hàm UPPER
Dùng để chuyển tất cả các chữ cái trong xâu ký tự thành chữ in.
Dạng hàm: UPPER(<BT xâu>)
Hàm sẽ cho giá trị là một xâu là kết quả của giá trị BT xâu đã chuyển tất
cả các chữ cái thành chữ in.
Ví dụ :
? UPPER(‘123aBcD’)
123ABCD
3.3.4.2. Các hàm chuyển loại dữ liệu.
a. Hàm VAL
Dùng để chuyển loại dữ liệu từ loại xâu sang loại số.
Dạng hàm: VAL(<BT xâu>)
Hàm sẽ chuyển giá trị BT xâu thành một số tương ứng. Trong trường hợp
giá trị BT xâu không biểu diễn một số nào thì hàm cho giá trị là số không “0”.
Ví dụ:
? VAL(‘123’+’45’)
12345
(Đây là số 12.345)
? VAL(‘12H1’)
12 (số 12)
? VAL(‘XYZT’)
0 (số 0)
b. Hàm STR
Dùng để chuyển giá trị một biểu thức số thành một xâu ký tự tương ứng.
Dạng hàm: STR(<Bt số> [,n] [,m])
Trong đó: n, m là các biểu thức số.
Hàm cho giá trị là một xâu biểu diễn giá trị của biểu thức số với độ dài là
n và m ký tự sau dấu chấm.
Nếu không viết m thì hiểu là dãy ký tự biểu diễn số nguyên.
Nếu không viết n thì lấy độ dài ngầm định của xâu là 10.
Nếu n nhỏ hơn số chữ số phần nguyên của giá trị Bt số thì xảy ra hiển
tượng tràn nên giá trị của hàm n ký tự “ * “.
Ví dụ:
? STR(20/3,5,2)
6.67 ( - một khoảng trống)
? STR(20/3,5)
7
? STR(20/3)
7
c. Hàm CTOD
Dùng để chuyển một xâu ký tự thành một ngày tương ứng.
Dạng hàm: CTOD( <Bt xâu> )
Hàm chuyển giá trị Bt xâu thành một ngày (dữ kiệu loại ngày tháng)
tương ứng.
Ví dụ:
NGAY=’01/21/98’
? CTOD(NGAY)
01/21/98
? TYPE(CTOD(NGAY))
D
Khi biểu thức xâu không chuyển được thành một ngày tương ứng thì các
giá trị ngày, tháng, năm sẽ bỏ trống.
Ví dụ: Giá trị của hàm CTOD(‘abcdefgh’) là { / / }.
d. Hàm DTOC
Dùng để chuyển giá trị một biểu thức ngày thành một xâu ký tự tương
ứng.
Dạng hàm: DTOC( <Bt ngày> )
Hàm chuyển giá trị <Bt ngày> thành một xâu ký tự tương ứng biểu diễn
giá trị của nó.
Ví dụ:
NGAY={01/21/98}
? DTOC(NGAY)
01/21/98 (là một xâu)
? TYPE(DTOC(NGAY))
C
3.3.4.3. Một số hàm số toán học thường gặp:
Hàm số nhận đối là số thực nằm trong miền xác định và giá trị của hàm là
một số thực:
Tên hàm Hàm Viết trong FOX
Trị tuyệt đối của x |x| ABS(X)
Căn bậc 2 của x X SQRT(X)
E mũ x Ex EXP(X)
Loga tự nhiên của x Lnx LOG(X)
Phần nguyên của x [x] INT(X)
Phần dư của x chia y X mod Y MOD(X,Y)
Sin x sinx SIN(X)
Cosin x cos x COS(X)
Tang x tg x TAN(X)
Giá trị nhỏ nhất Min {x1,x2,...,xn} MIN(x1,x2,...,xn)
Giá trị lớn nhất Max{x1,x2,...,xn} MAX(x1,x2,...,xn)
a. Hàm DATE
Để xác định ngày hệ thống.
b. Hàm DAY
Dùng để trích ra ngày từ giá trị một biểu thức ngày.
Dạng hàm: DAY(<Bt ngày>)
Hàm cho giá trị là ngày được trích ra từ giá trị biểu thức ngày.
Ví dụ:
Ngay={21/01/99}
?DAY(NGAY)
21 (giá trị thuộc loại số)
? TYPE(‘DAY(NGAY)’)
N
c. Hàm MONTH
Dùng để trích ra tháng từ giá trị một biểu thức ngày.
Dạng hàm: MONTH( <Bt ngày> )
Hàm cho giá trị là tháng được trích ra từ giá trị biểu thức ngày.
Ví dụ:
Ngay={21/01/99}
?MONTH(NGAY)
1 (giá trị thuộc loại số)
? TYPE(‘MONTH(NGAY)’)
N
d. Hàm YEAR
Dùng để trích ra năm từ giá trị một biểu thức ngày.
Dạng hàm: YEAR(<Bt ngày> )
Hàm cho giá trị là năm được trích ra từ giá trị biểu thức ngày.
Ví dụ:
Ngay={21/01/99}
?YEAR(NGAY)
1999 (giá trị thuộc loại số)
? TYPE(‘YEAR(NGAY)’)
N
e. Hàm DOW
Dùng để xác định thứ tự của ngày trong tuần của ngày lấy ra từ biểu thức
ngày.
Dạng hàm: DOW(<Bt ngày>)
Hàm cho giá trị là thứ tự ngày trong tuần của ngày được trích ra từ giá trị
biểu thức ngày.
Ví dụ:
Ngay={21/01/99}
?DOW(NGAY)
5 (Ngày thứ 5 trong tuần - giá trị thuộc loại số)
? TYPE(‘DOW(NGAY)’)
N
f. Hàm RECNO()
Dùng để xác định số thứ tự của bản ghi trong tệp dữ liệu.
Dạng hàm:
RECNO()
Hàm cho giá trị là số hiệu của bản ghi hiện thời có loại là số.
Số hiệu của bản ghi là số thứ tự của bản ghi.
Ví dụ:
USE QLHS
? RECNO()
1
GOTO 120
? RECNO()
120
g. Hàm EOF
Dùng để xác định con trỏ bản ghi có đặt vào dấu hiệu kết thúc tệp hay
không.
Dạng hàm: EOF()
Hàm cho giá trị .T. khi con trỏ đặt vào dấu hiệu kết thúc tệp và cho giá trị
là .F. trong trường hợp ngược lại.
Ví dụ:
USE QLHS
? EOF()
.F.
GOTO BOTTOM
? EOF()
.F.
SKIP
? EOF()
.T.
h. Hàm BOF
Dùng để xác định con trỏ bản ghi có đặt vào dấu hiệu bắt đầu tệp hay
không.
Dạng hàm: BOF()
Hàm cho giá trị .T. khi con trỏ đặt vào dấu hiệu bắt đầu tệp và cho giá trị
là .F. trong trường hợp ngược lại.
Ví dụ:
USE QLHS
? BOF()
.F.
SKIP -1
? BOF()
.T.
i. Hàm PROW
Dùng để xác định dòng của đầu in đang đặt trên trang in.
Dạng hàm: PROW()
Hàm cho giá trị là số chỉ thứ tự dòng của đầu in trên trang giấy in.
Hàm thường dùng khi điều khiển máy in để xuất thông tin ra giấy thành
văn bản.
j. Hàm PCOL
Dùng để xác định cột của đầu in đang đặt trên trang in.
Dạng hàm: PCOL( )
Hàm cho giá trị là số chỉ thứ tự cột của đầu in trên trang giấy in.
Hàm thường dùng khi điều khiển máy in để xuất thông tin ra giấy thành
văn bản.
k. Hàm ROW
Dùng để xác định dòng hiện thời trên màn hình.
Dạng hàm: ROW( )
Hàm cho giá trị là số chỉ thứ tự dòng hiện thời trên màn hình khi xuất
thông tin ra màn hình.
l. Hàm COL
Dùng để xác định cột hiện thời trên màn hình.
Dạng hàm: COL( )
Hàm cho giá trị là số chỉ thứ tự cột hiện thời trên màn hình khi xuất thông
tin ra màn hình.
3.4. Biểu thức.
Biểu thức gồm các đại lượng liên kết với nhau bởi các dấu phép toán và
cặp dấu ( ). Tuỳ thuộc đại lượng thuộc loại nào, liên kết bởi dấu phép toán
tương ứng mà có các loại biểu thức tương ứng.
Phép toán .OR. có hai toán hạng. Phép hoặc chỉ nhận giá trị sai (.F.) khi
cả hai toán hạng sai, sẽ nhận giá trị đúng khi có ít nhất một trong hai toán hạng
đúng (. T.)
Bảng giá trị của phép toán .OR. như sau:
Khi tính giá trị biểu thức logic, sẽ theo trình tự ưu tiên sau:
- Các phép toán trong ngoặc ( )
- Phép toán .NOT.
- Phép toán .AND.
- Phép toán .OR.
Vậy biểu thức logic chỉ nhận giá trị .T. hoặc .F.
Lưu ý: Các dấu phép toán logic, khi viết trong FOX có thể bỏ các dấu
chấm trước và sau nhưng phải có ít nhất một khoảng trống trước và sau các từ
NOT, AND, OR.
3.5. Phạm vi.
Phạm vi là một yếu tố của FOX để chỉ ra tập hợp các bản ghi được thao
tác đối với các lệnh xử lý các bản ghi trên tệp dữ liệu.
FOX sử dụng các phạm vi sau:
ALL - bao gồm tất cả các bản ghi.
NEXT n - gồm n bản ghi tiếp theo kể từ bản ghi hiện thời (đang làm
việc).
RECORD n - chỉ gồm bản ghi có số hiệu là n (số hiệu bản ghi chính là số
thứ tự của bản ghi trong tệp).
REST - gồm tất cả các bản ghi kể từ bản ghi đang làm việc đến cuối tệp.
4. CÁC LỆNH CƠ BẢN CỦA FOX.
- Tác động: Lệnh cho hiện ra một bảng khai báo để người sử dụng khai
báo cấu trúc tệp, có dạng:
Khi đó người sử dụng khai báo lần lượt từng trường, với:
+ Tên trường: Đặt theo qui tắc ở phần 3.3.2.
+ Loại trường: Ta chỉ xét mỗi trường thuộc một trong năm loại:
C (Character) - Trường loại ký tự.
N (Numeric) - Trường loại số.
D (Date) - Trường loại ngày tháng.
L (Logical) - Trường loại logic.
M (Memo) - Trường loại ký ức.
+ Độ rộng trường:
Trường loại ký tự (C) có độ rộng ≤ 254
Trường loại số (N) có độ rộng ≤ 20
Trường loại ngày tháng (D) có độ rộng = 8
Trường loại logic (L) có độ rộng =1
Trường loại memo (M) có độ rộng ≤ 5000
+ Số chữ số thập phân: Chỉ phải khai báo với trường số, nếu là 0 thì số đó
là số nguyên, nếu > 0 thì là số thực và khi đó mất một vị trí cho dấu chấm ngăn
cách phần nguyên và phân.
Kết thúc khai báo bấm ^ W ↵ hoặc ↵↵ , khi đó xuất hiện của sổ hỏi:
Ở đây, trường GT thuộc loại L chỉ nhận T hoặc F, vậy phải mã tương ứng
T tương ứng giới tính gì (giả sử T - Nam), F tương ứng với giới tính gì (giả sử
F - Nữ) và khi nhập dữ liệu bắt buộc phải tuân theo qui định đó để có thể xử lý
được về sau.
4.1.2. Mở - đóng tệp dữ liệu.
- Khái niệm : Tệp dữ liệu được lưu trữ trên đĩa. Để làm việc với tệp nào,
ta phải đọc tệp đó vào RAM - gọi là mở tệp. Sau khi làm việc xong ta ghi lại
thông tin của tệp ở RAM trở lại đĩa - gọi là đóng tệp.
- Để mở tệp, ta dùng lệnh:
USE < tên tệp >
Trong đó: <tên tệp> là tên tệp dữ liệu cần mở, phầm mở rộng ngầm định
là .DBF.
- Để đóng tệp, dùng một trong các lệnh:
USE - đóng tệp đang sử dụng.
CLOSE DATABASE - Đóng CSDL tức là đóng tất cả các tệp dữ liệu
đang mở.
CLOSE ALL - Đóng tất cả các tệp đang mở (trong đó có các tệp dữ
liệu).
Ngoài ra tại một vùng làm việc, khi mở một tệp dữ liệu, nếu trước đó đã
có một tệp khác đang mở, máy sẽ tự đóng tệp đang mở trước đó:
Ví dụ:
USE A:\VATTU.DBF
USE CHUNGTU
USE
4.1.3 Lệnh APPEND
- Dùng để bổ sung thêm các bản ghi vào cuối tệp dữ liệu đang mở
- Dạng: APPEND
- Tác động: Lệnh sẽ cho bổ sung thêm các bản ghi vào cuối tệp đang mở, dữ
liệu do người sử dụng nhập từ bàn phím, kết thúc nhập dữ liệu bấm ^W hoặc
^End.
Ví dụ: Giả sử tại thư mục làm việc đã có tệp QLHS.DBF, cần nhập
thêm danh sách học sinh vào tệp ta viết các lệnh:
USE QLHS
APPEND
Xuất hiện cửa sổ nhập bổ sung bản ghi:
(Nhập dữ liệu lần lượt từng bản ghi kết thúc bấm ^W)
USE
4.1.4. Lệnh APPEND FROM ...
- Dùng để bổ sung các bản ghi vào cuối tệp đang mở nhưng dữ liệu được
lấy từ một tệp dữ liệu khác đã có trên đĩa.
- Dạng:
APPEND FROM <tên tệp> [ FOR <biểu thức logic>]
Trong đó: <tên tệp> là tên của tệp dữ liệu khác chưa mở hoặc mở ở vùng
làm việc khác.
- Tác động : Lệnh sẽ cho bổ sung các bản ghi từ tệp xác định bởi
<tên tệp> vào cuối tệp dữ liệu đang mở. Dữ liệu chỉ có ở những trường giữa hai
tệp trùng tên nhau, ngược lại bỏ trống.
Nếu có mệnh đề FOR <biểu thức logic> thì chỉ những bản ghi thoả mãn
biểu thức logic (làm biểu thức logic đúng) được bổ sung.
- Ví dụ: Giả sử tại A:\ có tệp DSBS.DBF cùng cấu trúc với tệp
QLHS.DBF. Cần bổ sung danh sách học sinh khoá 36 từ tệp DSBS.dbf vào
cuối tệp QLHS.dbf thì viết:
USE QLHS
APPEND FROM A:\DSBS FOR KHOA = ‘36’
USE
Nếu bỏ FOR ... thì tất cả các bản ghi từ tệp DSBS.dbf sẽ được bổ sung
vào cuối tệp QLHS.dbf
4.1.5. Lệnh COPY STRUCTURE
- Dùng để sao chép cấu trúc tệp dữ liệu đang mở sang một tệp khác
- Dạng: COPY STRUCTURE TO <tên tệp>
Trong đó: <tên tệp> là tên tệp dữ liệu - kết quả của việc sao chép cấu trúc
- Tác động: Lệnh sẽ sao cấu trúc của tệp dữ liệu đang mở để có tệp mới
có tên xác định bởi <tên tệp>
- Ví dụ:
USE QLHS
COPY STRUCTURE TO A:\LUU.DBF
4.1.6. Lệnh COPY
- Lệnh này sẽ sao cả tệp dữ liệu này thành một tệp khác
- Dạng: COPY TO <tên tệp> [FOR <biểu thức logic>]
Trong đó: <tên tệp> là tên tệp dữ liệu kết quả sau khi sao được từ tệp dữ
liệu đang mở.
- Tác động: Lệnh sẽ sao tệp đang mở để có tệp mới xác định bởi tên tệp.
Nếu có FOR <biểu thức logic> thì chỉ các bản ghi thoả mãn biểu thức
logic được sao sang.
Ví dụ 1: USE QLHS
COPY TO A:\BANSAO
Lệnh COPY trên sao toàn bộ tệp QLHS. DBF thành tệp BANSAO.DBF
tại gốc A:
Ví dụ 2: USE QLHS
COPY TO K40 FOR KHOA = ‘40’
Lệnh COPY này sao các bản ghi có trường KHOA nhận giá trị là 40
(nghĩa là khoá 40) từ tệp QLHS.DBF thành tệp K40.DBF đặt tại thư mục làm
việc.
Biểu thức logic để xác định điều kiện các bản ghi cần xem. (Thoả mãn
biểu thức logic thì đưa ra cho xem, ngược lại thì không đưa ra).
- Tác động: Lệnh sẽ đưa ra màn hình hoặc máy in nội dung các bản ghi
nằm trong <phạm vi> và chỉ gồm các trường theo yêu cầu (có tên trong danh
sách trường).
Nếu có For <BTlogic> thì chỉ cho xem nội dung các bản ghi làm
BTlogic đúng (.T.)
TO PRINTER nếu có thì các thông tin đó được đưa ra máy in, nếu
không thì đưa ra màn hình.
Ví dụ: Xét tệp QLHS.DBF (ở thư mục làm việc)
+ Ví dụ 1: Cần xem bản ghi số 50
USE QLHD
GOTO 50
DISPLAY
USE
+ Ví dụ 2: Cần in danh sách học sinh của khoá 40, gồm họ tên, lớp, số
báo danh, ngày sinh, giới tính.
USE QLHS
LIST FIELDS HTD, TEN, LOP, SDB, NS, GT FOR KHOA = ‘40’ TO
PRINTER
USE
+ Ví dụ 3: Xem danh sách học sinh nữ có điểm trung bình từ 8.5 trở lên
LIST FOR .NOT. GT .AND. DTB > = 8.5
+ Ví dụ 4: Xem danh sách học sinh nam sinh trước ngày 1/1/1970
LIST FOR GT . AND. NS < = {01/01/70}
4.3.4. Lệnh MODIFY STRUCTURE
- Dùng để : Sửa lại cấu trúc tệp trúc tệp dữ liệu đang mở.
- Dạng: MODIFY STRUCTURE
- Tác động: Lệnh cho hiện lại bảng cấu trúc của tệp đang mở để người sử
dụng hiệu chỉnh lại cấu trúc.
Có thể qui về ba thao tác sửa chính sau:
+ Thêm một trường: Đặt con trỏ màn hình vào trường cần chèn thêm
trường, sau đó ấn Alt+I (hoặc kích chuột vào lựa chọn Insert trên màn hình của
lệnh) khi đó một trường mới có tên <NEW FIELD> được chèn vào và ta sẽ tiến
hành khai báo các đặc trưng của trường cần chèn (gồm tên, loại, độ rộng và số
chữ số thập phân của trường số)
+ Xoá bớt một trường: Đặt trỏ tại trường cần xoá rồi ấn Alt+D ( hoặc
chọn lựa chon Delete trong màn hình của lệnh)
+ Sửa trên một trường, gồm: Đặt con trỏ vào vị trí cần sửa, rồi tiến hành
các sửa chữa cần thiết. Sửa trường thường là: Sửa tên trường, sửa loại trường,
sửa độ rộng và sửa số chữ số thập phân.
Khi đó, trong ba trường hợp sửa loại, độ rộng, phần thập phân có thể gây
mất dữ liệu.
Kết thúc sửa ấn ^W (hoặc ^↵ hoặc kích chuột vào lựa chọn OK)
Chú ý: Khi sửa cấu trúc tệp dữ liệu, máy sẽ tự động sinh ra tệp lưu cất
cùng tên, phần mở rộng .BAK để lưu lại nội dung tệp trước khi sửa chữa .
Khi cần lấy lại tệp cũ, chỉ cần đổi thành phần mở rộng .DBF là có thể sử
dụng được ngay.
4.3.5 Hai lệnh BROWSE và EDIT
- Cả hai lệnh đều dùng để sửa lại nội dung các bản ghi trong tệp đang
mở.
- Dạng:
BROWSE [ Fields < ds trường >] [ FOR < BT logic> ]
EDIT [ fields < ds trường> ] [ For < BT logic>]
Trong đó: Danh sách trường để xác định tên các trường cần hiển thị để
sửa, ngầm định là mọi trường trong tệp đang mở.
- Tác động: Hai lệnh đều cho sửa các bản ghi trong tệp bắt đầu từ bản ghi
hiện thời, bao gồm các trường có tên trong danh sách trường. Nếu có
For < bt logic > thì chỉ cho sửa các biểu ghi hàm biểu thức logic đúng.
Để di chuyển con trỏ đến các trường và bản ghi cần sửa, dùng các phím
dịch chuyển con trỏ .
Kết thúc sửa ấn ^W hoặc ^End.
Hai lệnh BROWSE và EDIT chỉ khác nhau cách hiển thị khi sửa:
BROWSE hiển thị dạng bảng, mỗi bản ghi trên một dòng.
USE VATTU
REPLACE KL WITH KL ∗ 1000 FOR DVT = ‘TAN’
REPLACE DG WITH DG /1000 FOR DVT = ‘TAN’
REPLACE DVT WITH ‘KG’ FOR DVT = ‘TAN’
REPLACE ALL TT WITH KL ∗ DG
USE
Tất nhiên ba lệnh REPLACE đầu tiên cùng có mệnh đề For < btlogic>
như nhau, có thể gộp thành một lệnh như sau:
REPLACE KL WITH KL ∗ 1000, DG WITH DG/1000, DVT WITH;
‘KG’ FOR DVT = ‘TAN’
Nhận xét: Với bản chất là để thay thế giá trị cho trường dữ liệu, lệnh
REPLACE thường dùng để tính toán và ghi kết quả vào trường.
4.4. Các lệnh thêm, bớt bản ghi.
4.4.1. Lệnh INSERT
- Dùng để chèn một bản ghi vào bất kỳ vị trí nào trong tệp dữ liệu đang
mở. Tuy nhiên việc này ít dùng máy phải thực hiện ghi chép lại tệp nên tốc độ
rất chậm.
- Dạng:
INSERT [ BEFORE] [ BLANK]
- Tác động: Lệnh sẽ cho chèn một bản ghi vào tệp. Cụ thể:
+ Mệnh đề BEFORE:
Nếu có: chèn trước bản ghi hiện thời
Nếu không: Chèn sau bản ghi hiện thời
+ Mệnh đề BLANK :
Nếu có: Cho chèn một bản ghi trắng (rồng)
Bản ghi rỗng sẽ nhận giá trị là xâu gồm các khoảng trống ở trường kiểu
C, nhận 0 ở trường kiểu N, nhận . F. ở trường kiểu L, nhận .. / .. / .. ở
trường kiểu ngày D.
Nếu không: sau khi chèn bản ghi trắng cho người sử dụng nhập dữ
liệu vào bản ghi đó, kết thúc ấn ^W
Ví dụ: Xét tệp VATTU. DBF, cần chèn một bản ghi rỗng để nó là bản
ghi số 150.
USE VATTU
GOTO 150
INSERT BEFORE BLANK
USE
4.4.2. Lệnh DELETE
- Dùng để: Đánh dấu xoá các bản ghi trong tệp đang mở (chưa xoá hẳn)
- Dạng :DELETE [ phạm vi] [ FOR < BTlogic> ]
Trong đó : Phạm vi ngầm định là bản ghi hiện thời.
Tác động: FOX sẽ đánh dấu xoá các bản ghi thuộc phạm vi.
Nếu có For < BTlogic> thì chỉ các bản ghi làm <BT logic> đúng được
đánh dấu xoá.
- Ví dụ : Xét tệp QLHS.dbf
+ Ví dụ1: Đánh dấu xoá bản ghi số 50
USE QLHS
GOTO 50
DELETE
USE
+ Ví dụ 2: Đánh dấu xoá danh sách học sinh khoá 28
USE QLHS
DELETE FOR KHOA = ‘28’
USE
4.4.4. Lệnh RECALL
- Dùng để gọi lại các bản ghi đã bị đánh dấu xoá, thực chất RECALL huỷ
bỏ việc đánh dấu xoá của DELETE.
- Dạng:
RECALL [phạm vi] [FOR < BT logic> ]
Trong đó: Phạm vi ngầm định là bản ghi hiện thời.
- Tác động: FOX sẽ huỷ bỏ việc đánh dấu xoá trên các bản ghi thuộc
phạm vi đã bị đánh dấu xoá. Nếu có For < BTlogic> thì chỉ huỷ bỏ đánh dấu
xoá trên các bản ghi làm BT logic đúng.
- Ví dụ: Giả sử Tệp QLHS. DBF đã bị đánh dấu xoá toàn bộ các bản ghi
trong tệp, cần gọi lại các bản trừ các bản ghi có trường KHOA =’ 28’ :
USE QLHS
RECALL FOR KHOA # ‘28’
USE
4.4.5. Lệnh PACK
- Dùng để loại bỏ tất cả các bản ghi đã bị đánh dấu xoá ở tệp đang mở
- Dạng: PACK
Khi thực hiện PACK, các bản ghi bị đánh dấu xoá bị loại bỏ hẳn mà
không có cách nào có thể khôi phục lại được, sau đó số hiệu các bản ghi sẽ
được xác định lại.
4.4.6. Lệnh ZAP
- Dùng để huỷ bỏ tất cả các bản ghi trong tệp, bất kể các bản ghi có bị
đánh dấu xoá hay không.
- Dạng: ZAP
Lệnh ZAP tương đương với hai lệnh
DELETE ALL
PACK
4.5. Sắp xếp và tìm kiếm bản ghi.
4.5.1. Lệnh INDEX
- Dùng để tạo tệp chỉ dẫn để sắp xếp tệp đang mở theo giá trị tăng dần của
tiêu thức sắp xếp.
- Dạng:
INDEX ON <Biểu thức> TO <Tên tệp> [ FOR < BT logic>]
Trong đó:
Biểu thức: Là một biểu thức bất kỳ dùng làm tiêu thức sắp xếp.
Tên tệp : Là tên tệp chỉ dẫn, phần mở rộng ngầm định là .IDX
- Tác động: Khi thực hiện INDEX, Fox sẽ dùng giá trị của biểu thức làm
khoá để lập chỉ dẫn, sắp xếp sao cho trên các bản ghi từ đầu đến cuối tệp, biểu
thức có giá trị tăng dần. Nếu có các bản ghi có cùng giá trị của khoá sắp xếp,
Fox sẽ sắp xếp các bản ghi đó theo trật tự vật lý của các bản ghi.
Khi trong lệnh có mệnh đề For <BTlogic> thì chỉ có các bản ghi làm
biểu thức logic đúng mới được coi là có mặt trong tệp và tham gia sắp xếp.
- Ví dụ:
Ví dụ 1: Xét tệp QLHS .DBF
Cần in một doanh sách học sinh khoá 40 đã xếp theo thứ tự alphabet của
tên học sinh.
USE QLHS
INDEX ON TEN TO CD1. idx FOR KHOA = ‘40’
LIST TO PRINTER
USE
Ví dụ 2: Cần in danh sách khoá 40 xếp theo lớp, cùng lớp xếp theo điểm
trung bình tăng dần.
USE QLHS
INDEX ON LOP + STR (DTB, 5, 2) TO CD 2 FOR KHOA = ‘40’
LIST TO PRINTER
USE
4.5.2. Lệnh SORT
- Dùng để sắp xếp lại tệp dữ liệu, khác với lệnh INDEX, lệnh SORT
không sắp xếp trên các bản ghi của tệp đang mở mà tạo ra một tệp mới với các
bản ghi lấy của tệp dữ liệu đang mở đã được sắp xếp theo yêu cầu của lệnh.
- Dạng:
SORT TO <tên tệp> ON <DS biểu thức khoá [/A/D/C]>[FOR<BT
logic>]
Trong đó:
Tên tệp: Là tên tệp dữ liệu để ghi kết quả đã sắp xếp.
Danh sách biểu thức gồm các biểu thức viết cách nhau dấu phảy, dùng
làm tiêu thức sắp xếp. Nếu có nhiều biểu thức thì ưu tiên cho các biểu
thức viết trước.
- Tác động: Lệnh sẽ sắp xếp tệp dữ liệu dựa vào giá trị các biểu thức trong
danh sách biểu thức.
Nếu có /A thì xếp tăng dần. Nếu có /D thì xếp giảm dần. (Ngầm định là
/A)
Nếu có /C thì sẽ không phân biệt sự khác nhau giữa chữ in và thường.
Kết quả sắp xếp được ghi vào một tệp dữ liệu có tên xác định bởi <tên
tệp>.
Nếu có FOR <BT logic> thì trong tệp kết quả chỉ chứa các bản ghi làm
<BT logic> nhận giá trị đúng.
- Ví dụ: Xét tệp VATTU.DBF
Ta cần xem lại các chứng từ tháng 10/1999 đã nhập vào máy được xếp
theo mã vật tư, nếu cùng mã vật tư, xếp theo số tiền giảm dần.
USE VATTU
SORT TO SXEP ON MAVT, TT/D/C FOR MONTH (NLCT) =
10; .AND. YEAR (NLCT) = 1999
USE SXEP
DISPLAY ALL
USE
Trên thực tế lệnh SORT ít được sử dụng hơn lệnh INDEX vì tốn bộ nhớ
và tốc độ thực hiện chậm.
4.5.3. Lệnh LOCATE
- Dùng để tìm kiếm và định vị con trỏ bản ghi đến bản ghi thoả mãn một
điều kiện nào đó. Lệnh được dùng để tìm kiếm bản ghi.
- Dạng: LOCATE FOR <BTlogic>
Trong đó: BT logic xác định điều kiện tìm kiếm
- Tác động:
FOX sẽ duyệt lần lượt từng bản ghi bắt đầu từ đầu tệp và sẽ dừng lại đặt
con trỏ vào bản ghi đầu tiên thoả mãn biểu thức logic.
Trường hợp có nhiều bản ghi cùng thoả mãn điều kiện tìm kiếm, FOX
vẫn đặt con trỏ vào bản ghi đầu tiên làm biểu thức logic đúng, muốn chuyển
con trỏ đến các bản ghi tiếp theo cũng thỏa mãn biểu thức logic, ta dùng lệnh
CONTINUE. Với cách thức tìm kiếm của LOCATE như vậy, người ta còn gọi
LOCATE là lệnh tìm kiếm theo kiểu tuần tự. Cách này có ưu điểm là tìm kiếm
được trên bất kỳ tệp có được sắp xếp hay không. Tuy nhiên, nhược điểm của
lệnh là tốc độ tìm kiếm rất chậm.
Ví dụ: Xét tệp VATTU.DBF, cần tìm để đưa ra xem số lượng, đơn giá,
số tiền trên chứng từ số 20/VL nhập ngày 15/10/1999
USE VATTU
Trong đó:
DS trường số: Xác định tên các trường số cần tính trung bình cộng,
ngầm định là mọi trường số trong tệp đang mở.
DS biến nhớ: Gồm các tên biến nhớ để lưu giữ kết quả sau khi tính
Tác động: Lệnh sẽ tính trung bình cộng của các trường số được chỉ
định rồi gửi kết quả vào các biến trong <ds biến>, nếu có For
<BTlogic> thì chỉ tính trên các bản ghi làm biểu thức logic nhận giá
trị đúng (. T.)
- Ví dụ: Giả sử có tệp LUONGCB. DBF để tính lương cho cán bộ có cấu
trúc như sau:
Cần tính lương (thực lĩnh) bình quân của cán bộ thuộc đơn vị có mã
HCO6
USE LUONGCB
AVERAGE TL TO LTB FOR MADV = ‘HCO6’
? LTB
USE
4.6.2. Lệnh SUM
- Dùng để tính tổng giá trị trong các trường số của tệp dữ liệu.
- Dạng lệnh:
SUM [<DS trường >TO <ds biến>] [ FOR <BT logic>]
Trong đó:
DS trường: Xác định tên các trường số cần tính tổng, ngầm định là
mọi trường số của tệp đang mở.
DS biến: Gồm tên các biến để lưu giữ kết quả sau khi tính tổng.
- Tác động: Lệnh sẽ tính tổng các trường số có tên trong DS trường rồi
gửi kết quả vào các biến trong danh sách biến (nếu có).
Nếu có For <BT logic> thì chỉ tính tổng trên các bản ghi làm BTlogic
đúng.
- Ví dụ:
Xét tệp LUONGCB. DBF, cần tính tổng tiền thực lĩnh và các khoản phải
trừ của đơn vị có mã 01
USE LUONGCB
SUM PT, TL, TO T1, T2 FOR MADV = ‘01’
? ‘Tổng phải trừ:’, T1
? ‘Tổng thực lĩnh:’, T2
USE
4.6.3. Lệnh COUNT
- Dùng để: Đếm số bản ghi trong tệp, từ đó suy ra số đối tượng tương
ứng.
- Dạng lệnh:
COUNT [ TO <Biến> ] [ FOR < BTlogic>]
Trong đó: Biến là một biến bộ nhớ để lưu giữ kết quả sau khi đếm.
- Tác động: Lệnh sẽ đếm số bản ghi trong tệp rồi gửi kết quả vào biến.
Nếu không có TO <biến> thì hiện kết quả lên màn hình với trạng thái
môi trường đang ở chế độ SET TALK ON
Nếu có FOR <BT logic> thì chỉ đếm các bản ghi làm biểu thức logic
đúng.
- Ví dụ: Xét tệp QLHS. dbf . Cần tính tỷ lệ (%) học sinh nữ có điểm trung
bình từ 9 trở lên
USE QLHS
COUNT TO TSO FOR .NOT. GT
COUNT TO TGIOI FOR .NOT.GT. AND. DTB > = 9
? ‘Tỷ lệ:’ , TGIOI/TSO ∗ 100, ‘%’
USE
4.6.4. Lệnh TOTAL
- Dùng để : Tính tổng các trường số trên từng nhóm bản ghi của tệp dữ
liệu.
Nhóm bản ghi gồm tập hợp các bản ghi kế tiếp nhau có cùng giá trị của
tiêu thức phân nhóm. Khi phân nhóm, sẽ xét từ đầu tệp.
Ví dụ: Giả sử tệp LUONGCB. DBF có nội dung
HT MADV ... PT TL
A 01 ... 1 2
B 02 ... 3 4
C 01 ... 5 6
Nếu dựa vào mã đơn vị (trường MADV) để phân nhóm thì Fox sẽ chia
tệp thành ba nhóm bản ghi. Như vậy là không phù hợp với quan niệm chung về
nhóm đối tượng vì Fox không chỉ xét đến giá trị của tiêu thức phân nhóm mà
còn xét cả đến vị trí các bản ghi. Để cho phù hợp, trước khi phân nhóm ta sắp
xếp tệp để các bản ghi không bị ảnh hưởng bởi vị trí khi phân nhóm. Nguyên
tắc là muốn phân nhóm dựa vào tiêu thức nào thì trước đó phải tiến hành sắp
xếp dựa vào tiêu thức đó.
Chẳng hạn tệp LUONGCB.DBF , sau khi thực hiện lệnh: INDEX ON
MADV TO P các bản ghi sẽ có trật tự như sau:
HT MADV ... PT TL
A 01 ... 1 2
C 01 5 6
B 02 3 4
Bây giờ có thể phân nhóm chính xác: Hai bản ghi đầu là một nhóm, bản
ghi thứ ba là một nhóm.
- Dạng lệnh:
TOTAL TO <tên tệp> ON <Biểu thức>[FIELDS<ds trường>][FOR<BT
logic>]
Trong đó:
Tên tệp: Là tên tệp dữ liệu dùng để lưu giữ kết quả sau khi tính tổng.
Biểu thức: Là biểu thức bất kỳ, dùng làm tiêu thức phân nhóm.
DS trường gồm tập hợp tên các trường số cần tính tổng, ngầm định là
tất cả các trường số trong tệp đang mở.
- Tác động: Dựa vào giá trị của biểu thức để phân tệp dữ liệu thành các
nhóm bản ghi, sau đó tính tổng các trường số có tên trong danh sách trường
của từng nhóm rồi gửi tổng mỗi nhóm vào một bản ghi của tệp có tên xác định
bởi <tên tệp>. Tệp kết quả này có cùng cấu trúc với tệp gốc; Trên các bản ghi,
giá trị các trường cần tính tổng sẽ nhận giá trị là tổng của nhóm tương ứng, còn
các trường không được tính tổng sẽ lấy giá trị trên bản ghi đầu tiên của nhóm.
Trường hợp có For <BT logic> thì chỉ các bản ghi làm biểu thức logic
đúng mới được tham gia tính tổng.
- Ví dụ:
Ví dụ 1: Xét tệp LUONGCB.DBF, cần in ra bảng tổng hợp lương của
từng đơn vị
USE LUONGCB
INDEX ON MADV TO CD1
TOTAL TO KQ1. dbf ON MADV
USE KQ1
LIST FIELDS MADV, PT, TL TO PRINTER
USE
Ví dụ 2: Xét tệp VATTU.DBF, cần lập một báo cáo đơn giản về tổng
khối lượng và số tiền nhập vật tư từng loại trong quí 4/1999
USE VATTU
INDEX ON MAVT TO CD2 FOR LNV. AND. MONTH(NLCT) =
10; . AND. YEAR(NLCT) = 1999
TOTAL TO KQ2 ON MAVT FIELDS KL, TT
USE KQ2
LIST FIELDS TENVT, MAVT, KL, TT
CLOSE ALL
- Ví dụ:
INPUT ‘vào họ tên:’ TO HT
INPUT ‘ Ngày sinh:’ TO NS
INPUT ‘Hệ số lương:’ TO HLS
Chú ý: Khi vào dữ liệu cho INPUT, phải viết hằng theo đúng quy định
của FOX.
5.1.3. Lệnh ACCEPT
- Dùng để nhận một xâu ký tự từ bàn phím trong quá trình thực hiện
chương trình.
- Dạng: ACCEPT [ Lời nhắc] TO <Biến>
- Tác động: Tương tự INPUT, nhưng dữ liệu vào phải là một hằng xâu,
không cần đặt trong cặp dấu nháy.
- Ví dụ:
ACCEPT ‘In cho khoá:’ TO KH
5.1.4. Lệnh ? và lệnh ??
Đều dùng để đưa thông tin ra màn hình hoặc máy in.
Dạng: ? [Danh sách biểu thức] [ FONT ‘Kiểu font’, <cỡ>]
?? [ Danh sách biểu thức] [ FONT ‘Kiểu font’, <cỡ>]
Trong đó: Kiểu Font xác định font chữ cần đưa ra.
Cỡ xác định cỡ chữ đưa ra.
- Tác động: Cả hai lệnh đều đưa ra màn hình hoặc máy in giá trị các
biểu thức trong danh sách biểu thức, song:
Lệnh ? luôn đưa từ đầu dòng mới;
Lệnh ?? Đưa tiếp từ vị trí trống còn lại trên dòng hiện tại.
Việc đưa ra thiết bị nào là do lệnh:
SET PRINTER ON /OFF đang có hiệu lực. Ngầm định là SET
PRINTER OFF - nghĩa là đưa ra màn hình, ngược lại nếu là SET PRINTER
ON thì cả hai lệnh đều đẩy thông tin ra máy in.
Mệnh đề [ FONT ‘Kiểu font’, <cỡ> ] nếu có thì thông tin đưa ra sẽ
theo Font và cỡ chữ được chọn.
Nếu trong lệnh không có danh sách biểu thức thì để trắng chỗ đưa ra.
INPUT ‘vào n’ TO N
P =1
FOR I = 1 TO N
P =P ∗ I
ENDFOR
? ‘P =’, P
Ví dụ 2: Chương trình xét một số nguyên dương n > 2 có là số nguyên tố
không?
INPUT ‘vào số nguyên dương >2:’ TO N
FOR I = 2 TO N - 1
IF MOD(N, 2) = 0
KQ = ‘N không là’
EXIT
ENDIF
KQ = ‘N là’
ENDFOR
? KQ + ‘số nguyên tố’
5.3.2. Lệnh DO WHILE ... ENDDO
- Dùng để tổ chức tất cả hai loại chu trình (có số lần lặp biết trước và
không biết trước).
- Dạng lệnh:
DO WHILE <BT logic>
<các lệnh Fox>
ENDDO
Tác động:
Gặp DO while, máy kiểm tra giá trị của biểu thức logic
Nếu biểu thức đúng: Thực hiện <các lệnh Fox> trong thân chu trình,
khi gặp ENDDO, điều khiển lại trả về DO WHILE và tiếp tục lặp lại
quá trình trên
Nếu biểu thức sai: Đã thực hiện xong chu trình, thực hiện tiếp lệnh
đứng sau ENDDO.
EJECT
CLOSEALL
RETURN
Sau khi thực hiện lệnh SET FILTER TO có biểu thức logic thì chỉ những
bản ghi làm BTlogic đúng được coi là có mặt trong tệp. Lệnh SET FILTER
TO (không có BTlogic) sẽ huỷ bỏ lệnh đặt lọc trước đó.
Tuy nhiên lệnh này chỉ có hiệu lực khi con trỏ bản ghi đã được di chuyển.
5.4.7. SET SAFETY ON /OFF
Để bật hoặc tắt chế độ bảo vệ file trước khi ghi đè hay xoá tệp.
Nếu SET SAFETY ON máy sẽ hỏi lại người sử dụng có khẳng định
không trước khi ghi đè hay xoá tệp, nếu SET SAFETY OFF thì máy không
yêu cầu người sử dụng khẳng định một lần nữa.
5.4.8. SET TALK ON/OFF
Để bật hoặc tắt chế độ hiện các kết quả trung gian lên màn hình hay máy
in.
Nếu SET TALK ON thì các kết quả tính toán trung gian được đưa ra màn
hình hay máy in tuỳ SET PRINTER là ON hay OFF, nếu ngược lại thì các kết
quả đó không được đưa ra.
5.4.9. SET STATUS ON /OFF
Để bật hoặc tắt dòng trạng thái làm việc của FOX.
Dòng trạng thái là dòng 22 trên màn hình để thông báo một số trạng thái
làm việc với FOX.
Nếu SET STATUS ON thì dòng trạng thái được bật.
Nếu SET STATUS OFF thì dòng trạng thái tắt.
6. ỨNG DỤNG FOX ĐỂ XÂY DỰNG BỘ CHƯƠNG TRÌNH CHO CÁC BÀI
TOÁN QUẢN TRỊ DỮ LIỆU.
xuyên, phụ cấp khác, khấu trừ thường xuyên, khấu trừ khác. Yêu cầu hàng
tháng phải in ra các bảng biểu sau:
Bảng 1.1
Bảng lương tháng .... năm .......
Đơn vị: <Tên đơn vị>
Các khoản Các khoản Được lĩnh
ST Họ và C H L phụ cấp khấu trừ
T tên V SL C
TX Khác TX Khác ST Ký
1
..
Cộng * * * * * *
Bảng 1.2
Bảng tổng hợp lương các đơn vị tháng .... năm ......
Các khoản phụ Các khoản khấu Được lĩnh
Số Tên đơn L cấp trừ
tt vị C
TX Khác TX Khác ST Ký
1
..
Cộng * * * * * *
...
Cộng ****
Biểu 2.2: Sổ theo dõi tình hình nhập vật tư theo loại
Loại vật tư <Tên vật tư>
Từ ngày .... đến ngày.... năm ...
Số Phiếu Ngày Số lượng Tiền
..
...
Cộng ***** ****
Biểu 2.4: Sổ theo dõi tình hình xuất vật tư theo loại
Loại vật tư <Tên vật tư>
Từ ngày .... đến ngày.... năm ...
Số Phiếu Ngày Số lượng Tiền
..
...
Cộng ***** ****
Biểu 2.5: Biểu theo dõi tình hình Nhập – Xuất – Tồn
Từ ngày ..... dến ngày ..... năm ......
Tên ĐV Tồn ĐK Nhập TK Xuất TK Tồn CK
Cộng ** ** ** **
6.1.2 Đặc điểm của các bài toán quản trị dữ liệu.
Qua 2 ví dụ trên và một số các bài toán quản trị dữ liệu khác như bài toán
quản lý nhân sự, bài toán tài chính kế toán... ta thấy các bài toán này có một số
đặc điểm như sau:
Các bài toán đều yêu cầu lưu trữ một khối lượng lớn các dữ liệu, các
dữ liệu được lưu trữ trong các tệp dữ liệu, số lượng các bản ghi trong
các tệp được coi là khối lượng dữ liệu cần xử lý của bài toán. Chẳng
hạn bài toán lương, số lượng cán bộ và số lượng các đơn vị phòng ban
chính là khối lượng dữ liệu của bài toán, còn bài toán quản lý vật tư
thì số lượng các phiếu nhập, phiếu xuất và số lượng danh mục vật tư là
khối lượng của bài toán.
Một bài toán quản trị dữ liệu thường phải xử lý trên nhiều tệp dữ liệu,
các tệp dữ liệu phải có sự liên kết móc nối với nhau thông qua các
trường kho. Trong các tệp các trường khoá dùng để móc nối các tệp
thường để dưới dạng mã để đảm bảo tính chuẩn của thông tin.
Kết quả của bài toán quản trị dữ liệu chủ yếu là các bảng biểu in ra
trên giấy hoặc các xem trên màn hình của máy tính.
Các thao tác xử lý của bài toán quản lý dữ liệu không đòi hỏi các phép
tính phức tạp, mà chủ yếu là các phếp toán cộng trừ, nhân chia đơn
giản, các thao tác thương gặp nhiều trong các bài toán quản trị dữ liệu
là các thao tác lọc bản ghi, phân nhóm, tìm kiếm, xắp xếp lại dữ liệu,
liên kết dữ liệu, lập các báo cáo (REPORT), cung cấp thông tin nhanh
.
6.2. Tổ chức xây dựng bộ chương trình cho bài toán quản trị
dữ liệu.
Để xây dựng một bài toán quản trị dữ liệu ta phải thực hiện hai công việc
cơ bản đó là tạo lập một cơ sở dữ liệu và xây dựng một bộ chương trình xử lý
cơ sở dữ liệu đáp ứng được yêu cầu quản lý. Các công việc đó được thực hiện
như sau:
6.2.1 Tạo cơ sở dữ liệu.
Căn cứ vào yêu cầu của bài toán và tính chất từng loại thông tin, trong
quá trình tạo các tệp dữ liệu ta thường chia thành ba nhóm. Đó là nhóm tệp mã
đối tượng, nhóm tệp dữ liệu chính, nhóm tệp kết quả, thông thường mỗi nhóm
tệp ta đặt riêng một thư mục. Đặc trưng của các nhóm như sau:
Nhóm tệp mã hoá đối tượng, chứa các dữ liệu phục vụ việc mã hoá
các dữ liệu của bài toán. Trong các bài toán quản trị dữ liệu có các
thông tin cần có độ chuẩn dùng làm các trường khoá cho việc liên kết,
tìm kiếm và xử lý dữ liệu. Những thông tin đó khi đưa vào máy ta phải
đưa ở dạng mã, nhưng khi in ra ta lại phải trả lại đúng giá trị của nó.
Để thực hiện việc đó trong khi tạo cơ sở dữ liệu ta tạo các tệp mã đối
tượng, mỗi dữ liệu cần mã hoá ta phải tạo cho nó một tệp mã, trong
tệp đó có tối thiểu hai trường là trường mã đối tượng và trường tên đối
tượng. Chẳng hạn trong bài toán lương ở trên thì có hai thông tin cần
được mã đó là thông tin về đơn vị làm việc của cán bộ và tên cán bộ
và vì vậy ta sẽ tạo hai tệp mã, một tệp dùng để tra mã của đơn vị, một
tệp dùng để tra mã cán bộ, hoặc trong bài toán quản lý vật tư thì tên
vật tư phải được mã hoá, như vậy, ta phải tạo một tệp mã tên vật tư.
Thông tin trong các tệp mã có thể được sử dụng lâu dài trong nhiều
năm.
Nhóm dữ liệu chính của bài toán đó là các dữ liệu phục vụ cho xử lý
thông tin hàng ngày và dùng để tạo các thông tin kết quả theo yêu cầu
quản lý. Đó chính là các dữ liệu đầu vào của bài toán. Các dữ liệu này
có tính rất động, nó được cập nhật thường xuyên. Số lượng tệp dữ liệu
nhóm này tuỳ thuộc vào từng bài toán. Chẳng hạn bài toán lương ở
trên ta chỉ cần 1 tệp chứa các thông tin cần thiết về từng cán bộ (Như:
Họ và tên, đơn vị công tác, hệ số lương, phụ cấp thường xuyên, phụ
cấp khác, khấu trừ thường xuyên, khấu trừ khác) để tính và in ra đưọc
các bảng biểu kết quả, còn bài toán quản lý vật tư thì phải cần tới ba
tệp, một tệp chứa số tồn đầu kỳ, một tệp chứa các phiếu nhập vật tư,
một tệp chứa các phiếu xuất vật tư. Các thông tin trong các tệp này
thường chỉ có giá trị trong một niên độ nhất định.
Nhóm dữ liệu kết quả, đó chính là các tệp chứa các thông tin kết quả
của một yêu cầu xử lý nào đó để chuẩn bị in ra máy in hoặc đưa ra
trên màn hình, hoặc chuyển tiếp cho quá trình xử lý tiếp theo. Các tệp
chứa thông tin kết quả chỉ là các tệp trung gian, các thông tin trong đó
được tạo khi thực hiện một yêu cầu nào đó, nên các thông tin trong
các tệp kết quả chỉ có giá trị tạm thời tại một thời điểm.
6.2.2 Xây dựng bộ chương trình xử lý.
Căn cứ vào đặc điểm và các yêu cầu của bài toán quản lý khi xây dựng bộ
chương trình ta phải phân chia bộ chương trình thành nhiều Modun chương
trình nhỏ, mỗi Modun sẽ giải quyết một yêu cầu của bài toán, số lượng các
Modun trong mỗi bộ chương trình tuỳ thuộc vào từng bài toán, song trong mọi
bài toán các Modun thường được phân thành ba nhóm chính. Đó là nhóm hệ
thống, nhóm dữ liệu, nhóm kết quả. Đặc trưng của các nhóm như sau:
Nhóm hệ thống, chứa các Modun dùng để thiết lập chung cho chương
trình. Trong nhóm này thường có các Modun về thiết lập năm làm
việc, ngày làm việc, các khai báo phần cứng, khai báo về người sử
dụng, tạo lập các tệp mã, thiết lập các tuỳ chọn .... Nhóm Modun này
rất ít khi thao tác khi thực hiện chương trình, nếu có thao tác thường
hay thực hiện khi mới vào chương trình.
Nhóm dữ liệu, nhóm này thường chứa các Modun về các thao tác trên
tệp dữ liệu. Các Modun đó có thể là Modun nhập dữ liệu, sửa dữ liệu,
tìm kiếm dữ liệu, lọc dữ liệu trên các tệp dữ liệu chính hoặc các
Modun về sao lưu, khôi phục, xoá bỏ dữ liệu.
Nhóm kết quả, nhóm này chứa các Modun về các thao tác tạo các tệp
kết quả và đưa các thông tin trong các tệp kết quả ra máy in (màn
hình) theo yêu cầu quản lý.
6.2.3 Qui trình xây dựng một bộ chương trình quản trị cơ sở dữ
liệu.
Để tiến hành xây dựng một bộ chương trình quản trị dữ liệu trên máy
tính, căn cứ vào đặc điểm của bài toán quản trị dữ liệu, căn cứ vào các công
việc cần tiến hành để xây dựng một hệ quản trị cơ sở dữ liệu, ta thấy qui trình
để tiến hành xây dựng bộ chương trình quản trị dữ liệu gồm các bước sau:
Bước 1: Lập bài toán, trong bước này căn cứ vào tình hình cụ thể của
công việc để xác định các yêu cầu cần thực hiện trong chương trình,
trên cơ sở đó xác định các tệp dữ liệu của bài toán, qui trình và thuật
toán xử lý các thông tin ban đầu để có các thông tin kết quả.
Bước 2: Trên cơ sở xác định dữ liệu vào và ra của bài toán và qui trình
xử lý thông tin, ta xây dựng cơ sở dữ liệu thông qua việc thiết kế cấu
trúc các tệp
Bước 3: Xây dựng mô hình, thiết kế hệ thống. Trong bước này ta căn
cứ vào yêu cầu của bài toán ta xây dựng mô hình liên kết dữ liệu và
thuật toán xử lý các công việc từ đó xác định số lượng các Modun
chương trính trong từng nhóm Modun và sự liên kết giữa các Modun
trong quá trình xử lý.
Bước 4: Chọn ngôn ngữ để xây dựng chương trình. Để thực hiện xây
dựng chương trình cho các bài toán quản trị dữ liệu trên máy tính hiện
nay có rất nhiều ngôn ngữ quản trị dữ liệu (Như FOX, ACCESS,
ORACLE, LOTUS NOTE, SQL Server.....). Việc lựa chọn ngôn ngữ
lập trình phải căn cứ vào tình hình cụ thể của từng doanh nghiệp, từng
thời kỳ, từng cấu hình máy.
Bước 5: Chạy thử và hiệu chỉnh chương trình. Sau khi các Modun đã
hoàn tất và đã kết nối với nhau thành bộ chương trình, ta phải chạy thử
(TEST) trên số liệu giả định để thử tất cả các Modun khi đã thấy ổn thì
ta lại tiếp tục cho hạy thử trên số liệu thật của đơn vị trong một thời
gian có sự kiểm chứng song song với kết quả thực hiện bằng tay. Qua
quá trình chạy thử có các vướng mắc, sai sót ta chỉnh sửa lại chương
trình và dữ liệu để bộ chương trình hoàn chỉnh.
Bước 6: Tập huấn cho các cán bộ sử dụng bộ chương trình và bàn giao
bộ chương trình cho người sử dụng.
MODIFY STRUCTURE
eExpressionList
Specifies the expressions that can contain any combination of the following functions:
AVG(nExpression)
CNT( ) or COUNT( )
MAX(eExpression)
MIN(eExpression)
NPV(nExpression1, nExpression2 [, nExpression3])
STD(nExpression)
SUM(nExpression)
VAR(nExpression)
Functions in the expression list eExpressionList are separated by commas. These functions are specific to
CALCULATE and are described in detail later in this section. They should not be confused with similarly named
independent functions. For example, CALCULATE MIN( ) is not the same as MIN( ).
DO CASE
CASE lExpression1
[Commands]
[CASE lExpression2
[Commands]]
...
[CASE lExpressionN
[Commands]]
[OTHERWISE
[Commands]]
ENDCASE