Federation Server V9.5 版本的最突出的新特性之一 XML Federation 的使用方法。如果說 pureXML 是 DB2 UDB LUW V9 中的最大亮點,那麼也可以說 XML Federation 是 Federation Server V9.5 中的最大亮點。 DB2 UDB LUW pureXML 技術的誕生實現了數據庫對 XML 數據的原生支持,同時也帶來了對 XML 數據集成的需求。 XML Federation 正是因此應運而生。所謂 XML Federation 是指,利用昵稱 (Nickname),在 Federation Server 中將遠程 DB2 UDB 中的 XML 數據直接映射到本地數據庫中,從而使用戶可以利用 XQuery 和 SQL/XML 語句對其進行各種操作。本文將詳細描述 XML Federation 的概念,和怎麼利用它方便的定義對遠程 UDB 中的 pureXML 數據的映射和進行相關操作。
什麼是 XML Federation?
XML Federation,也可以叫做 Remote XML Data Type Support,是指利用昵稱 (Nickname),在 Federation Server 中將遠程 DB2 UDB 中的 XML 類型的數據直接映射到本地數據庫中,並使用戶可以利用與 DB2 一樣的 SQL, Xquery 和 SQL/XML 語句,對其進行各種操作。原理如圖 1 所示。
圖 1. XML Federation 工作原理
查看原圖(大圖)
如何定義對遠程 pureXML 的映射
如果您有一個 Federation Server V9.5 安裝和遠程 DB2 LUW 服務器 XML_HOST 。通過以下步驟可以定義對遠程 DB2 LUW 的 XML 數據的映射。打開一個 Federation Server 的命令行窗口,然後執行下面的步驟:
1. 打開 Federation 功能:
db2 update dbm cfg using federated yes;
db2stop
db2start
2. 創建本地的 Federation 數據庫:
db2 create db FED_DB using codeset UTF-8 territory US authentication clIEnt;
3. Catalog 遠程 XML 數據庫(在 Windows 上,可以通過 Control Center 實現):
catalog tcpip node XML_NODE remote XML_HOST server xfeduser;
catalog database XML_DB as CATALOG_XML_DB at node XML_NODE;
4. 連接到本地數據庫:
connect to FED_DB;
5. 創建 DRDA Wrapper,Server 和 User Mapping:
create wrapper drda OPTIONS(db2_fenced 'Y');
create server XML_SERVER type db2/cs version 9.5 wrapper drda authorization 'feduser'
passWord 'xxxxxx' options (node 'XML_NODE', dbname 'CATALOG_XML_DB');
create user mapping for feduser server XML_SERVER options ( REMOTE_AUTHID 'feduser',
REMOTE_PASSWord 'xxxxxx')
6. 假設遠程數據庫中已有由如下語句定義的表
create table rem_xml (intcol INT, strcol VARCHAR(128), xmlcol1 XML,
xmlcol2 XML, xmlcol3 XML)
我們可以對其建立下面的 Nickname
create nickname rem_xml_nick for XML_SERVER.feduser.rem_XML
我們可以通過下列的命令來查看 Nickname 的模式:
describe table rem_XML_nick Data type Column
Column name schema Data type name Length Scale Nulls
------------------------------- --------- ------------------- ---------- ----- ------
INTCOL SYSIBM INTEGER 4 0 Yes
STRCOL SYSIBM VARCHAR 128 0 Yes
XMLCOL1 SYSIBM XML 0 0 Yes
XMLCOL2 SYSIBM XML 0 0 Yes
XMLCOL3 SYSIBM XML 0 0 Yes
可以看到,遠程表的 XML 類型被直接映射成本地的 XML 類型。
當然,也可以對遠程的視圖建立 Nickname 。
如果我們有 3 個遠程服務器,XML_SERVER1, XML_SERVER2, XML_SERVER3, 有相似的表,那麼,我們都可以用同樣的方法把它們映射過來。
create nickname rem_xml_nick_S1 for XML_SERVER1.feduser.rem_XML
create nickname rem_xml_nick_S2 for XML_SERVER2.feduser.rem_XML
create nickname rem_xml_nick_S3 for XML_SERVER3.feduser.rem_XML
對已映射的 XML 數據的操作
將遠程的數據映射後,就可以像操作本地的數據一樣沒有限制的操作了。
1. 查詢操作。查詢所有遠程服務器中的 XML 數據,查出每個站點中符合條件的 XML 文檔:
SELECT xmlcol1 FROM rem_XML_nick_S1 WHERE intcol = 1 and strcol = ‘ S ’ ;
SELECT xmlcol1 FROM rem_XML_nick_S2 WHERE intcol = 1 and strcol = ‘ S ’ ;
SELECT xmlcol1 FROM rem_XML_nick_S3 WHERE intcol = 1 and strcol = ‘ S ’ ;
…
2. 插入操作。向遠程服務器中插入 XML 數據:
INSERT INTO rem_xml_nick_S1 (intcol, strcol, xmlcol1, xmlcol2, XMLcol3)
VALUES(1, 'S', '<a> <b>XML col1 </b><c> </c> </a>',
'<a> <b> XML col2 </b> <c> </c> </a>',
'<a><b> XML col3</b><c> </c> </a>');
可以將一個服務器的 XML 數據導入另一個:
INSERT INTO rem_xml_nick_S2 SELECT * FROM rem_XML_nick_S1
3 .更新操作。將某些 XML 文檔更新。
UPDATE rem_xml_nick_S1 SET xmlcol1 = XMLparse(document ‘ <a> new data <b> </b></a> ’ )
WHERE intcol = 1 and strcol = ‘ S ’ ;
4 .刪除操作。將某些文檔刪除。
DELETE FROM xmlmul_nick WHERE xmlexists( ‘ $x/a ’ passing XMLcol1 as “ x ” );
5. SQL/XML 查詢。可以使用諸如 XMLPARSE, XMLVALIDATE, XMLSERIALIZE, XMLQUERY 等 SQL/XML 函數 :
SELECT xmlquery('$x/a/c' passing xmlcol1 as "x") from rem_XML_nick_S1
where xmlexists('$x/a/b[value= ‘ XXX ’ ]' passing XMLcol1 as "x");
我們還可以將每個 Nickname 的查詢結果用 Union 操作生成統一的結果:
SELECT xmlquery('$x/a/c' passing xmlcol1 as "x") FROM rem_XML_nick_S1
WHERE xmlexists('$x/a/b[value= ‘ YYYY ’ ]' passing XMLcol1 as "x") UNION ALL
SELECT xmlquery('$x/a/c' passing xmlcol1 as "x") FROM rem_XML_nick_S2
WHERE xmlexists('$x/a/b[value= ‘ YYYY ’ ]' passing XMLcol1 as "x") UNION ALL
SELECT xmlquery('$x/a/c' passing xmlcol1 as "x") FROM rem_XML_nick_S3
WHERE xmlexists('$x/a/b[value= ‘ YYYY ’ ]' passing XMLcol1 as "x")
6 . XQuery 查詢。
for $proj in db2-fn:sqlquery('SELECT xmlcol1 FROM rem_XML_nick_S1 ')/Projects/Project
for $emp in db2-fn:sqlquery('SELECT xmlcol2 FROM rem_XML_nick_S3')//Employee
where $proj/@owner = $emp/@id
order by $proj/@id
return ($proj/Name, $emp/Name);
這裡我們把服務器 1 的數據和服務器 3 的數據在 XQuery 中“連接”起來。
在非 Unicode 環境中集成 XML 數據時對 Codepage 的處理方式
Federation Server V9.5 支持非 Unicode 的 pureXML 數據源。在非 Unicode 環境中,從遠程傳遞 XML 數據到本地,或從本地到遠程,可能需要對 Codepage 進行轉換。從遠程獲取的 XML 文檔,Federation 將調用 XML Parser,將其轉換成內部的表示形式,此時同時會將 Codepage 轉換為 Unicode 。假設遠程的數據庫的 Codepage 與 Federation 的不同 :
以 Character 方式傳遞的 XML 文檔將被轉換為 Federation 的 Codepage 。當文檔有 Internal Encoding(位於 XML Header 類似於 "<?xml version="1.0" encoding = "...encoding string">" 的字符串中)時,Federation 會將其直接清除。在隨後將文檔傳給 XML Parser 處理時,如果不是 Unicode,將被轉換為 Unicode 。
以 Binary 方式傳遞的 XML 文檔,Codepage 轉換只發生在將其傳給 XML Parser 時。如果文檔有 Internal Encoding, 且不是有效的 IBM Encoding 模式,Federation 會設法將它映射成有效的 IBM Encoding,如果不成功,就直接將其清除。
在缺省模式下,Federation 會以 Character 方式與遠程數據庫傳遞 XML 文檔。需要注意的是,Codepage 的轉換會占用額外的 CPU 周期,會使數據處理的性能下降,應盡量避免。
對 XML 數據的驗證
從遠程接收來的 XML,可以調用 XMLVALIDATE 進行驗證。此時如果直接調用 XMLVALIDATE, 驗證用的 Schema 將由 XML 文檔中的schemaLocation屬性確定。而由於 XML 文檔是從遠程服務器獲取的,所以這個 schemaLocation 可能在本地並不有效。這時需要在本地定義相應的 Schema,並在調用 XMLVALIDATE 時指定注冊的 Schema 或本地可訪問的 URI 用於驗證,以便覆蓋對 schemaLocation 的使用。定義和注冊 schema 的步驟可以參見文獻 3
集成 XML 文件
前面說明了怎樣集成遠程 DB2 LUW 數據庫中 XML 數據。對於非關系型數據源,如 XML 文件,可以用下面的方式定義 Nickname:
CREATE NICKNAME customers
(
doc VARCHAR(100) OPTIONS(DOCUMENT 'FILE'),
customer_info XML
) FOR SERVER XML_server
這樣就可以用下面的方式對 XML 文件進行查詢了:
SELECT XMLquery('$x/name ’ passing customer_info as "x") from customers
WHERE doc = ‘ /home/customer.XML ’
集成非關系數據源 XML 數據的具體的使用方法可以參見參考資源。
使用 XML Federation 時的限制
FederationV9.5 中,使用 XML Federation 功能時的限制包括,不能對 Nickname 中 XML 類型的 Column 進行 Alter 操作改變其本地的類型;不能對其定義 Federation Index ;不能定義以 XML 類型的 Column 為參數 Stored Procedure 或 Federated Stored Procedures 等。
小結
通過本文,讀者將理解怎麼樣通過 Federation Server V9.5 集成遠程 DB2 的 pureXML 數據,在充分利用 Federation Server 實時性,高效性和靈活性優勢的基礎上,方便的構建分布式的 XML 數據庫應用。