当W3C的专家们刚开始筹划XML(eXtensible Markup Language) 的标准时,他们的目的是发明一种比HTML更好得标识语言:“Originally designed to meet the challenges of large-scale electronic publishing …”(http://www.w3.org/XML/)。没有想到最终结果却是为互联网上的数据传输提供了一个好办法。
<Customer CustomerID="ALFKI" CompanyName="Alfreds Futterkiste" ContactName="Maria Anders" Phone="030-0074321">
<Order OrderID="10643" OrderDate="1997-08-25T00:00:00">
<OrderDetail UnitPrice="45.6000" Quantity="15">
<Product Productname="Rössle Sauerkraut" UnitPrice="45.6000" />
</OrderDetail>
<OrderDetail UnitPrice="18.0000" Quantity="21">
<Product Productname="Chartreuse verte" UnitPrice="18.0000" />
</OrderDetail>
<OrderDetail UnitPrice="12.0000" Quantity="2">
<Product Productname="Spegesild" UnitPrice="12.0000" />
</OrderDetail>
</Order>
<Order OrderID="10692" OrderDate="1997-10-03T00:00:00">
<OrderDetail UnitPrice="43.9000" Quantity="20">
<Product Productname="Vegie-spread" UnitPrice="43.9000" />
</OrderDetail>
</Order>
</Customer>
上面的XML非常自然的表现出客户、订单、订单细节、和产品之间的关系。这是因为在XML中,数据和元数据(Metadata)是结合在一起的。这个特点使XML具有自我解释的能力。这正是互联网数据传输所需耍的。
在SQL2000中,FORXML提供了非常简单快捷的方法将任何SELECT的结果变成任何的格式XML,OPENXML则可将任何的格式XML变成SELECT的结果。再加上SQLXML的API,SQL2000成为了第一个可直接面向互联网的关系性数据库。
但XML可以解决更多关系性数据库解决不了(or不好)的问题,特别是在数据模型(data modeling)方面:
- 半结构性semi-structure
- 分层hierarchical
- 保留顺序order preservation
- 非结构性un-structure
通过下面的例子我们可以看到XML如何解决上述问题1,2,3.
一个描述家族谱系的XML:
<?xml version="1.0" encoding="utf-8"?>
<成员 名="李一" 生日="yyyy-mm-dd" 冥日="yyyy-mm-dd">
<成员 名="李二一" 生日="yyyy-mm-dd" 冥日="yyyy-mm-dd">
<成员 名="李三一" 生日="yyyy-mm-dd" 冥日="yyyy-mm-dd">
...
</成员>
<成员 名="李三三" 生日="yyyy-mm-dd" 冥日="yyyy-mm-dd">
...
</成员>
<成员 名="李三四" 生日="yyyy-mm-dd" 冥日="yyyy-mm-dd">
<成员 名="李四四" 生日="yyyy-mm-dd" 冥日="yyyy-mm-dd"/>
<成员 名="李四六" 生日="yyyy-mm-dd" 冥日="yyyy-mm-dd">
<成员 名="李五一" 生日="yyyy-mm-dd" 冥日="yyyy-mm-dd" 妻="李张氏">
<成员 名="李六一" 生日="yyyy-mm-dd" 冥日="yyyy-mm-dd" 妻="李王氏">
<成员 名="李七一" 生日="yyyy-mm-dd" 冥日="yyyy-mm-dd" 妻="李赵氏">
<成员 名="李八一" 生日="yyyy-mm-dd" 冥日="yyyy-mm-dd" 妻="李张氏">
<成员 名="李九一" 生日="yyyy-mm-dd" 妻="李胡氏" 职业="教师">
<成员 名="李十一" 生日="yyyy-mm-dd" 职业="学生"/>
</成员>
</成员>
</成员>
</成员>
</成员>
</成员>
<成员 名="李四七" 生日="yyyy-mm-dd" 冥日="yyyy-mm-dd"/>
</成员>
</成员>
<成员 名="李二二" 生日="yyyy-mm-dd" 冥日="yyyy-mm-dd"/>
<成员 名="李二三" 生日="yyyy-mm-dd" 冥日="yyyy-mm-dd">
<成员 名="李三二" 生日="yyyy-mm-dd" 冥日="yyyy-mm-dd">
...
</成员>
</成员>
</成员>
从上面数据中,你可看出下述特点:
- 直观表现层次(hierarchical)。如要找出李五一所有直系子孙,只需执行查询 //成员[@名="李五一"]
- 保留顺序(order preservation)。如要找出李二一第三个孩子的名字,只需执行查询 //成员[@名="李二一"]/成员[3]/@名
- 支持半结构性(semi-structure)数据。从李五一开始,增加了关于”妻”的新属性。从李九一开始,增加了关于”职业”的新属性。这些增加都不对已有数据产生影响。
SQL2005通过对XML的内置(native support)和对XQuery的支持实现了上述功能.