Thuật toán lồng tận dụng các đặc tính phân cấp và các toán tử *. + của XML nhằm khắc phục những hạn chế của chuyển đổi phẳng. Thuật toán này sử dụng toán tử lồng (nest) để đưa ra mô hình nội dung phần tử tốt nhất có sử
Giả sử, cho một bảng t với một tập các cột C, lồng trên cột X C, X không rỗng, nghĩa là chọn tất cả các bộ thoả mãn các cột C - X đưa vào một tập hợp. Một cách hình thức, điều này được định nghĩa như sau:
Định nghĩa 2.8 (Nest)
Cho một bảng t kích cỡ n với tập hợp các cột C, X C và X= X - X. Với mỗi (n-1) - bộ
x
(t), chúng ta định nghĩa n bộ * như sau:
* * X X {k X k t k X } thì nestx(t) = { * X(t)}
Sau khi nestx(t), nếu cột X thu được chỉ có một tập giá trị "đơn" {v} trong tất cả các bộ thì ta kết luận lồng (nest) thất bại và xem {v} tương đương với v ({v} = v), khi đó nestx(t) = t, ngược lại, nếu cột X là một tập đa trị {v1, v2,….vk}với k 2 thì ta nói lồng thành công.
Ví dụ 2.13: Xét bảng R của hình 2.12, giả sử cột A, B và C không rỗng. Tính nestAR tại hình (b), ta thấy các giá trị ở cột (B, C) của bộ đầu tiên, bộ thứ 3 và bộ thứ 4 trong R là giống nhau (a, 10), cũng trên các bộ đó thì giá trị của cột A là khác nhau. Ta sẽ nhóm các giá trị khác nhau này thành một tập hợp {1,2,3}. Kết quả của nestA® là {1,2,3}, a,10). Tương tự đối với bộ thứ 6 của R, thứ 7 có giá trị là (b, 20) nên ta nhóm thành một tập {4, 5}. Tiếp tục tính nestB (R) = R tại hình (c) vì không có bộ nào giống nhau trong các cột (A, C); nestC R = (1, a, {10,20}),….
Hình 2.12: Các dạng lồng của bảng quan hệ R
Ý tưởng của toán tử lồng như sau: Nếu lồng trên cột X thành công thì cột X sẽ không phẳng để nó có thể chứa các sự kiện đa trị đúng với mô hình thực tế. Khi đó chúng ta sử dụng mô hình nội dung phần tử * (nếu X có thể rỗng) hoặc + (nếu X không rỗng).
Ta nhận thấy rằng, toán tử lồng yêu cầu phải duyệt qua tất cả các bộ trong bảng, thao tác này khá vất vả và tốn nhiều chi phí. Hơn nữa, có nhiều cách lồng trên cùng một bảng. Vì vậy vấn đề quan trọng là phải tìm ra cách nào hiệu quả nhất (chẳng hạn sử dụng toán tử lồng trong thời gian trong thời gian ngắn nhất) để có đựơc mô hình nội dung phần tửu có số lồng ít nhất.
Bổ đề 2.3: Nếu thực hiện toán tử lồng trên cột X mà không khoá tham gia thì kết quả không thay đổi.
Chứng minh: Xét bảng t có các cột C, nếu cột X không phải là một
Z là duy nhất (vì Z là khoá) thì các giá trị nằm trong tập con của Z, , cũng phải
duy nhất (Z là khoá dự tuyển trong khi X là siêu khoá). Vì vây, kết quả lồng trên X sẽ không có gì khác nhau so với bảng trước khi lồng (đpcm).
Hệ quả 2.1: Với bất kỳ một bảng lồng nestx(t) nào đều có được
X X
Hệ quả cho rằng sau khi áp dụng toán tửu nest trên cột X, thì các cột X
còn lại sẽ trở thành siêu khoá. P. C. Fischer đã chứng minh rằng các phụ thuộc hàm sẽ được bảo toàn dựa trên việc lồng (nesting) như sau:
Bổ đề 2.4: Nếu X, Y, Z là các cột của t thì:
t : X Y nestZ(t) : X Y
Áp dụng bổ đề 2.3 và 2.4 cho bổ đề 2.5
Bổ đề 2.5: Sử dụng khái niệm giai thừa thiếu ký hiệu là xm , cho một bảng t có n cột, trong đó có m cột là khoá (m n), T là số lần cần thiết phải lồng là: T = m k
K 1 m
Chứng minh: Giả thuyết C n và K m cột khoá (K C). Theo định nghĩa khoá thì t: K K. Theo bổ đề 2.3, chúng ta chỉ lồng m cột trong K. Giả sử chúng ta chọn cột X K là cột đầu tiên đề lồng. Sau khi lồng, áp dụng bổ đề 2.4 và hệ quả 2.1 ta có một trong m cách để lồng và:
x
Nest (t) : KK,XX
Tiếp tục lồng cột thứ hai, ta cần phải chọn một cột khoá Y thuộc vế trái
của các hai ràng buộc trên. Nghĩa là Y K X K X. Do K có m cột nên K - X có m - 1 cột. Vì vậy, khi chọn cột thứ hai ta có m(m - 1) lần lồng. Tiếp tục như thế, chúng ta có:
m + m(m - 1) +…+ m (m - 1) …= m k
K 1 m
(đpcm)
Bổ đề 2.5 dựa trên thông tin về khoá dự tuyển nên ta có thể tránh được những phép lồng không cần thiết. Chẳng hạn, giả sử thuộc tính A và C trong hình 2.12 là khoá R. B không tham gia vào khoá nên ta không cần thực hiện phép lồng trên B, do đó nestB® là không cần thiết. Hơn nữa, theo bổ đề 2.4
phụ thuộc bao hàm (AC key R ACACACB) bảo toàn sau khi lồng trên cột A hoặc C. Ta chỉ cần thực hiện phép lồng cần thiết như sau: nestAR tại (b), nestC(R) tại (d) và nestA(nestC (R)) tại (e) hoặc nestC(nestA(R)) tại (f).
Do đó, nếu chúng ta có được thông tin khoá thì chi phí để thực hiện phép toán lồng là nhỏ nhất. Tuy nhiên, nếu không có thông tin về khoá hoặc các bảng trung gian được sinh ra từ các câu truy vấn thì phép toán lồng phải được áp dụng trên tất cả các tổ hợp có thể.
Sau khi áp dụng toán tử lồng, nhiều bảng lồng thành công được giữ lại. Thông thường sẽ chọn ra lược đồ cuối cùng để xem xét về ngữ nghĩa và dùng làm lược đồ kết quả vì sự dư thừa dữ liệu trên lược đồ này là thấp nhất. thủ tục tổng quát cho thuật toán NeT như sau:
1) For mỗi bảng ti trong lược đồ quan hệ R sẽ được chuyển thành một
phần tử ei trong DTD: E = i ei .
2) Chọn một bảng lồng cuối tốt nhất có dạng ti (c1,…ck-1, ck,…, cn), trong đó lồng thành công trên các cột (c1,…ck-1).
(a) If k = 1 (lồng không thành công) then chuyển đổi phẳng.
(b) If k > 1,
(i) For mỗi cột ci (1 i k - 1), nếu ci là null trong R thì mô hình nội dung là M(ei) = (ci*,…), ngược lại là M(ei) = (ci,…).
(ii) For mỗi cột ci (k j n)
- (mô hình hướng phần tử) Nếu ci là null trong R thì mô hình nội dung là M(ei) = (…,cj?), ngược lại là M(ei) = (…,cj).
- (mô hình hướng thuộc tính) Nếu cj được chuyển sang aj, th ì A(ei) =
U j {aj}. Nếu cj là null trong R thì P(aj) = (S, nullable, d, f), ngược lại P(aj) = (S, not - nulllable, d, f).
3) Tất cả các phần tử ei trong DTD trở thành gốc t = Ul {ei}; sao chép
trong R và trong DTD.