-- 作者:admin -- 发布时间:2005-10-21 21:25:57
-- SQL Server 2005中的XML的最佳实践
Microsoft SQL Server 2005 对XML数据处理提供了广泛的支持。XML值可以以原生的形式存储在具有XML数据类型的列中,它们可以是有类型的XML(typed XML),或者是无类型的XML(untyped XML)。你可以对XML列添加索引。此外,还可以使用XQuery和XML DML来精细地操作数据,后者已成为数据修改功能的扩展。
Microsoft SQL Server 2000和SQLXML web版提供了强大的XML数据管理能力。他们主要体现在关系型数据和XML数据的映射上。关系型数据的XML视图可以用带注解的XSD(AXSD)定义,来提供一个以XML为中心的方法用以支持数据的大量装载,查询,以及对xml数据的改写能力。T-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数据进行索引,属性提升(property promotion,),XML实例的类型化。
·用法
这个主题将讨论XML数据使用方面的内容,诸如装载XML数据到server中,输入推论在查询编辑中(and type inference in query compilation);解释和区分相近的特性;对这些特性的建议用法。还用例子来做个演示。
如果想更好的阅读本文档,建议先对SQL Server中的XML特性有个基本的了解。可以查看XML Support in Microsoft SQL Server 2005.
数据建模
这一部分简要的介绍了在SQL Server 2005中使用XML的原因,并对如何选择原生XML存储或XML视图技术提供了一些指导,和数据建模方面的建议。
关系型还是XML数据模型
如果数据具有高度的结构化和熟悉的架构,那么采用关系型模型存储数据更合适。微软SQL Server为此提供了必要的功能和相应的工具。另一方面,如果数据结构很灵活(半结构化或无结构化)或者结构未知,那你就必须为这些数据考虑合适的数据模型。
XML是个好的选择,如果你还希望这个数据模型是平台独立的,数据能够在结构化和语义标记间保持灵活的话。此外,如果考虑到下面几个因素的话,就更合适了:
·数据稀疏,或者数据结构未知,或者是数据结构将来会有较大的改变。
·数据需要表现出层次性(并非实体之间的引用)且可能有递归。
·数据内含顺序特性。
·你希望根据数据的结构来查询或更改部分数据。
如果你不需要满足上面这些条件,那么你应该选择关系型数据模型。例如,如果你的数据是XML格式的,但应用程序仅仅是存储和检索它,那么一个[n]varchar(max)列足够了。将数据存储在XML列有额外的优点:存储引擎会检查数据是否具有良好的格式、合法性,且支持对XML数据的精细的查询和修改。
在SQL Server 2005存储XML数据的原因
下面是选择在SQL Server 2005中存储XML数据而非在文件系统中管理XML数据的原因:
·你希望能利用数据库服务器的管理特性来管理XML数据(如,备份、恢复、复制)。
·你希望能够以有效的、交易化的方式来共享、查询和修改XML数据。对你的应用程序而言,精细的数据访问很重要。例如,你可能希望提取XML文档中的某一部分,或者是希望插入一个新的部分而不是替换整个文档。
·你已有关系型的数据和应用程序,并且你希望在你的应用程序中关系型数据和XML数据间能互操作,你需要一个能够在整个应用程序中查询和修改数据的语言。
·你希望服务器能够保证数据的良好结构性,且能根据XML架构验证数据。
·你希望能够对XML数据添加索引来获得更有效的查询处理和更好的扩展性。
·你希望能够用SOAP、ADO.NET、OLE DB来访问XML数据。
如果不存在上面这些情况,把数据存储为非XML的,大对象类型的如[n]varchar(max) 或 varbinary(max)更为合适。不然,你还是应该采用XML来存储数据。
XML存储选项
SQL Server 2005中XML数据存储选项如下:
·作为XML数据类型来存储:
这种存储方式将保留XML数据的内容,如层次性、文档顺序、元素和属性值等。特别是XML数据的InfoSet内容被保留(更多InfoSet信息,请参见http://www./TR/xml-infoset)。它不是XML文本的原样拷贝,它忽略了一些信息:无意义的空格、属性的顺序、命名空间前缀、XML声明。
对有类型的XML数据类型(也就是说XML数据类型和XML架构相关联),post-schema validation Infoset (PSVI,它将类型信息加入Infoset)被编码到XML数据的内部表示中,这将显著提高语法分析速度。(更多信息,请查阅W3C架构规范http://www./TR/xmlschema-1 和 http://www./TR/xmlschema-2)。
·把XML数据映射成关系型数据来存储:
通过AXSD,XML数据被分解到一个或多个表的列中,在关系级别上忠实的保留了数据——层次结构被保留,然而元素的顺序被忽略了。架构不可被回归,操作不可逆。
·大对象存储([n]varchar(max) 和 varbinary(max)):
这种方式是XML数据的原样拷贝。这种方法对于一些特定的应用很有用,如法律文本的保存。大多数应用并不需要原样拷贝,忠实的Infoset 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格式,每个主题有各自的章节,每章中有多个段落(section)。段落还包含子段落,因此<section>是个递归的元素(element)。产品手册还包含大量的混合内容、图表、技术资料等,数据是半结构化的。用户希望能够对感兴趣的主题执行语义查找(如”indexing”章节中的”clustered index”段落),这里,对XML文档的合适的存储模型是XML数据类型列。这将保留XML数据的Infoset内容,并且可以对XML加索引提高查询速度。
例:保持XML数据的原样拷贝
假如政府规章(XML文档格式)要求完全的原样拷贝(如,签署的文档、法律文档、股票交易单等),你可能需要存储该文档在[n]varchar(max)列中。
对查询而言,SQL Server将在运行是转化数据为XML数据,并且对其执行Xquery操作。运行时的转化可能非常消耗资源,特别是当文档很大时。如果你需要频繁的查询,你应该额外存储文档在一个XML数据列中,并对其加索引,仅在需要原样文档时才从[n]varchar(max)列中取得。
XML列可以是基于[n]varchar(max)列的计算列。你不能在XML计算列上创建XML索引,然而,你也不能在[n]varchar(max) 或 varbinary(max) 列上创建XML索引。
XML视图技术
借助于在XML架构和数据库的表之间定义映射,你可以为永久数据(不被改写的)创建“XML视图”。XML大容量装载功能可以被用来往使用XML视图的基础表上装填数据。你可以使用XPath 1.0 查询XML视图,该查询被翻译成施加在表上的SQL查询。同样的,改写也是这么做的。
这项技术适用于下面几种场合:
·你希望你的编程模型以XML为中心,这样你可以使用XML视图在已存在的关系型表上。
·你的XML数据有架构对应(XSD, XDR),该架构是你的外部合作伙伴所提供的。
·XML数据的顺序不重要,或者是需查询的数据不是递归的,或者是将来的最大递归深度已知。
·你希望使用XPath 1.0 来通过XML视图查询和修改数据。
·你希望能大容量装载XML数据并且能把它分解到使用XML视图的基表中。
关系型的数据被暴露为XML数据用于数据交换和web service,带固定架构的XML数据。更多信息,请参见the SQLXML Developer Center.
例:使用带注解的XML架构(AXSD)对数据建模
假设你已有关系型数据(诸如客户信息,订单信息),你希望把它作为XML数据来操作。你可以在关系型数据上使用AXSD来定义一个XML视图。这个XML视图允许你大量导入XML数据到表中,并且能够借助它查询和修改关系型数据。如果你需要和其他应用程序交换XML数据,同时不影响SQL应用程序的正常运行,采用这种建模非常有用。
混合模型
常见的数据建模情况是结合了关系型和XML数据类型的混合模型。XML数据中的一些值可以存储在关系型的数据列中,剩余的、也可以是全部的XML值被存储在XML列中。这会导致较好的性能(如,你可以完全控制关系型列上的索引)和锁的特性。然而,你必须对管理数据的存储付出更多的劳动。
怎样把值存储在关系型列中依赖于你的实际情况。例如,如果你基于路径表达式/Customer/@CustId检索整个XML值,接着提升(promoting)CustId属性值到关系型列中,对该列加索引,将会得到很快的查询速度。另一方面, 如果你的XML数据被彻底的且不带冗余的分解到关系型的列中,重新拼装的代价可能会很高。
对于那些有着高度结构化的XML数据(如,表的内容可以被转换成XML数据),你可以使用XML视图技术映射所有的值到关系型的列中。
使用XML数据类型的数据建模这一部分将讨论原生XML存储方式下的数据建模。包括:索引XML数据、属性提升(property promotion)、有类型(typed)的XML数据类型。
同一个表中或不同表
XML数据类型列可以关系型列在一个表中共存,也可以单独在另一张表中,通过主外键的方式和主表相联。
当满足下面条件时,可以创建XML数据类型列和关系型列在同一张表中:
·应用程序从XML数据列上检索数据,但并不要求其上有XML索引
或者
·你希望在XML数据类型列上构建索引,主表的主键就是表的聚集索引。
当满足下面条件时,在另一张表中创建XML数据类型列:
·你希望在XML数据类型列上构建XML索引,但主表的主键不是聚集索引,或者主表没有主键,或者主表没有聚集索引。
·你不希望由于表中XML列的原因导致表扫描速度下降,不管它是in-row存储还是out-of-row存储。
XML数据粒度
存储在XML列中的XML数据粒度对锁和改写特性至关重要。SQL Server 采用同样的锁机制对XML数据和非XML数据,因此,行级锁将造成一行中的所有XML实例被锁。当粒度较大时,更大的XML实例被锁将导致在多用户环境下的吞吐量下降。另一方面,过度的分解(粒度较小)将导致对象封装的丢失和重新拼装代价的提高。
在数据建模需求和锁、改写特性之间的平衡,对一个好的设计是非常重要的。
无类型、有类型和受约束的XML数据类型
SQL Server 2005 XML数据类型实现了ISO SQL-2003所定义的 标准XML数据类型。同样,它可以存储良好结构的XML 1.0 文档,以及所谓的带文本节点和任意数量的顶级元素的XML内容片段在无类型的XML列中。系统会检查数据是否是良好结构的,并不要求该列被绑定到XML架构上,同时在引伸意义(extended sense)拒绝不具备良好结构的数据。这对无类型的XML变量和参数也一样。
如果你有XML架构来描述XML数据,你将能够把架构和XML列关联起来产生有类型(typed)XML。相对于无类型的XML而言,在查询和数据修改语句的编译时,XML架构被用来校验数据,执行更精确的类型检查,此外,它还能优化查询和存储处理。
在下面情况下使用无类型的XML数据类型:
·你的XML数据没有架构
·你有XML架构,但你不希望服务器校验数据。有时有这种情况:应用程序在存储数据到服务器之前在客户端校验数据,或者是临时地根据架构存储非法的XML数据,或者是服务器不支持这种架构成分(如key/keyref)。
在下面情况下使用有类型的XML数据类型:
·你的XML数据有XML架构,同时你还希望服务器能根据XML架构校验XML数据。
·你希望能够根据类型信息在存储和查询方面的得到好处
·你希望在编译查询时得到
有类型的XML列,参数和变量都能够存储XML文档或者内容,只要你在声明时分别的指定标记(DOCUMENT 或 CONTENT),此外,你还可以提供XML架构集。如果每个XML实例都有完整的一个顶级元素,那么指定DOCUMENT,否则指定CONTENT。查询编译器在编译时使用DOCUMENT标记进行类型检查,推断出单独的顶级元素。
除了类型化一个XML列之外,你还可以使用关系型的约束(列约束或者是行约束)在有类型或者是无类型的XML数据类型列上,通常使用在下面的场合:
·你的商业规则不能被表示为XML架构。例如下面这个商业规则,花店的送货地址必须在花店的50英里之内。这时我们可以把它作为约束在XML列上。约束必须包含XML数据类型方法。
·你的约束包含表中的其他XML列或非XML列,一个例子是客户ID的强制性(/Customer/@CustId),它被建立在一个XML实例上,用来匹配关系型CustomerID列的值。
文档类型定义(DTD)
XML数据类型列,变量和参数可以用XML架构来类型化,但不能用DTD来做。然而,行内(inline)的DTD可以被用来对有类型和无类型的XML提供默认值,和替换实体引用。
你可以使用第三方工具转换DTDs为XML架构文档,再把它加载到数据库中。
|