MicrosoftSQLServer2005的XML最佳实施策略.doc_第1页
MicrosoftSQLServer2005的XML最佳实施策略.doc_第2页
MicrosoftSQLServer2005的XML最佳实施策略.doc_第3页
MicrosoftSQLServer2005的XML最佳实施策略.doc_第4页
MicrosoftSQLServer2005的XML最佳实施策略.doc_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Microsoft SQL Server 2005 的 XML 最佳实施策略发布日期: 7/5/2004 | 更新日期: 7/5/2004作者: Shankar Pal、Vishesh Parikh、Vasili Zolotov、Leo Giakoumakis、Michael Rys Microsoft Corporation适用于:Microsoft SQL Server摘要:了解 SQL Server 2005 中的 XML 数据建模和使用准则,并观察一些说明性的示例。目录简介5数据建模5关系或 XML 数据模型5在 SQL Server 2005 中存储 XML 数据的理由6XML 存储选项6XML 技术的选择7原生 XML 存储7示例:使用 XML 数据类型对 XML 数据进行建模8示例:保留 XML 数据的精确副本8XML 视图技术8示例:使用带有批注的 XML 架构 (AXSD) 对数据进行建模9混合模型9使用 XML 数据类型进行数据建模9相同或不同的表9XML 数据的粒度10非类型化、类型化和受约束的 XML 数据类型10文档类型定义 (DTD)11将 XML 数据类型列编入索引11主 XML 索引11示例:创建主 XML 索引11辅助 XML 索引12示例:基于路径的查找12示例:获取对象的属性13示例:基于值的查询13XML 列上的全文索引13示例:将全文搜索与 XML 查询结合起来13示例:使用单词衍生对 XML 值进行全文搜索14属性提升14基于 XML 数据类型的计算列14示例:基于 XML 数据类型方法的计算列15示例:基于 XML 数据类型方法的计算列上的查询15创建属性表15示例:创建属性表16示例:创建用户定义的函数以便从 XML 实例生成行集16示例:创建触发器以填充属性表16示例:查找作者的名字为David的 XML 实例18示例:使用 CLR 流式表值函数的解决方案18XML 架构集合20多类型化列20架构演变21用法21加载 XML 数据21将 XML 数据从 SQL Server 2000 传输到 SQL Server 200521示例:将列类型更改为 XML21批量加载 XML 数据22示例:从文件中加载 XML22文本编码22示例:显式指定编码22Xquery 与类型推理23错误模型23唯一性检查23示例:已知的唯一性23示例:value() 的用法24父轴24Data()、Text() 和 String() 访问器24联合类型的函数和运算符25示例:联合类型上的函数25示例:联合类型上的运算符25Value()、Nodes() 和 OpenXML()25示例:nodes() 的用法25示例:对 XML 数据类型使用 OpenXml()26使用 FOR XML 从行集中生成 XML27示例:返回生成的 XML 数据类型的 SQL 视图27添加业务逻辑27示例:应用 XSL 转换28跨域查询29示例:使用 sql:variable() 的跨域查询29用于原生 XML 支持的目录视图29XML 索引29示例:XML 索引的空间利用率30检索 XML 架构集合30示例:枚举 XML 架构集合中的 XML 命名空间30示例:枚举 XML 架构集合的内容31示例:输出 XML 架构集合中的指定架构31查询 XML 架构31简介Microsoft SQL Server 2005 为 XML 数据处理提供了广泛的支持。XML 值可以自然地存储在 XML 数据类型列中,而后者可以根据 XML 架构集合进行类型化,或者保持非类型化。可以将 XML 列编入索引。而且,使用 XQuery 和 XML DML(为进行数据修改而进行的扩展)可以支持细粒度的数据操作。SQL Server 2000 和 SQLXML Web Release 提供了强大的 XML 数据管理功能。这些功能致力于关系数据和 XML 数据之间的映射。可以使用带有批注的 XSD (AXSD) 来定义关系数据的 XML 视图,以便提供以 XML 为中心的方法,该方法支持 XML 数据的批量数据加载、查询和更新功能。Transact-SQL 扩展提供了以 SQL 为中心的方法,以便将关系查询结果映射到 XML(使用 FOR XML),以及从 XML 生成关系视图(使用 OpenXML)。这些支持已在 SQL Server 2005 中得到了扩展。结合新增的原生 XML 支持,SQL Server 2005 提供了一种强大的平台,以便针对半结构化和非结构化的数据管理开发功能丰富的应用程序。本文提供了 SQL Server 2005 中的 XML 数据建模和使用准则。它包含以下两个主题: 数据建模XML 数据可用多种方式存储在 SQL Server 2005 中,例如,使用原生 XML 数据类型和分散到表中的 XML。本主题提供了做出适当的选择以便对 XML 数据进行建模的准则。同时,还讨论了将 XML 数据编入索引、属性提升和 XML 实例的类型化。 用法本主题讨论了与用法相关的主题(如将 XML 数据加载到服务器以及查询编译中的类型推理),解释和区分了密切相关的功能,并推荐了这些功能的适当使用。文中通过示例阐述了各种概念。 为了最大限度地领会本文的内容,您应该对 SQL Server 环境中的 XML 功能有一个基本的了解。请参阅 XML Support in Microsoft SQL Server 2005。数据建模本节概述了使用 SQL Server 2005 中的 XML 的理由,提供了在原生 XML 存储和 XML 视图技术之间进行选择的准则,并且提供了数据建模建议。关系或 XML 数据模型如果您的数据是高度结构化的,具有已知的架构,则关系模型可能对于数据存储最为有效。Microsoft SQL Server 提供了您可能需要的必要功能和工具。另一方面,如果结构是灵活的(半结构化和非结构化)或未知的,则必须适当地考虑如何对此类数据进行建模。如果您需要独立于平台的模型,以便确保使用结构化和语义标记的数据的可移植性,则 XML 是一种不错的选择。而且,如果满足下列某些属性,则它还是一种适当的选择: 您的数据比较稀疏,或者您不了解数据的结构,或者数据的结构将来可能发生重大更改。 您的数据表示容器层次结构(与实体中的引用相对),并且可能是递归的。 您的数据具有内在的顺序。 您希望对数据进行查询,或者基于其结构更新部分数据。 如果上述任一条件都不满足,则您应该使用关系数据模型。例如,如果您的数据是 XML 格式,但您的应用程序很少使用数据库来存储和检索数据,则 nvarchar(max) 列就能满足您的全部需要。在 XML 列中存储数据可以带来其他好处 - 引擎将检查数据格式规范或者有效,并且支持对 XML 数据进行细粒度的查询和更新。在 SQL Server 2005 中存储 XML 数据的理由以下为一些使用 SQL Server 2005 中的原生 XML 功能而不是在文件系统中管理 XML 数据的理由: 您希望使用数据库服务器的管理功能来管理 XML 数据(例如,备份、恢复和复制)。 您希望以高效的方式和事务处理方式来共享、查询和修改 XML数据。细粒度的数据访问对于您的应用程序而言很重要。例如,您可能需要提取 XML 文档内部的某些节,或者您可能需要插入一个新节而不是替换整个文档。 您具有关系数据和 SQL 应用程序,您希望在应用程序内部的关系数据和 XML 数据之间进行互操作。对于跨域应用程序,您需要有关查询和数据修改的语言支持。 您希望服务器能够保证数据格式规范,并能够视情况根据 XML 架构来验证数据。 您需要将 XML 数据编入索引以便实现高效的查询处理和良好的可伸缩性,并且使用一流的查询优化器。 您希望对 XML 数据进行 SOAP、ADO.NET 和 OLE DB 访问。 如果不满足上述任一条件,您最好将数据存储为非 XML 的大型数据类型,如 nvarchar(max) 或 varbinary(max)。XML 存储选项SQL Server 2005 中的 XML 的存储选项如下所示: 本机存储采用 XML 数据类型: 用能够保留数据的 XML 内容(如容器层次结构、文档顺序、元素和属性值等等)的内部表示形式存储数据。具体说来,就是保留 XML 数据的信息集内容(有关信息集的详细信息,请参阅 /TR/xml-infoset)。它可能不是文本 XML 的精确副本,因为未保留以下信息:无关紧要的空格、属性顺序、命名空间前缀和 XML 声明。 对于类型化的 XML 数据类型(即绑定到 XML 架构的 XML 数据类型)而言,负责向信息集添加类型信息的后架构验证信息集 (Post Schema Validation Infoset, PSVI) 以内部表示形式编码。这会显著提高分析速度。(有关详细信息,请参阅 W3C XML 架构规范,网址为 /TR/xmlschema-1 和 /TR/xmlschema-2。) XML 和关系存储之间的映射: 使用带有批注的架构 (AXSD),XML 将被分解到一个或多个表中的列,并且在关系级别保留数据的保真度 - 保留层次结构,但忽略元素顺序。架构不能是递归的。 大型对象存储(nvarchar(max) 和 varbinary(max)): 存储了数据的精确副本。这对于特殊用途的应用(如法律文档)很有用。大多数应用不要求精确副本,XML 内容(信息集保真度)即可满足需要。 通常情况下,可能需要组合使用这些方法。例如,您可能需要用 XML 数据类型列存储 XML 数据,并将其中的属性提升到关系列中。相反,您可能希望使用映射技术,将非递归部分存储到非 XML 列中,而仅将递归部分存储到 XML 数据类型列中。XML 技术的选择XML 技术(原生 XML 与 XML 视图)的选择通常取决于下列因素: 存储选项: 您的 XML 数据可能更适合于大型对象存储(例如,产品手册),或者更适合于存储在关系列中(例如,转换到 XML 的行项目)。每个存储选项都在不同程度上保留了文档保真度。 查询功能: 基于查询的性质以及对 XML 数据进行查询的程度,您可能发现一个存储选项比其他存储选项更为适合。细粒度的 XML 数据查询(例如,XML 节点上的谓词计算)在这两个存储选项中受到不同程度的支持。 将 XML 数据编入索引: 您可能希望将 XML 数据编入索引,以便提高 XML 查询性能。索引选项随存储选项的不同而不同;您需要进行适当的选择以优化工作量。 数据修改功能: 某些工作量涉及到对 XML 数据进行细粒度的修改(例如,在文档内添加新节),而其他工作量则不涉及(例如,Web 内容)。对于您的应用程序而言,数据修改语言支持可能很重要。 架构支持: 您的 XML 数据可能通过架构进行描述,这可能是也可能不是 XML 架构文档。对架构绑定 XML 的支持取决于 XML 技术。 不用说,不同的选择具有不同的性能特性。原生 XML 存储可以将您的 XML 数据存储在服务器的 XML 数据类型列中。在下列情况下,这将是一个适当的选择: 您需要一种在服务器上存储 XML 数据的简单方法,同时需要保留文档顺序和文档结构。 您的 XML 数据可能有也可能没有架构。 您需要查询和修改您的 XML 数据。 您需要将 XML 数据编入索引以便实现更为快速的查询处理。 您的应用程序需要系统目录视图以管理您的 XML 数据和 XML 架构。 当您的 XML 文档具有多种结构时,或者当您的 XML 文档符合不同的或复杂的架构,而这些架构很难映射到关系结构时,原生 XML 存储将很有用。示例:使用 XML 数据类型对 XML 数据进行建模考虑一个 XML 格式的产品手册,其中每个主题对应单独的一章,而每章内又有多节。一节可以包含多个子节,因此 是一个递归元素。产品手册包含大量混合内容、图表和技术资料;数据是半结构化的。用户可能希望对感兴趣的主题执行与上下文有关的搜索(例如,在有关索引的章内部搜索有关聚集索引的节),并且查询技术数量。XML 文档的合适存储模型是 XML 数据类型列。这可以保留 XML 数据的信息集内容。将 XML 列编入索引可以提高查询性能。示例:保留 XML 数据的精确副本假设政府法令要求您保留 XML 文档(例如,已签署的文档、法律文档或股票交易订单)的精确文本副本。您可能需要将您的文档存储在 nvarchar(max) 列中。对于查询,可在运行时将数据转换为 XML 数据类型,然后对其执行 Xquery。运行时转换可能代价高昂,尤其是在文档很大时。如果您经常进行查询,可以采用冗余方式将文档存储在 XML 数据类型列中并将其编入索引,同时从 nvarchar(max) 列返回精确的文档副本。XML 列可能是基于 nvarchar(max) 列的计算列。您不能在 XML 计算列上创建 XML 索引,也不能在 nvarchar(max) 或 varbinary(max) 列上生成 XML 索引。XML 视图技术通过在 XML 架构和数据库的表之间定义映射,可以创建持久性数据的XML 视图。可以使用 XML 批量负载来填充使用 XML 视图的基础表。您可以查询使用 XPath 1.0 的 XML 视图;该查询将被转换为针对表的 SQL 查询。与此类似,更新也会被传递到这些表。在以下情况下,此技术很有用: 您希望拥有以 XML 为中心的编程模型,该模型使用现有关系数据上的 XML 视图。 您的 XML 数据具有架构 (XSD, XDR),它可能由外部合作伙伴提供。 数据的顺序不重要,或者您的可查询数据不是递归的,或者预先已经知道最大递归深度。 您希望通过使用 XPath 1.0 的 XML 视图来查询和修改数据。 您希望批量加载 XML 数据,并将其分解到使用 XML 视图的基础表中。 这方面的例子包括以 XML 形式公开以便用于数据交换和 Web 服务的关系数据,以及具有固定架构的 XML 数据。有关详细信息,请参阅 SQLXML 开发人员中心。示例:使用带有批注的 XML 架构 (AXSD) 对数据进行建模假设您现有一些希望以 XML 形式进行操作的关系数据(例如,客户、订单和行项目)。请使用 AXSD 在关系数据上定义 XML 视图。通过 XML 视图,可以将 XML 数据批量加载到表中,以及使用 XML 视图查询和更新关系数据。如果您需要在自己的 SQL 应用程序持续工作时与其他应用程序中的 XML 标记交换数据,则该模式很有用。混合模型很多时候,适合将关系数据和 XML 数据类型列结合起来进行数据建模。可以将 XML 数据中的某些值存储在关系列中,而将其余或全部 XML 值存储在 XML 列中。这可能会产生更好的性能(例如,可以完全控制在关系列上创建的索引)和锁定特性。然而,这需要您承担更多的责任来管理数据存储。要存储在关系列中的值取决于您的工作负荷。例如,如果您基于路径表达式 /Customer/CustId 检索全部 XML 值,则通过将 CustId 属性的值提升到关系列中以及将其编入索引,可能产生更高的查询性能。另一方面,如果您的 XML 数据被广泛且非冗余地分解到关系列中,则重新组合的成本可能很大。对于高度结构化的 XML 数据(例如,表的内容已经转换到 XML),可以将所有值映射到关系列(可能使用 XML 视图技术)。使用 XML 数据类型进行数据建模本节讨论有关原生 XML 存储的数据建模主题。这些主题包括将 XML 数据编入索引、属性提升和类型化 XML 数据类型。相同或不同的表XML 数据类型列可以在包含其他关系列的表中创建,也可以在与主表之间具有外键关系的独立表中创建。在满足下列某个条件时,请在同一个表中创建 XML 数据类型列: 您的应用程序在 XML 列上执行数据检索,并且不需要 XML 列上的 XML 索引。 或者 您需要在 XML 数据类型列上生成 XML 索引,并且主表的主键与其聚集键相同。有关详细信息,请参阅将 XML 数据类型列编入索引一节。 在满足下列条件时,请在单独的表中创建 XML 数据类型列: 您需要在 XML 数据类型列上生成 XML 索引,但主表的主键与其聚集键不同,或者主表不具有主键,或者主表是一个堆(也就是说,没有聚集键)。如果主表已经存在,则这可能是真的。 您不希望表扫描由于表中存在 XML 列(无论它是存储在行中还是存储在行外,都会占用空间)而降低速度。 XML 数据的粒度XML 列中存储的 XML 数据的粒度对于锁定和更新特性而言至关重要。SQL Server 对 XML 和非 XML 数据采用了相同的锁定机制。因此,行级锁定会导致相应行中的所有 XML 实例被锁定。当粒度比较大时,锁定大型 XML 实例以便进行更新会导致多用户场合下的吞吐量下降。另一方面,严重的分解会丢失对象封装并提高重新组合成本。对 XML 实例进行更新会将现有实例替换为更新后的实例,即使只修改单个属性的值。XML 数据粒度越大,更新成本就越高。较小的 XML 实例会产生较高的更新性能。对于良好的设计而言,重要的是保持数据建模需要与锁定和更新特性之间的平衡。非类型化、类型化和受约束的 XML 数据类型SQL Server 2005 XML 数据类型实现了 ISO SQL-2003 标准 XML 数据类型。因此,它可以在非类型化 XML 列中存储格式规范的 XML 1.0 文档以及带有文本节点和任意数量顶级元素的所谓的 XML 内容片段。系统将检查数据的格式是否规范,不要求将列绑定到 XML 架构,并且拒绝在扩展意义上格式不规范的数据。对于非类型化 XML 变量和参数,也是如此。如果您具有描述 XML 数据的 XML 架构,则可以将这些架构与 XML 列相关联,以便产生类型化 XML。XML 架构用于对数据进行有效性验证,在查询和数据修改语句编译过程中执行比非类型化 XML 更准确的类型检查,以及优化存储和查询处理。在下列条件下,请使用非类型化 XML 数据类型: 您没有对应于 XML 数据的架构 您拥有架构,但不希望服务器对数据进行有效性验证。当应用程序在服务器中存储数据之前执行客户端验证时,或者暂时存储根据架构无效的 XML 数据时,或者使用在服务器中不受支持的架构组件(例如 key/keyref)时,有时会出现这种情况。 在下列条件下,请使用类型化 XML 数据类型: 您拥有对应于 XML 数据的架构,并且希望服务器按照 XML 架构对 XML 数据进行有效性验证。 您希望充分利用基于类型信息的存储和查询优化。 您希望在查询的编译过程中更充分地利用类型信息。 类型化 XML 列、参数和变量可以存储 XML 文档或内容 - 您在声明时必须将它们指定为标志(分别指定为 DOCUMENT 或 CONTENT)。而且,您必须提供 XML 架构集合。如果每个 XML 实例恰好有一个顶级元素,请指定 DOCUMENT;否则,请使用 CONTENT。查询编译器在查询编译过程的类型检查中使用 DOCUMENT 标记来推理唯一的顶级元素。除了将 XML 列类型化以外,您还可以在类型化或非类型化 XML 数据类型列上使用关系(列或行)约束。在下列条件下,请使用约束: 无法在 XML 架构中表示业务规则。例如,花店的送货地址必须在其营业地点周围 50 英里范围之内,这可以编写为 XML 列上的约束。该约束可能涉及到 XML 数据类型方法。 您的约束涉及到表中的其他 XML 列或非 XML 列。这方面的一个例子是:强制 XML 实例中存在的 Customer ID (/Customer/CustId) 与关系 CustomerID 列中的值匹配。 文档类型定义 (DTD)XML 数据类型列、变量和参数可以使用 XML 架构而不是 DTD 加以类型化。然而,对于非类型化和类型化 XML,都可以使用内联 DTD 来提供默认值,以便将实体引用替换为它们的扩展形式。您可以使用第三方工具将 DTD 转化为 XML 架构文档,并且将 XML 架构加载到数据库中。将 XML 数据类型列编入索引可以在 XML 数据类型列上创建 XML 索引。这会将该列中 XML 实例上的所有标记、值和路径编入索引,从而提高查询性能。在下列条件下,您的应用程序可能受益于 XML 索引: 对 XML 列进行查询在您的工作负荷中很常见。必须考虑数据修改过程中的 XML 索引维护成本。 XML 值相对较大,而检索的部分相对较小。生成索引可以避免在运行时分析全部数据,并且因为受益于索引查找而提高查询处理的性能。 XML 列上的第一个索引是主 XML 索引。通过该索引,可以在 XML 列上创建三种类型的辅助 XML 索引,从而提高常见种类的查询的速度,如下节所述。主 XML 索引这会将 XML 列中的 XML 实例内部的所有标记、值和路径编入索引。基表(即包含 XML 列的表)必须在该表的主键上具有聚集索引;主键用于将索引行与基表中的行相关联。从 XML 列中检索完整的 XML 实例(例如 SELECT *)。查询使用主 XML 索引,并返回标量值或使用索引本身的 XML 子树。示例:创建主 XML 索引在我们的多数示例中,都使用带有非类型化 XML 列的表 T (pk INT PRIMARY KEY, xCol XML),这些示例都可以简单地扩展为类型化 XML 的形式(有关使用类型化 XML 的信息,请参阅 SQL Server 2005 联机图书)。为了便于说明,将针对如下所示的 XML 数据实例描述查询: Writing Secure Code Michael Howard David LeBlanc 39.99下面的语句在表 T 的 XML 列 xCol 上创建了名为 idx_xCol 的 XML 索引:CREATE PRIMARY XML INDEX idx_xCol on T (xCol)辅助 XML 索引在创建主 XML 索引之后,您可能希望创建辅助 XML 索引来提高工作负荷中的不同种类查询的速度。三种类型的辅助 XML 索引 - PATH、PROPERTY 和 VALUE 分别为基于路径的查询、自定义属性管理场合和基于值的查询提供帮助。PATH 索引在列中的所有 XML 实例上,按照文档顺序生成各个 XML 节点的 (path, value) 对的 B+ 树。PROPERTY 索引创建各个 XML 实例中 (PK, path, value) 对的聚集 B+ 树,其中 PK 是基表的主键。最后,VALUE 索引在 XML 列中的所有 XML 实例中,按照文档顺序创建各个节点的 (value, path) 对的 B+ 树。以下是创建上述一个或多个索引的一些准则: 如果工作负荷大量使用 XML 列中的路径表达式,则 PATH 辅助 XML 索引可能会加快工作负荷的处理速度。最常见的例子是在 T-SQL 的 WHERE 子句中对 XML 列使用 exist() 方法。 如果您的工作负荷从单独的使用路径表达式的 XML 实例中检索多个值,则将各个 XML 实例中的路径聚集到 PROPERTY 索引中可能会很有用。这种情况通常出现在属性包场合中,此时对象的属性被获取并且其主键值已知。 如果您的工作负荷涉及到查询 XML 实例中的值,而不知道包含这些值的元素或属性名称,则您可能需要创建 VALUE 索引。这通常发生在子代轴查找中,例如 /authorlast-name=Howard,其中 元素可以出现在层次结构的任意级别上。这种情况还会发生在通配符查询中,例如 /book * = novel,其中查询将查找具有某个值为 novel 的属性的 元素。 示例:基于路径的查找假设下面的查询在您的工作负荷中很常见:SELECT pk, xColFROM TWHERE xCol.exist (/bookgenre = novel) = 1路径表达式 /book/genre 和值 novel 对应于 PATH 索引的键字段。因此,PATH 类型的辅助 XML 索引对于该工作负荷很有用:CREATE XML INDEX idx_xCol_Path on T (xCol)USING XML INDEX idx_xCol FOR PATH示例:获取对象的属性请考虑下面的查询,它从表 T 的各个行中检索一本书的属性genre、title和 ISBN:SELECT xCol.value (/book/genre)1, varchar(50), xCol.value (/book/title)1, varchar(50), xCol.value (/book/ISBN)1, varchar(50)FROM T在这种情况下,属性索引很有用,其创建方式如下所示:CREATE XML INDEX idx_xCol_Property on T (xCol)USING XML INDEX idx_xCol FOR PROPERTY示例:基于值的查询在以下查询中,子代轴或自身轴 (/) 指定了部分路径,以便基于 ISBN 值的查找可以因为使用 VALUE 索引而受益:SELECT xColFROM TWHERE xCol.exist (/bookISBN = 1-8610-0157-6) = 1VALUE 索引按如下方式创建:CREATE XML INDEX idx_xCol_Value on T (xCol)USING XML INDEX idx_xCol FOR VALUEXML 列上的全文索引您可以在 XML 列上创建全文索引,从而将 XML 值的内容编入索引,而忽略 XML 标记。属性值没有被编入全文索引(因为它们被视为标记的一部分),并且元素标记被用作标记边界。在某些情况下,可以将全文搜索与 XML 索引用法结合起来: 首先,使用 SQL 全文搜索筛选感兴趣的 XML 值。 接下来,查询这些 XML 值,这会使用 XML 列上的 XML 索引。 示例:将全文搜索与 XML 查询结合起来在 XML 列上创建全文索引之后,以下查询将检查 XML 值是否在书名中包含单词custom:SELECT * FROM T WHERE CONTAINS(xCol,custom) AND xCol.exist(/book/title/text()contains(.,custom) =1CONTAINS() 方法使用全文索引,将文档中任何地方包含单词custom的 XML 值组合为一个子集。exist() 子句确保单词custom出现在书名中。使用 CONTAINS() 和 XQuery contains() 的全文搜索具有不同的语义。后者是子字符串匹配,而前者则是使用单词衍生的标记匹配。因此,如果要搜索标题中的字符串 run,则 run、runs 和 running 都将匹配,因为全文 CONTAINS() 和 Xquery contains() 都满足。然而,上述查询不匹配标题中的单词customizable。(全文 CONTAINS() 失败,而 Xquery contains() 被满足)。通常,对于纯粹的子字符串匹配,应该删除全文 CONTAINS() 子句。而且,全文搜索采用单词衍生,而 XQuery contains() 是一种字面匹配。这一区别将在下一个示例中阐述。示例:使用单词衍生对 XML 值进行全文搜索通常情况下,不能排除示例:将全文搜索与 XML 查询结合起来中的 XQuery contains() 检查。请考虑查询: SELECT * FROM T WHERE CONTAINS(xCol,run) 因为使用单词衍生,所以文档中的单词ran匹配搜索条件。而且,使用 XQuery 时不会检查搜索上下文。在使用被全文索引的 AXSD 将 XML 分解到关系列中时,XML 视图上的 XPath 查询不会对基础表执行全文搜索。属性提升如果主要是对少量元素和属性值进行查询(例如,基于客户 ID 查找客户,即指定了 /Customer/CustId 的值),您可能希望将这些数量提升到关系列中。当检索了整个 XML 实例,但只对一小部分 XML 数据进行查询时,这将很有用。在 XML 列上创建 XML 索引是没有必要的;相反,可以将被提升的列编入索引。必须编写查询以使用提升的列(即,查询优化器不会将对 XML 列的查询重新定向到提升的列)。提升的列可以是同一表中的计算列,也可以是表中单独的、用户维护的列。当从各个 XML 实例中提升唯一值(即单值属性)时,这已足够。然而,对于多值属性,您必须为该属性创建单独的表,如下所述。基于 XML 数据类型的计算列可以使用能够激活 XML 数据类型方法的用户定义函数 (UDF) 来创建计算列。计算列的类型可以是任何 SQL 类型,包括 XML。以下示例说明了这一点。示例:基于 XML 数据类型方法的计算列为书籍的 ISBN 创建用户定义的函数:CREATE FUNCTION udf_get_book_ISBN (xData xml)RETURNS varchar(20)BEGIN DECLARE ISBN varchar(20) SELECT ISBN = xData.value(/book1/ISBN, varchar(20) RETURN ISBN END为 ISBN 向表中添加一个计算列:ALTER TABLE TADD ISBN AS dbo.udf_get_book_ISBN(xCol)可以用通常的方式将计算列编入索引。示例:基于 XML 数据类型方法的计算列上的查询要获取其 ISBN 为 0-7356-1588-2 的 ,可以改写 XML 列上的查询SELECT xColFROM TWHERE xCol.exist (/bookISBN = 0-7356-1588-2) = 1以使用计算列,如下所示:SELECT xColFROM TWHERE ISBN = 0-7356-1588-2可以创建一个用户定义的函数,返回 XML 数据类型和使用该 UDF 的计算列。然而,无法在计算的 XML 列上创建 XML 索引。创建属性表您可能希望将 XML 数据中的某些多值属性提升到一个或多个表中,在这些表上创建索引,并且重定向查询以使用这些表。典型的情形是一小部分属性覆盖了大部分查询工作负荷。您可以执行以下操作: 创建一个或多个表以存放多值属性。您可能发现采用以下处理方式会很方便:每个表存储一个属性,并且在属性表中复制基表的主键以便与基表进行向后联接。 如果您希望保持属性的相对顺序,则需要为相对顺序引入一个单独的列。 在 XML 列上创建触发器以便维护属性表。在触发器中,执行以下操作: 使用 XML 数据类型方法(如 nodes() 和 value())在属性表中插入和删除行。(有关 nodes() 方法的详细信息,请参阅 Value()、Nodes() 和 OpenXML()。) 在 CLR 中创建流式表值函数,以便在属性表中插入和删除行。 编写查询,以便对属性表进行 SQL 访问,以及对基表中的 XML 列进行 XML 访问,这需要使用这些表的主键将其相互联接。 示例:创建属性表假设您希望提升作者的名字。书籍有一个或多个作者,因此名字是一个多值属性。每个名字都存储在属性表的单独行中。在属性表中复制了基表的主键以便向后联接。create table tblPropAuthor (propPK int, propAuthor varchar(max)示例:创建用户定义的函数以便从 XML 实例生成行集下面的表值函数 udf_XML2Table 接受一个主键值和一个 XML 实例。它将检索 元素的所有作者的名字,并返回(主键,名字)对行集。create function udf_XML2Table (pk int, xCol xml)returns ret_Table table (propPK int, propAuthor varchar(max)with schemabindingasbegin insert into ret_Table select pk, nref.value(., varchar(max) from xCol.nodes(/book/author/first-name) R(nref) returnend示例:创建触发器以填充属性表插入触发器:在属性表中插入行create trigger trg_docs_INS on T for insertas declare wantedXML xml declare FK intselect wantedXML = xCol from inserted select FK = PK from insertedinsert into tblPropAuthorselect * from dbo.udf_XML2Table(FK, wantedXML)删除触发器:基于删除行的主键值,从属性表中删除行create trigger trg_docs_DEL on T for deleteas declare FK int select FK = PK from deleted delete tblPropAuthor where propPK = FK更新触发器:在与更新的 XML 实例对应的属性表中删除现有行,并且在该属性表中插入新行create trigger trg_docs_UPDon Tfor updateasif update(xCol) or update(pk)begin declare FK int declare wantedXML xml select FK = PK from deleted delete tblPropAuthor where propPK = FKselect wantedXML = xCol from insertedselect FK = pk from insertedinsert into tblPropAuthor select * from dbo.udf_XML2Table(FK, wantedXML)end示例:查找作者的名字为David的 XML 实例可以在 XML 列上表示该查询。另外,还可以在属性表中搜索名字David,然后与基表执行向后联接以返回 XML 实例,如下所示:SELECT xCol FROM T JOIN tblPropAuthor ON T.pk = tblPropApPKWHERE tblPropApAuthor = David示例:使用 CLR 流式表值函数的解决方案该解决方案包括以下步骤:(a) 定义 CLR 类 SqlReaderBase,它实现了 ISqlReader,并且通过在 XML 实例上应用路径表达式来生成流式表值输出;(b) 创建一个程序集和一个 T-SQL 用户定义函数 (UDF) 来激活该 CLR 类;(c) 使用 UDF 定义插入、更新和删除触发器,以维护属性表。首先,创建流式 CLR 函数,其主干如下所示。XML 数据类型被公开为 ADO.NET 中的托管类 SqlXml;它支持返回 XmlReader 的方法 CreateReader()。public class c_streaming_xml_tvf public static ISqlReader streaming_xml_tvf (SqlXml xmlDoc, string pathExpression) return (new TestSqlReaderBase (xmlDoc, pathExpression);/ Class that implements ISqlReaderpublic class TestSqlReaderBase : ISqlReader XPathNodeIterator m_iterator; ?public SqlChars FirstName;/ Metadata for current resultsetprivate SqlMetaData m_rgSqlMetaData; public TestSqlReaderBase (SqlXml xmlDoc, string pathExpression) / Variables for XPath navigation XPathDocument xDoc; XPathNavigator xNav; XPathExpression xPath; / Set sql meta data m_rgSqlMetaData = new SqlMetaData1; m_rgSqlMetaData0 = new SqlMetaData (FirstName, SqlDbType.NVarChar,50); /Set up the Navigator if (!xmlDoc.IsNull) xDoc = new XPathDocument (xmlDoc.CreateReader(); else xDoc = new XPathDocument (); xNav = xDoc.CreateNavigator(); xPath = xNav.Compile (pathExpression); m_iterator = xNav.Select(xPath);public bool Read() bool moreRows = true; if (moreRows = m_iterator.MoveNext() ?FirstName = new SqlChars (m_iterator.Current.Value); return moreRows;接下来,创建一个程序集,以及一个与 CLR 函数 streaming_xml_tvf 对应的 T-SQL 用户定义函数 SQL_streaming_xml_tvf(未显示)。该 UDF 用于定义表值函数 CLR_udf_XML2Table 以便生成行集:create function CLR_udf_XML2Table (pk int, xCol xml)returns ret_Table table (FK int, FirstName varchar(max)with schemabindingasbegin insert into ret_Table select pk, FirstName FROM SQL_streaming_xml_tvf (xCol, /book/author/first-name) returnend最后,定义触发

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论