Lập trình với XML cho DB2, Phần 2: Phát huy sự hỗ trợ của cơ sở dữ liệu
cho XML trong kiến trúc ứng dụng của bạn
Hardeep Singh, Kiến trúc sư các công nghệ nâng cao, IBM
Tóm tắt: Hãy tìm hiểu cách môi trường lưu trữ và truy vấn XML mới của DB2®
phiên bản 9 cho các hệ điều hành Linux®, UNIX® và Windows® làm việc trong
mô hình dữ liệu XML được mô tả trong Phần 1 của loạt bài này. Phần 2 tập trung
vào cách làm thế nào để khai thác sự hỗ trợ đã cải tiến của cơ sở dữ liệu cho XML
trong kiến trúc ứng dụng của bạn.
Giới thiệu
Vị thế của XML trong cơ sở dữ liệu đã thay đổi trong vài năm qua, từ một công
nhân tạm thời thành một công dân hạng nhất. Nó không còn phải biến hình nhân
dạng để phù hợp với thế giới dữ liệu quan hệ. Nó duy trì các di sản phân cấp của
nó một cách tự hào, ngay cả khi khai thác sức mạnh và sự ổn định của thế giới cơ
sở dữ liệu quan hệ. Thực vậy, một số láng giềng cơ sở dữ liệu quan hệ của nó phải
có các kỹ thuật thích nghi, làm cho mình giống với XML để khai thác sự phong
phú của mô hình XML phân cấp.
Bài viết này giới thiệu cách môi trường lưu trữ và truy vấn XML mới làm việc
trong mô hình dữ liệu XML từ phần 1. Nó cho thấy rằng một khi bạn thích ứng
với kiến trúc phát triển ứng dụng dựa trên XML mới, thì các lược đồ cơ sở dữ liệu
của bạn trở nên đơn giản hơn nhiều và tự nhiên hơn như thế nào. Nó cũng cho thấy
cách truy vấn dữ liệu XML trong cơ sở dữ liệu không khác với cách truy vấn dữ
liệu trong ứng dụng. Cuối cùng, nó cho bạn thấy cách kết hợp các dữ liệu quan hệ
với các dữ liệu XML để có được những điểm tốt nhất của cả hai thế giới đó. Các khái niệm cơ bản về cơ sở dữ liệu XML
Mặc dù hầu hết các cơ sở dữ liệu quan hệ chính đều có một số hỗ trợ cho XML,
nhưng sự hỗ trợ của pureXML DB2 cho XML là mạnh mẽ và hiệu quả hơn nhiều,
làm cho nó trở thành một cơ sở dữ liệu lý tưởng để thử nghiệm mô hình lập trình
XML. Trong bài này tôi tập trung vào cách để khai thác sự hỗ trợ đã cải tiến này
của cơ sở dữ liệu cho XML trong kiến trúc ứng dụng của bạn.
ENFORCED ENABLE QUERY OPTIMIZATION )
Từ các mệnh đề trên, rõ ràng rằng bằng cách lưu trữ một đối tượng dữ liệu của
ứng dụng dưới dạng XML, thì các lược đồ quan hệ đơn giản hóa rất nhiều. Hơn
nữa, việc cơ sở hạ tầng vẫn là quan hệ cho phép các dữ liệu XML sử dụng được
các khả năng đã được minh chứng của các cơ sở dữ liệu quan hệ, ví dụ như các
triggers, các ràng buộc và các mối quan hệ khóa ngoài.
Vì rằng về mặt lôgic thì cột XML tỏ ra giống như cột VARCHAR, CLOB, hoặc
BLOB, nên các câu lệnh INSERT cũng tương tự.
insert into CUSTOMER_TABLE values('hardeep',
'<Customer customerid="hardeep" firstname="hardeep" lastname="singh"/>')
Hoặc nếu bạn chèn vào từ một chương trình Java:
Liệt kê 2. Chèn vào từ một chương trình Java
String insertsql= "insert into PURCHASE_TABLE values(?,?)";
PreparedStatement iStmt=connection.prepareStatement(insertsql);
File inputfile= new File(filename); //filename is the path of the XML file
long filesize=inputfile.length();
BufferedReader in = new BufferedReader(new FileReader(inputfile));
iStmt.setCharacterStream(1,in,(int)filesize);
int rc= iStmt.executeUpdate();
Để hiểu rõ hơn về lưu trữ lai, bạn hãy nhìn vào khung nhìn về cách dữ liệu XML
dường như về lôgic được lưu giữ như thế nào trong cơ sở dữ liệu quan hệ.
Ghi chú: Ngay cả khi công nghệ lưu trữ vật lý cho XML có thể khác nhau với
từng nhà cung cấp cơ sở dữ liệu quan hệ khác nhau, thì khung nhìn lôgic là như
nhau.
Hình 2. Khung nhìn lôgic lưu trữ lai của DB2
"cust" )
Hoặc nếu bạn đã thực hiện cuộc gọi này từ một chương trình Java bằng cách sử
dụng truy vấn có tham số (parametrised):
select CUSTXML from CUSTOMER_TABLE
where xmlexists ('$cust/Customer[@lastname= $lname ]'
passing CUSTXML AS "cust" , cast(? as VARCHAR(12)) as "lname")
Một khi bạn bỏ qua cú pháp kỳ cục của việc chuyển tham số cho các hàm
SQL/XML, bạn sẽ thấy rằng đối với các truy vấn lai cơ bản trên dữ liệu quan hệ và
XML, thì truy vấn XML chủ yếu là chứa các câu lệnh XPath. Điều này khá giống
với những gì bạn đã làm ở tầng ứng dụng (trong Phần 1) đối với mô hình dữ liệu
XML, ở đây phần lớn mã của bạn đã thực hiện các cuộc gọi XPath đến lớp bao gói
(wrapper) mô hình đối tượng tài liệu (DOM) để truy vấn và thao tác dữ liệu XML.
Lưu ý: Trong Viper phiên bản 2, một số đơn giản hóa đã được thực hiện liên quan
đến chuyển tham số cho một số hàm SQL/XML. Ví dụ: Trong truy vấn trước,
mệnh đề chuyển tham số XMLExists không phải chỉ rõ cột CUSTXML.
select CUSTXML from CUSTOMER_TABLE
where xmlexists ('$CUSTXML/Customer[@lastname= $lname ]'
passing cast(? as VARCHAR(12)) as "lname")
Đẩy logic ứng dụng sang cơ sở dữ liệu
XQuery có tất cả các chức năng thô sơ của hầu hết các ngôn ngữ bậc cao (các câu
lệnh if-then-else, for, các biến, các hàm và các toán tử số học). Điều này làm cho
có thể nhúng logic nghiệp vụ bên trong truy vấn. Thêm nữa, nó có rất nhiều chức
năng chung ánh xạ đến XSLT làm cho có thể không chỉ truy vấn mà còn biến đổi
đầu ra XML ngay trong cơ sở dữ liệu.
Hãy lấy ví dụ Customer cho mô hình dữ liệu XML từ phần 1.
}</Customer>
' passing cast( ? AS varchar(255) ) as "customerid" ))
Kết quả XML cho tất cả các mục mà khách hàng hardeep đã mua sẽ là:
Hình 4. Kết quả truy vấn
Trong truy vấn trên, bạn đã phải xây dựng phần tử Customer bên ngoài và thêm
các thuộc tính từ dữ liệu cột CUSTXML. Viper 2 (phiên bản beta) của DB2 có sự
hỗ trợ cho biểu thức cập nhật XQuery cho phép sửa đổi các tài liệu XML, như vậy
không cần phải xây dựng phần tử Customer bên ngoài nữa. Thay vào đó, bạn có
thể sử dụng chính phần tử này trong bảng khách hàng và chèn các mục từ bảng
mua hàng như là các phần tử con.
Liệt kê 4. Truy vấn Viper 2 đối với hai cột XML
values(xmlquery('
for $Customer in db2-fn:xmlcolumn(
"CUSTOMER_TABLE.CUSTXML")/Customer
let $items:=(<Items>{
for $Customer0 in db2-fn:xmlcolumn("PURCHASE_TABLE.ITEMXML")/Customer
where $Customer0/@customerid= $Customer/@customerid
return $Customer0/Item
}</Items>)
DYNAMIC RESULT SETS 1
LANGUAGE SQL
BEGIN
DECLARE c_cur CURSOR WITH RETURN FOR
values(xmlquery('
for $Customer in db2-fn:xmlcolumn(
"CUSTOMER_TABLE.CUSTXML")/Customer
let $items:=(<Items>{
for $Customer0 in db2-fn:xmlcolumn("PURCHASE_TABLE.ITEMXML")/Customer
where $Customer0/@customerid= $Customer/@customerid
return $Customer0/Item
}</Items>)
where $Customer/@customerid= $customerid
return
transform
copy $cust:=$Customer
modify(
do insert $items as last into $cust)
return $cust
' passing custid as "customerid" ))
OPEN c_cur;
DYNAMIC RESULT SETS 1
LANGUAGE SQL
BEGIN
DECLARE c_cur CURSOR WITH RETURN FOR
values(xmlquery('
for $Customer in db2-fn:xmlcolumn(
"CUSTOMER_TABLE.CUSTXML")/Customer
let $items:=(
<Items>{
for $Customer0 in db2-fn:xmlcolumn("PURCHASE_TABLE.ITEMXML")/Customerlet $insurance:=<insurance currency="{($rate//rate[@price=""]/@currency)}">
{(
if($Customer0/Item/@price > 500) then (
$Customer0/Item/@price * $rate//rate[@price=""]/@rate
)
else (
if($Customer0/Item/@price > 100) then (
$Customer0/Item/@price * $rate//rate[@price="500"]/@rate
)
else (
$Customer0/Item/@price * $rate//rate[@price="100"]/@rate
)
)
ở định dạng XML, thì sức mạnh của XQuery có thể được sử dụng để thực hiện
nhiều logic nghiệp vụ hơn so với trước đây khi chỉ sử dụng một mình SQL. Ngoài
ra, rõ ràng rằng XML đang được sử dụng trong truy vấn thậm chí không cần phải
tồn tại trong cơ sở dữ liệu. Vì vậy, dữ liệu XML tham gia vào một truy vấn
SQL/XML có thể được lưu trữ hoặc trong cơ sở dữ liệu dưới dạng thuần (phân
cấp) của nó, nó có thể được tạo ra bằng cách sử dụng hàm SQL/XML, hoặc thậm
chí có thể được chuyển như một tham số thời gian chạy đến truy vấn. Sự khác biệt
giữa cơ sở dữ liệu và một máy chủ ứng dụng đang dần bị mờ đi. Ưu điểm và khuyết điểm
Giống như mọi công nghệ mới, sẽ có vấn đề liên quan đến sự phát triển. Một số là
do thực tế rằng quá trình triển khai thực hiện đang ở trong giai đoạn phiên bản đầu
tiên, một số vấn đề khác là do sức ỳ phải thay đổi một phương pháp luận đúng và
đã được thử thách mà bạn đã quen với chúng.
1. Việc cải thiện hiệu suất thông lượng còn chưa ngang bằng với các dữ liệu
quan hệ.
2. XQuery là một ngôn ngữ mới và một số hàm SQL/XML có những cú pháp
cần phải làm quen với chúng.
3. Có rất nhiều dữ liệu di sản đã ở định dạng quan hệ.
4. Điều quan trọng nhất là đây là một cách mới để tạo ra các ứng dụng nghiệp
vụ và các lược đồ dữ liệu, khác với cách thức hiện tại của các ứng dụng
hướng đối tượng và các lược đồ quan hệ được chuẩn hóa.
5. Không có nhiều công cụ có thể gỡ lỗi và tối ưu hóa các loại truy vấn để có
hiệu suất tốt hơn.
Đối lập với các nhược điểm này là sự thực rằng mô hình mới tự nhiên hơn trong
cách nó quản lý dữ liệu. Các thông tin về dữ liệu nghiệp vụ được duy trì và được
thao tác nguyên vẹn ở cả tầng ứng dụng và lẫn tầng cơ sở dữ liệu, thậm chí ở cả
tầng khách, như bạn sẽ thấy trong phần 3.
Mặc dù các ngôn ngữ bao ngoài có thể khác nhau (Java, XQuery,
XQuery. Liệt kê 7. Chuyển biến thời gian chạy tới cho SQL nhúng trong
XQuery
values(xmlquery('
for $Customer0 in db2-fn:xmlcolumn("PURCHASE_TABLE.ITEMXML")/Customer
where $Customer0/@customerid= $custid
return (
$Customer0/Item,
db2-fn:sqlquery(
''select xmlrow(details, description, weight option ROW "description")
from sqlproduct where pid= parameter(1)'', $Customer0/Item/@ID))
' passing cast( ? AS varchar(255) ) as "custid" ))
Vì vậy, ngay cả khi một số dữ liệu ở trong các bảng quan hệ và một số dữ
liệu khác ở trong XML, bây giờ bạn vẫn có thể thực hiện phép nối động
giữa dữ liệu XML và dữ liệu quan hệ từ bên trong hoặc là truy vấn SQL
hoặc là XQuery hoặc cả hai.
Thậm chí hiệu suất cũng không phải là một vấn đề lớn trong một số trường
hợp vì:
o Bạn có thể tạo các chỉ mục dựa trên biểu thức XPath trên các tài liệu
XML được lưu trữ trong cơ sở dữ liệu.
o
create index custfname on customer_table(info) generate key
using xmlpattern '/Customer/@firstname' as sql varchar(64)