荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Sage (魅力四射), 信区: Database
标  题: [转载] 中文翻译(四)(转寄)
发信站: BBS 荔园晨风站 (Tue Sep 12 11:48:03 2000), 站内信件

【 以下文字转载自 Sage 的信箱 】
【 原文由 Sage 所发表 】
XML介绍之三十二:XML和数据库设计原则、展望、工具(四)
by Ronald Bourret
4.0 存储和获取数据
    数据的类型可以在数据为主的文件的原始定义或则从数据库中的字段类型中得到。

    前者的例子是你想把数据库中的数据保存成XML文件放到网站上;后者的例子是你需

把大量的数据保存到关系数据库中。根据你的具体需求,你需要的软件或则是把XML数据
读入到
数据库或则是把数据库中的数据输出到XML文件,或则两者都支持。
4.1 转录数据
    当将数据保存在数据库中,它经常需要抛弃与文档信息有关的大量内容,例如它的
名称和
DTD,同时还有它的物理结构,例如实体的定义和使用、属性值和相同类型元素的出现顺
序,还有
二进制数据的存储方式 (是经过Base64编码的还是没有经过编码的实体或则其他方式),
 CDATA的
内容和其他编码信息。简单而言,当从数据库中获取信息时,最后生成的XML文档结果可
能不
包含任何CDATA或则实体运用(entity usage) (除非预先定义了实体lt(就是符号"<"
),
gt(">"), amp("&"), apos("'"),  quot("""))和同类型元素、属性出现的顺序。
    例如,假设你需要把一个销售单的信息使用XML格式从一个数据库中获取数据然后转
录到另外
一个数据库中,在这个例子中,在XML文档中并不关心销售单的编号是保存在销售单的日
期的
前面还是后面,也不用关心是否将顾客的名称保存在CDATA section作为一个扩展入口,
 或则甚至
直接当成一个PCDATA. 但是,对于将这些相关数据从第一个数据库中转录到第二个数据
库的
过程中,这些信息都是非常重要的。这样,这个数据传输软件就需要考虑使用树状结构

它将一个单独的销售单的信息用组(group)来实现)。
    另一个当忽略文档信息和它的物理结构会带来麻烦的例子是---"借贷套利"文档,它
保存的
数据是从一个数据库中的文档中获取,并且需要重新组装这些数据成为一个新的文档,
而这个
过程经常会导致新的文档的结构和原来的文档会不一致。
    从上面的例子可以看出,对于数据库和数据传输中间件的选择是根据你的需求而变
化的。
4.2 将文档结构映射成数据库结构
    为了能够在XML文档和数据库之间传递数据,有必要将文档的结构映射成数据库的结
构,
反之亦然,这种映射关系又分两类:模板驱动和模型驱动
4.2.1 以模板驱动的映射
    以模板驱动的映射, 这种映射没有预先定义文档结构和数据库结构之间的映射关系
,而是
使用将命令语句内嵌入模板的方法,让数据传输中间件来执行该模板。例如,考虑下面

的模板(注意该模板并不适应与所有的产品),在<SelectStmt>元素中内嵌了SELECT选
择:
   <?xml version="1.0"?>
   <FlightInfo>
      <Intro>The following flights have available seats:</Intro>
      <SelectStmt>SELECT Airline, FltNumber, Depart, Arrive FROM Flights</Se
lectStmt>
      <Conclude>We hope one of these meets your needs</Conclude>
   </FlightInfo>
   当数据传输中间件处理到该文档时,每个SELECT选项都将被他们各自的结果所替换,

   得到下面的XML格式:
   <?xml version="1.0"?>
   <FlightInfo>
      <Intro>The following flights have available seats:</Intro>
      <Flights>
         <Row>
            <Airline>ACME</Airline>
            <FltNumber>123</FltNumber>
            <Depart>Dec 12, 1998 13:43</Depart>
            <Arrive>Dec 13, 1998 01:21</Arrive>
         </Row>
         ...
      </Flights>
      <Conclude>We hope one of these meets your needs</Conclude>
   </FlightInfo>
    这种以模板驱动的映射方法相当灵活。例如,一些产品允许你在最后的结果中替换
你想要
的内容 -- 包括在SELECT中使用参数 -- 而不是象上面的例子中简单地格式化结果。
另外它还支持使用编程结构例如循环和条件判断结构。还有就是它支持通过HTTP的传递
参数。
    目前,以模板驱动的映射仅仅只支持从一个关系数据库转换成XML文档的情况。
4.2.2 以模型驱动的映射
    在以模型驱动的映射模式中,它的原理就是利用XML文档中的数据模型的结构显性或
隐性地
将其映射成数据库的结构,反之亦然。它的缺点是灵活性不如模板驱动方式,但是优点
是简单
易用,这是因为它是基于具体的数据模型来进行映射的,通常它能够自己完成很多地转
换工作,
从而简单易用。因为将数据从数据库转换成XML的工作是根据单一的一个模型(模型),
所以通常
在这种方式下还要综合搭配XSL来提供灵活性。
    在XML文档中有两种模型是非常普遍的。第一种是被许多中间件包在转换XML文档成
关系数据库
数据所使用到的模型,就是将XML文档当成一个单独的表(Table)对象或则一系列表对
象。
也就是说,真正的XML文档必须类似于下面的格式,如果是单一的表对象的话,<databa
se>元素就
不需要出现了
   <database>
      <table>
         <row>
            <column1>...</column1>
            <column2>...</column2>
            ...
         </row>
         ...
      </table>
      ...
   </database>
     其中的"table"可理解为单个的结果集 (当数据是从数据库往XML中传输时)或则是
一个
单独的表对象或则一个可更新的视图(view)(当数据是从XML往数据库传输时)。如果数
据是
来自多个结果集的描述中(当数据来自数据库中时)或则XML的文档包含有更深层次的嵌套
元素
,有必要表现成一系列表对象 (当数据要转换到数据库中时),那么类似与上面例子那么
简单的
传输是不可能的。
     第二种普遍的数据模型是XML文档种的对象树,在这种模型下,元素通常对对应了

一个对象或则属性或则PCDATA对象。这种模型直接映射成面向对象的数据库和树状结构
数据库,
当然借助传统的对象-关系映射技术和SQL 3对象视图也可以映射成关系数据库。要注意
的是,
这种模型并不是文档对象模型(DOM),DOM是指文档本身是个模型,而不是指文档中的数
据。
    举例,在上面介绍的销售单文档可以被看成是有5个类的对象树---Orders, SalesO
rder,
Customer, Line, and Part -- 入下图所示:
                       Orders
                         |
                     SalesOrder
                    /    |    \
             Customer   Line   Line
                         |      |
                        Part   Part
    当一个XML文档模型化处理成一个对象树时,对元素和对象不需要什么特殊的要求。
例如,
如果一个元素只包含有PCDATA,例如销售单文档中的CustName元素,它能够被看做一个
属性
进行处理(就是仅仅只包含有单独的数值)。简单来说,有时将混合元素或则元素内容
模型化
处理成属性是非常有用的方法。一个现成的例子就是在销售单文档中对Description元素
的处理:
尽管它在XHTML的Form中有混合的内容,但是将description元素看作一个单独的属性来
处理会
更有用些,因为它的组成部分就本身而言没有什么意义。
4.3 数据类型, 空值(Null), 字符集设置和其他所有的类似集
    本节将探讨一些和将XML文档转换成数据库之间有关存储数据的内容。通常,你在选
择什么
样的中间件来解决这些问题的时候是不会考虑到这些问题的,但是如果你注意到这些问
题的
存在时,希望下面的讨论对与你在选择中间件时有所帮助。
4.3.1 数据类型
    XML不支持任何有意义的数据类型,除非是不能够解释的实体,所有XML文档中的数
据都被
当成文本(text)来对待,虽然它能够用其他的数据类型来表示,例如可以表示成日期
或则整数。
通常,数据转换中间件将把文本(在XML文档中的文本)转换成其它的数据类型(数据库
中的数据
类型),反之亦然。然而,一些特定的数据类型在转换的过程中是受限制的,例如受那
些提供
数据支持的JDBC驱动的限制。在这些众多的有可能的数据类型中,日期类型通常会导致
麻烦。
数字,特别是由于国际地域不同的数字格式,也可能导致问题。
4.3.2 二进制数据
    有两种比较普遍的方法将二进制数据保存到XML文档中:对实体不做任何编码处理和
对实体
进行Base64编码处理(一种MIME编码方法,可以将二进制数据影射成US-ASCII的子集)。
对于关系
数据库,这两种方法都被证明是有可能存在问题的,因为大家都知道当保存和获取二进
制数据到数据库
中的规则是非常严格的,这样对中间件将有可能导致问题。另外,并没有一种标准的符
号用来
说明一个XML文档中的元素包含有Base64编码数据,从而中间件可能根本就不能够识别这
种编码。
最后,还有可能有些中间件在将数据存储入数据库的过程中根本就会忽略没有编码实体
中的符号
或则Base64编码中的元素。所以,如果对你而言,二进制数据非常重要的话,请千万要
确认你的
中间件是否支持二进制数据。
4.3.3 空值(Null)
    在数据库世界中,null数据意味着数据不在那。这不同与一个值为0(对数字类型数
据)或则
长度为0(对字符串类型)。例如,假设你的数据是收集自一个气象站, 如果气象站的温
度计出
毛病了,那么你的数据库中将存储一个null值而不是一个0,值为0完全是另外一回事了

    XML也支持空值的概念,可以通过设置元素的类型和属性来实现。如果元素类型或属
性的
值为null,XML的处理方法是简单地不将其包含到文档中。但是对数据库来说,空的元素
或则
包含0长度字符串的属性并不意味着null:他们的值是长度为0的字符串。
    当将一个XML文档结构映射成数据库或则反过程中,你必须特别注意那些可选的数据
类型
和本来表示空值的属性。如果不这么做的话,结果将是可能出现插入错误(当将数据转换
到数据库
中时)或则非法文档错误(当将数据从数据库读出时)。
    因为XML中相对与数据库而言在对符号意义的申明有更好的灵活性 --- 具体来说,
就是XML
用户愿意将空元素或则包含长度为0内容的属性认为是"null" -- 你必须根据这个考虑选
择什么
样的中间件来处理这个问题。一些中间件提供给用户自定义在XML文档中什么标志是表示
"null"的。
4.3.4 字符集设置
    根据定义,一个XML文档能够包含任何Unicode字符,除了一些特殊的控制字符。但
是不幸
的是,许多数据库都限制或则不支持Unicode并且需要一些特殊的配置才能够处理非ASC
II 编码的
数据字符。如果你的数据包含有非ASCII字符,那么请确保你的数据库和中间件是否能够
处理这些
字符集。
4.3.5 处理指令(Processing Instructions)
    处理指令不是XML文档中的“数据”部分,目前许多中间件都不能够正常的处理它们

问题是这样的,尤其是在一个严格的将XML文档结构映射成数据库结构中,处理指令通常

很难处理的,因为题目可以出现在文档的任何位置,于是,中间件就非常困难的需要判

将它们保存到什么位置和读取的时候取回到什么位置。如果处理指令和文挡的"round-t
ripping"
对你而言是非常重要的话,你就必须确保你选择的中间件能够处理这个问题。
4.3.6 存储标志(Storing Markup)
    在4.2.2小节中提到,有时候直接将包含有元素或则混合内容的元素不进行进一步的
解析
直接保存到数据库中是非常有用的。最普遍的实现方法是简单的把这个标志本身直接保
存到
数据库中。不幸的是,这将带来另外一个问题,当从数据库中读取这些数据时:将很难
判断数据库
中的标志到底是真是假,特别是一些由lt和gt转义的字符。
    例如下面的描述:
   <description>
      <b>Confusing example:</b> &lt;foo/&gt;
   </description>
   保存到数据库中将变成这样:
   <b>Confusing example:</b> <foo/>
   这时数据库将不能够判断<b>和<foo>是标志还是文本了。解决方法有以下几种,例如

标志的符号使用其它非标志符号替代,但是这时你要非常的小心,因为也许别的运用程
序在
使用这些数据时就会出现不兼容的现象。例如,如果你想查询数据库中的小于号("<")和

lt标志("&lt;")时就要特别小心了。
4.4 从数据库的结构生成DTDs和逆反过程
      在XML文档和数据库之间转换数据的一个普遍问题是:如何从数据库的结构生成D
TDs
和其逆反过程。简而言之,目前有许多软件都提供了可以直接使用的操作功能,但是它
产生的
结果对许多用户来说用处和帮助不大,也许没有多少人喜欢。
    例如,下面的过程(已经简化过的)就是从一个XML文档到关系数据库中生成DTD的

    对每一种包含有元素或则混合内容的元素类型,新建立一个table和一个主关键字段

    对混合内容种的每一个元素,建立一个分开的table,在其中保存PCDATA,通过主关键
字连接
到父表中。
    对于元素类型中每个有单一数值的属性和只包含有PCDATA内容的子元素类型在该ta
ble中
新建立一列(字段)。如果子元素类型或则属性是可选的,让该字段允许为空。
    对于每个有多值的属性或则多仅含有PCDATA内容的子元素类型,再建立一个分开的
table
来保存他们的值,通过它们的父表的主关键字连接到父表。
    对于每个子元素,这些子元素本身还有元素或则混合内容,使用父表中的关键字将
父元素表
连接到子元素表中。
    而下面则是一个从关系数据库的结构生成XML文档的过程(简化过的):
    对每个table,新建一个元素。
    对表中的每列,建立一个属性或则只含PCDATA的子元素
    对每个包含有在主键/外键关键字关系中主键值的列,新建一个子元素。
    不幸的是,在这些过程中存在许多缺陷。例如,其中没有实现对数据类型的预先定

和在DTD中没有实现对列长度的预先定义的方法。因为任何的预先定义,例如通过读一个
示例
文档,当读取其他“类型”的文档或则其他文档中包含有超过字段长度内容的文档时,
就会发生
错误。(解决这个问题的办法时使用XML schema文档中数据类型定义)简单来说,当从一
个关系
结构中生成DTD时,是没有办法预先判断子元素“应该”出现的顺序或则类似数据库中的
行标识。
    尽管有这些陷,根据数据库结构生成DTDs的软件能够给我们带来了一个很好的开端
,特别
是对与那些非常庞大和复杂的系统。

--

※ 来源:·BBS 水木清华站 smth.org·[FROM: 202.112.137.7]
※ 修改:·Sage 於 Sep 12 11:45:42 修改本文·[FROM: 192.168.18.238]
--
※ 转载:·BBS 荔园晨风站 bbs.szu.edu.cn·[FROM: 192.168.18.238]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店