傳統關聯資料庫存儲 XML 需拆解為多表多欄,或塞入 CLOB/BLOB,導致查詢複雜、模式僵化。DB2 9 引入 pureXML:XML 文檔以解析後的階層結構直接存入 XML 欄位,支援 XQuery/XPath 原生查詢、XML 索引、存儲過程與視圖,大幅降低應用層解析負擔。
雙面板對比:左側使用 DB2 pureXML,右側使用無 XML 功能的關聯模式(模擬 MySQL)。同一用戶體驗,後端代碼量與複雜度截然不同。
| 項目 | DB2 pureXML | 傳統關聯模式 |
|---|---|---|
| 產品表 | xmlproduct (pid XML, doc XML) | sqlproduct (pid, name, details, brand, category, price, weight, size, description) + sqlimages 等多表 |
| 客戶表 | xmlcustomer (cid XML, doc XML) | 多欄位關聯表 |
| 訂單表 | xmlorder (oid XML, doc XML) | 訂單主表 + 明細表 + BLOB 存原始 XML |
pureXML 僅需三張表、各兩欄;傳統模式需四張表、數十欄位,維護成本指數級上升。
$conn = db2_connect($dbname, $user, $pass); if (!$conn) die(db2_conn_errormsg()); // 持久連線可用 db2_pconnect()
$stmt = db2_prepare($conn, "INSERT INTO xmlproduct VALUES (?, ?)");
$xml = file_get_contents("products/p1.xml");
$dom = simplexml_load_string($xml);
$pid = (string)$dom['pid'];
db2_execute($stmt, array($pid, $xml)); // 直接寫入 XML 文檔,無需 XMLPARSE
$dom = simplexml_load_string($xml);
$pid = (string)$dom['pid'];
$name = (string)$dom->description->name;
// ... 逐一提取 10+ 欄位 ...
foreach ($dom->description->images->image as $img) {
// 寫入 sqlimages 表
}
$stmt = db2_prepare($conn, "INSERT INTO sqlproduct (...) VALUES (?,?,...)");
db2_execute($stmt, array($pid, $name, ...));
CREATE VIEW Categories(Category) AS
SELECT DISTINCT(XMLCAST(
XMLQUERY('for $i in $t/product/description/category return $i'
PASSING BY REF T.DOC AS "t" RETURNING SEQUENCE)
AS VARCHAR(128)))
FROM xmlproduct AS T;
PHP 呼叫:$stmt = db2_exec($conn, "SELECT * FROM Categories");
| 維度 | DB2 pureXML | 傳統關聯 |
|---|---|---|
| XML Schema | 僅在新文檔中加入 <category catx="silverplated">,舊文檔自動相容 | 需 ALTER TABLE 新增欄位,並回填歷史資料 |
| 關聯模式 | 完全無變更 | 修改表結構,可能需鎖表、重建索引 |
| 查詢語句 | 視圖 XQuery 加入條件,應用層 PHP 零修改 | 所有 INSERT/SELECT 需同步新增欄位參數 |
| 應用代碼 | 無變更 | 需新增 DOM 解析邏輯、修改 SQL、重跑資料遷移 |
$xquery = '
for $i in $t/product
let $thumb := $i/description/images/image[@type="thumbnail"]
where $i/description/category = "' . htmlentities($category) . '"
return
<div class="item">
<img src="{$thumb}" />
<h3>{$i/description/name}</h3>
<p>{$i/description/details}</p>
</div>';
$stmt = db2_prepare($conn, "SELECT XMLQUERY('$xquery' PASSING BY REF doc AS \"t\" RETURNING SEQUENCE) FROM xmlproduct");
db2_execute($stmt);
// 直接 echo 結果,中間層零模板邏輯
DB2 pureXML 讓 XML 成為一等公民: