本文解释如何使用 DB2® pureXML™ 创建不区分大小写的数据库以及让 XML 查询和 XML 索引发挥预期的作用。

依据界说,XML 元素和特点的值是区别大小写的。例如,假如查找值为 “Paris” 的 元素,那么不会找到 “PARIS” 或 “paris”。能够运用 fn:upper-case() 等 XQuery 函数处理这个问题,可是运用这些函数时不能运用 XML 索引,所以功能或许欠好。本文解说怎么运用 DB2® pureXML™ 创立不区别大小写的数据库以及让 XML 查询和 XML 索引发挥预期的作用。用大写和小写函数履行不区别大小写的查找

下面的示例帮助您更清楚地了解不区别大小写的查找。清单 1 界说一个包括一个 INTEGER 列和一个 XML 列的表,并在表中刺进 7 行。每行包括一个小的客户文档,其间包括 XML 元素 。

此元素中的值在大小写方面并不共同。一些值是全大写的,一些是全小写的,其他是大小写混合的(首字母大写)。假如数据来自不同的应用程序,而这些应用程序选用不同的大小写数据输入规矩,就会呈现这种状况。

清单 1. 示例表和数据

CREATE TABLE customer (id INTEGER, xmldoc XML);

INSERT INTO customer (id, xmldoc)
VALUES (1,'<Customer id="1"><city>PARIS</city></Customer>'),
       (2,'<Customer id="2"><city>Tokyo</city></Customer>'),
       (3,'<Customer id="3"><city>tokyo</city></Customer>'),
       (4,'<Customer id="4"><city>PARIS</city></Customer>'),
       (5,'<Customer id="5"><city>paris</city></Customer>'),
       (6,'<Customer id="6"><city>Delhi</city></Customer>'),
       (7,'<Customer id="7"><city>Paris</city></Customer>'); 

假如一个应用程序查询这些 XML 文档,寻觅某一城市的客户,那么很或许需求不区别大小写的查找。例如,或许期望找到 Paris 的一切客户,也便是期望获取第 1、4、5 和 7 行。可是,假如查找值 “Paris”,那么只会回来第 7 行。要想获取所需的一切四行,能够运用 XQuery 函数 fn:upper-case() 把 city 元素值转换为大写并与 “PARIS” 做比较。清单 2 中的查询就选用这种办法,它会回来 Paris 的一切四个客户。

清单 2. 挑选 Paris 的客户


SELECT id, XMLCAST( XMLQUERY('$XMLDOC/Customer/city') AS VARCHAR(15)) AS city
FROM customer
WHERE XMLEXISTS('$XMLDOC/Customer[fn:upper-case(city) = "PARIS"]');

假如查询经过一个参数标志供给查找值,那么这个参数也应该转换为大写,见 清单 3。这个参数标志(“?”)的类型为 VARCHAR(15) 并作为变量 “c” 传递给 XQuery 谓词。

清单 3. 运用参数标志挑选客户


SELECT id, XMLCAST( XMLQUERY('$XMLDOC/Customer/city') AS VARCHAR(15)) AS city
FROM customer
WHERE XMLEXISTS('$XMLDOC/Customer[fn:upper-case(city) = fn:upper-case($c)]'
PASSING CAST(? AS VARCHAR(15)) AS "c");


图 1 显现以上示例查询的输出。

用DB2 pureXML履行不区别大小写的高效查找  pureXML 大小写 DB2 IBM 第1张

图 1. 示例查询的成果

假如只查询少数数据,或许查询还包括其他挑选性谓词,使得大写谓词只应用于很小的中心成果集,那么这种办法作用还不错。问题是假如运用包括 fn:upper-case() 函数的谓词,就不会运用 DB2 中的 XML 索引。因而,这种办法不适用于很多数据。

要想防止运用 fn:upper-case() 函数并运用 XML 索引加速查询,就需求创立不区别大小写的数据库。

创立不区别大小写的 DB2 数据库

DB2 从 Version 9.5 Fixpack 1 开端支撑感知区域的 Unicode 排序规矩。这使咱们能够疏忽大小写和/或重音符号。要想创立关于一切字符串比较不区别大小写的数据库,需求运用排序规矩 UCA500R1,见 清单 4。

清单 4. 创立不区别大小写的数据库


CREATE DATABASE testdb
USING CODESET UTF-8 TERRITORY US
COLLATE USING UCA500R1_LEN_S2;

字符串 UCA500R1_LEN_S2 终究意味着什么?UCA500R1 指定此数据库运用根据 Unicode 5.0.0 规范的默许 Unicode Collation Algorithm(UCA)。因为默许的 UCA 不能一起掩盖 Unicode 支撑的每种言语的排序规矩序列,所以能够运用可选特点定制字符的次第。特点以下划线(_)分隔。UCA500R1 关键字加上一切特点构成一个 UCA 排序规矩名。

