| Yiwei's profile我以维的世界PhotosBlogLists | Help |
|
April 02 从DTD到数据库的映射——31.1.1. 从对象模式到数据库模式的映射 对象关系型映射的第二部分中,类被映射为基本表(称之为类表),标量属性被映射为列,指针与索引属性被映射为主/外键关系。例如: Classes Tables ============ ================= class A { Table A: String b; Column b C c; ==> Column c_fk String f; Column f }
class C { Table C: String d; ==> Column d String e; Column e } Column c_pk 我们注意到上面的基本表由主键(C.c_pk)和外键(A.c_fk)连接。由于主元素与子元素间的关系是一对一的,所以主键也可以映射到任一基本表中。如果二者关系是一对多的,主键必须在两表中的“一个”中,无论其是否为子元素或父元素。例如,如果SalesOrder元素含有复合的Item元素,那么主键必须映射到SalesOrder(父元素)表中。但是如果每个Item元素含有一个Part元素,主键必须映射到Part(子元素)表中,因为一个part元素可以出现在多个项目中。 我们在映射递归出现的元素时,可以使用主外键关系。例如,你定义了如下元素类型; <!ELEMENT A (A?, B, C)> <!ELEMENT B (#PCDATA)> <!ELEMENT C (#PCDATA)> 在这个例子中,A可以视为其自身的子元素。对A的映射,与对其他复合元素引用的映射原理一样,这里可以使用主/外键关系。在递归的情况中,唯一不同的时外键与主键指向相同的基本表。例如,元素A可以被映射为如下的类中: class A { A a; // Nullable String b; String c; } 而后,映射到如下基本表中,该基本表中a_fk为指向含有子元素A的列的外键。 Table A ======= Column a_pk Column a_fk Column b Column c 主键列的来源有二。其一,如上例所示,主键可以视为映射的一部分。其二,已存在的一列或几列可以被视为主键。例如,若SalesOrder元素类型含有一个子元素Number,该元素类型可以被映射为主键列。 若主键列被创建为映射的一部分,他的值必须由数据库或数据转换软件构造。针对这一点,更好的数据库设计方案取代了用数据列作为主键,但在使用XML时仍旧存在缺陷,即,创建的关键字字段往往在源数据外没有具体含义。因此,当存在生成主键的数据被转换到XML文档中时,要么存在一个没有具体含义的主键(如果主键值被转换),要么根本不存在主键(如果关键字没有被转换)。在后者的情况中,重新定义源数据时不可能的,如果数据被更新并作为XML文档返回到数据库中,这将会是一个不容忽视的问题。 1.1.2. 后记 在我们讨论更加复杂的映射步骤前,我们需要提及几件事情。首先,名称在映射中可以改变。也就是说,DTD,对象模式,关系型模式均可以使用不同的名字。例如:与类相比,下面的DTD使用了不同的名字: DTD Classes =============================== ===================== <!ELEMENT Part (Number, Price)> class PartClass { <!ELEMENT Number (#PCDATA)> ==> String numberProp; <!ELEMENT Price (#PCDATA)> float priceProp; } 相对于基本表,它同样使用了不同的名字: Classes Tables ===================== ================== class PartClass { Table PRT String numberProp; ==> Column PRTNUM float priceProp; Column PRTPRICE } 其次,在应说过程中,数据类型可以被改变。即,DTD,对象模式,和数据库模式均可以使用不同的数据类型。例如,下面的DTD与相应的类相比,对Price元素使用了不同的数据类型: DTD Classes =============================== ===================== <!ELEMENT Part (Number, Price)> class Part { <!ELEMENT Number (#PCDATA)> ==> String number; <!ELEMENT Price (#PCDATA)> float price; } 与相应的基本表相比,使用了不同的数据类型: Classes Tables ===================== ================== class Part { Table Parts String number; ==> Column number VARCHAR(50) float price; Column price DECIMAL(10,2) } 这种不同所需的是数据类型间已经定义的转换规则。尽管会有精度的损失问题有限,这种做法并不值得鼓励。最后,在映射过程中引入的对象是概念层面上的。即,当在XML文档与关系型数据库间转换数据时,并不需要实例化对象。(这并不意味着对象不能被实例化。是否需要实例化对象具体要视实际应用而定。) TrackbacksThe trackback URL for this entry is: http://vane-zhang.spaces.live.com/blog/cns!15C6882C30119870!302.trak Weblogs that reference this entry
|
|
|