信息之舟电脑软件应用栏目编者按:
摘要:本论文简要的探讨了XML和数据库之间的关系,同时列出一些可以使用数据库处理XML文档的软件。虽然这里不打算详尽地介绍这些软件,但是笔者希望它能够描述使用数据库处理XML文档中的主要部分。
5.3 数据类型、空值、字符集合和其它
本节将探讨一些有关来自数据库的XML文档的存储问题。通常,你决定不了你选择的中间件是如何解决这些问题的,但是你最好应该意识到这些问题的存在,因为这有助于你正确选择你的中间件。
5.3.1 数据类型
XML不支持任何有实际意义的数据类型。除了未析实体,所有XML文档中的数据都被当成文本来对待,即便它能够用其他的数据类型(如日期或者整数)来表示。通常,数据转换中间件将把XML文档中的文本转换成其它数据库中的数据类型,反之亦然。然而,特定的数据类型所识别的文本格式是有限制的,例如受到提供的JDBC Driver所支持的数据类型的限制。在这些众多的数据类型中,日期类型通常会导致麻烦。不同国际地区的数字格式的差异也可能产生问题。
5.3.2 二进制数据
通常有两种方法将二进制数据保存到XML文档中的:未析实体和Base64编码处理(一种MIME编码方法,可以将二进制数据映射成US-ASCII的子集)。
对于关系型数据库,这两种方法都可能存在问题,因为从数据库中保存和检索二进制数据的规则非常的严格,这样对会导致中间件出现问题。
另外,并没有一种标准的符号用来说明一个XML文档中的元素包含有Base64编码数据,从而使得中间件可能根本就不能够识别这种编码。最后,在存储数据到数据库时,可能会忽略与未析实体或Base64编码元素相关的符号。所以,如果对你而言二进制数据非常重要的话,请务必要确认你的中间件是否支持二进制数据。
5.3.3 空值
在数据库世界中,空值(null)数据意味着数据不存在值。但是这与一个值为0的数字或长度为0的字符串有很大的区别。例如,假设你的数据来自一个气象站,如果气象站的温度计出了毛病读不出温度值,那么你的数据库中将存储一个null值而不是一个0。显然,值为0完全是另外一回事了。
XML中空值概念的支持可以通过设置可选的元素类型或属性来实现。如果元素类型或属性值为null,XML只要在文档不包含该元素或者属性就可以了。但是对数据库而言,空的元素或包含0长度字符串的属性并不是空值null:它们的值为长度为0的字符串。
当在XML文档和数据库结构之间相互映射过程中,你必须特别注意那些可选的元素类型或属性是否对应于数据库中的空值项。如果不这么做的话,很可能出现插入错误(当将数据转换到数据库中时)或者无效文档错误(当将数据从数据库读出时)。
因为同样要用符号空值,XML中相对与数据库而言更为灵活。具体来讲,许多XML用户很可能包含空字符串的空元素或属性是空值。这个时候你必须考虑如何选择合适的中间件来解决这个问题。一些中间件可以让用户选择在XML文档中定义用什么来组成空值。
5.3.4 字符集
根据定义,除了一些控制字符,XML文档能够包含任何的Unicode字符。但是不幸的是,许多数据库都限制或则不支持Unicode,而且需要一些特殊的配置才能够处理非ASCII编码的字符数据。如果你的数据包含了非ASCII字符,那么务必要核实你的数据库和中间件是否能够处理这些字符。
5.3.5 处理指令
处理指令并不属于XML文档中的“数据”部分,因此目前许多中间件可能不能正常的处理。问题是,尤其是在将XML文档结构严格映射成数据库结构时,处理指令通常是很难处理的,因为它们可以虚拟地出现在文档的任何位置。因此,中间件就很难判断将它们保存到什么位置以及在什么时候检索读取出来。如果处理指令和文档的循环回复("round-tripping")对你而言是非常重要的话,就务必检查你的中间件是如解决这个问题的。
对于每个包含混合内容的元素类型,创建一个单独的表格,其中存放未析数据,通过父元素主键链接到父表格。
对于此元素类型的每个单值属性和只包含未析数据内容、只出现一次的子元素,在该表格中创建一个字段。如果元素类型或者属性是可选的,可以让设置该字段为空值。
对于每个多值属性和多次出现的子元素,创建一个单独的表格来存储数值,并且通过父元素主键链接到父表格。
对每个有元素或者混合内容的子元素,通过父元素主键将父元素表格和子元素表格相连接。
下面的过程(经简化)说明了如何从一个关系型的结构生成一个DTD:
对于每个表格,新建一个元素;
对于表格中的每个字段,新建一个属性或者是只包含未析数据的子元素;
对于每个表格字段中提供主键的主键/外键的关系都新建一个子元素。
不幸的是,这些过程还存在着一些缺陷。例如,DTD中没有方法预先准确地规定数据类型或者字段长度。
因为任何的预先定义(例如通过读取一个示例文档)在读取其它“类型”的文档或者其他文档中包含有超过字长内容的文档时就会产生错误。(长久之策是使用XML schema文档的数据类型。)简单来说,当从一关系型结构生成DTD时,是没有办法预先判断子元素“应该”出现的顺序或者字段(如数据库内部的行标识)是否该进行完全转换。
在以上两种情况中都可能产生命名的冲突。
尽管有这样那样的缺陷,但是这些方法仍然能够很好地奠定在关系型结构和DTD之间互相转换的起点。