清单 4 中运用的排序规矩名包括两个特点:LEN 和 S2。LEN 是 L(言语)和 EN(英语的 ISO 639-1 言语编码)的组合。第二个特点 S2 指定强度等级,这决定在字符串排序或比较时是否考虑大小写或重音符号。在 清单 4 中运用强度等级 2,所以 “PARIS” 和 “paris” 是持平的。下面是其他有效值的示例:

UCA500R1_LEN_S1 导致 "cliche" = "Cliche" = "cliché"

UCA500R1_LEN_S2 导致 "cliche" = "Cliche"

UCA500R1_LEN_S3 导致 "cliche"

在 DB2 Information Center 中能够找到能够作为 UCA 排序规矩名的一切组合(拜见 参考资料)。

在不区别大小写的数据库中查询 XML 数据

因为此数据库运用排序规矩名 UCA500R1 和强度等级 2,所以现在能够简化前面的查询,去掉 fn:upper-case() 函数(清单 5),就像一切数据都是大写的相同。不管查找字符串是 “Paris” 或 “PARIS” 仍是其他任何大小写组合,成果都是相同的。

清单 5. 挑选 Paris 的客户


SELECT id, XMLCAST( XMLQUERY('$XMLDOC/Customer/city') AS VARCHAR(15)) AS city
FROM customer
WHERE XMLEXISTS('$XMLDOC/Customer[city = "PARIS"]');


图 2. 示例查询的成果

用DB2 pureXML履行不区别大小写的高效查找  pureXML 大小写 DB2 IBM 第2张

假如经过添加 ORDER BY 子句按提取的 city 值排序,那么成果集仍然是相同的:PARIS、paris 和 Paris 被当作相同的值。

为了高效地查询此数据,尤其是在表中行数很大的状况下,应该用 XPath /Customer/city 创立一个 XML 索引,见 清单 6:

清单 6. 创立 XML 索引

 
CREATE INDEX customer_lang_idx ON test (xmldoc)
GENERATE KEY USING XMLPATTERN '/Customer/city' AS SQL VARCHAR(15);

现在,假如用 Visual Explain 或 DB2exfmt 解说此查询,就会看到这个不区别大小写的查找运用了索引:

用DB2 pureXML履行不区别大小写的高效查找  pureXML 大小写 DB2 IBM 第3张

图 3. 在不区别大小写的数据库中查询 Paris 的一切客户的 Explain Plan

本节介绍的办法有一个潜在的缺陷:整个数据库中一切表中的一切列中的一切数据都是不区别大小写的。不或许以区别大小写的办法处理特定的表或列。要么都区别大小写,要么都不区别。

留意,不区别大小写只应用于元素和特点值,而不该用于符号名自身。XML 符号和途径表达式仍然是区别大小写的。例如,XPath 表达式 /Customer/city(小写 “c”)和 /Customer/City(大写 “C”)是不同的。后者不匹配示例数据中的任何元素,因为示例数据中的 元素名是小写的。

功能

在数据库中运用定制的排序规矩或许影响查询功能,因为在挑选更宽松的 UCA 设置时,匹配的字符串数量或许会添加。换句话说,在不区别大小写的数据库中,字符串比较的开支或许会稍微添加。为了查明区别大小写的和不区别大小写的数据库之间的功能差异,咱们创立了一个惯例数据库(区别大小写)和一个不区别大小写的数据库。然后,刺进来自 TPoX 基准测验的 20,000 个 CustAcc 文档并在这两个数据库中对各种查询进行测验。

关于只触及少数到中等数量的行的查询,两个测验数据库之间的功能差异能够疏忽不计。咱们发现触及很多行的查询的功能差异比较大,比方对一切 20,000 个 XML 文档进行全表扫描并对每个文档比较字符串。在不区别大小写的数据库中,这种查询花费的时刻添加了 5% 到 8%。因而,完成不区别大小写的查找需求支付的价值并不大。

结束语

以不区别大小写的办法查找 DB 2 数据有多种办法,比方运用生成的列(请拜见 参考资料)。虽然这些办法都合适联系数据,可是不合适查询 XML 数据。以不区别大小写的办法处理 XML 数据的最佳办法是用定制的 Unicode 排序规矩创立数据库。这使数据库中的一切字符串值比较都选用不区别大小写的办法,防止阻碍运用 XML 索引和联系索引。因为不区别大小写或重音符号,会添加匹配的字符串,可是添加的开支十分低。

【修改引荐】

  1. Oracle数据库中段办理的四个技巧
  2. 最简略删去SQL Server中一切数据的办法
  3. DB 2数据库功能优化技巧详解
转载请说明出处
知优网 » 用DB2 pureXML履行不区别大小写的高效查找

发表评论

您需要后才能发表评论