Yiwei's profile我以维的世界PhotosBlogLists Tools Help

Blog


    April 02

    从DTD到数据库的映射——3

    1.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文档与关系型数据库间转换数据时,并不需要实例化对象。(这并不意味着对象不能被实例化。是否需要实例化对象具体要视实际应用而定。)

    Comments

    Please wait...
    Sorry, the comment you entered is too long. Please shorten it.
    You didn't enter anything. Please try again.
    Sorry, we can't add your comment right now. Please try again later.
    To add a comment, you need permission from your parent. Ask for permission
    Your parent has turned off comments.
    Sorry, we can't delete your comment right now. Please try again later.
    You've exceeded the maximum number of comments that can be left in one day. Please try again in 24 hours.
    Your account has had the ability to leave comments disabled because our systems indicate that you may be spamming other users. If you believe that your account has been disabled in error please contact Windows Live support.
    Complete the security check below to finish leaving your comment.
    The characters you type in the security check must match the characters in the picture or audio.

    To add a comment, sign in with your Windows Live ID (if you use Hotmail, Messenger, or Xbox LIVE, you have a Windows Live ID). Sign in


    Don't have a Windows Live ID? Sign up

    Trackbacks

    The trackback URL for this entry is:
    http://vane-zhang.spaces.live.com/blog/cns!15C6882C30119870!302.trak
    Weblogs that reference this entry
    • None