`

关于为什么单向一对多(one-to-many)要使用关联表的再思考

 
阅读更多

在传统的数据建模中,允许为 Null 值的外键被认为是一种不好的实践,。这并不是 Hibernate的要求.---Hibernate文档

 

2013年1月29日:补充:

简单地说,数据库的外键关联描述的最严格与最精准的物关系应该是像“子-父这样的单向多对一关系,也即,“子”必有“父”!而反方向的一对多的关系并不是其所能准确描述,原因就是“父”未必有“子”,所以从这个角度上说,使用关联表描述单向一对多是更加贴切的。

 

我在Hibernate2010年的笔记中对为什么单向一对多(one-to-many)的映射要使用关联表做过讨论,但是我觉得那时候的认识并不深刻,也不太具有说服力,今天我有了进一步的思考。

首先必须明确,一对一,一对多或者多对多都是领域对象间的关系,它们体现的是业务层面上各种事物之间的对应关系。这些对应关系与数据库上的外键关联是有本质区别的。但是当我们需要持久化这些数据时,又必须要把它们之间的这些关系以数据库方式保存起来,或者说是以数据库的方式对这些关系进行模拟。很显然,可供我们使用的方式无非就是外键关联和关联表。

我们先来看外键关联:

在所有对象关系中双向一对多也就是最最典型的“父子关系”(注意,严格来说父子关系和双向一对多多对一关系是有一点差别的,那就是父子关系中要求子是一定有父的,而单向多对一中并没有明确要求一方是一定存在的,这个我在后面会再细说)使用外键关联是最贴切的!

外键关联是两张表级别上的关联关系,这里有一个暗含的要求,那就是两张表的全部记录应该都满足这种约束才对(像在父子关系中,子一定有父一样!)。虽然这不是必须的。因为一旦我们允许外键列为空就会使得一些数据可以不受此外键约束,这于我们设置外键关联的初衷就背道而驰了。从一对多的语义上来看,它只期望从单端能够找到一组多端对象,至于多端对象是不是都有一个对应的单端对象,是不再其关心或者表述范围之内的。显然,要实现这种语义,必须置多端对象的外键为可空,来放宽于约束。从数据库设计的角度来看,外键为空是一种不好的设计,而使用关联表则可以避开这个问题。我们可以看到关联表允许我们只是对两表之间的“部分”数据间的关系进行表达。它们这种关系并不是表级别的,也就是说并不是每条记录都有这种关系,这比使用允许外联列为空的外键约束要自然和合理。

由此我想,是不是对于单向多对一(many-to-one)来说,如果它对应的那个one不是必须有的时候,那我们是不是也不应该使用外键关联呢?我想答案是肯定的。

最后再简明的把这个问题描述一下:

因为单向一对多关系中对many方与one方之间的关系没有相关的描述,many方可能有对应的one方也可能没有,在这种情况下使用外键约束是不合适的。而使用关联表的好处就在于可以“规避”这个问题,也就是不正面回应这个问题。因为单向一对多关系本身就不关心这个问题。

分享到:
评论

相关推荐

    Hibernate_Annotation关联映射

    通过联接表来建立单向一对多关联不需要描述任何物理映像,表名由以下三个部分组成:主表(ownertable)表名+从表(the other side table)表名,指向主表的外键名:主表表名+下划线+主表主键列名,指向从表的外键名:主...

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联...

    HibernateAPI中文版.chm

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联...

    hibernate3.2中文文档(chm格式)

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联...

    Hibernate3的帮助文档

    7.2.5. 一对多关联(One-to-many Associations) 7.3. 高级集合映射(Advanced collection mappings) 7.3.1. 有序集合(Sorted collections) 7.3.2. 双向关联(Bidirectional associations) 7.3.3. 三重关联...

    Hibernate中文详细学习文档

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联...

    hibernate 框架详解

    一对多关联(One-to-many Associations) 7.3. 高级集合映射(Advanced collection mappings) 7.3.1. 有序集合(Sorted collections) 7.3.2. 双向关联(Bidirectional associations) 7.3.3. 三重关联...

    Hibernate 中文 html 帮助文档

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联,...

    hibernate 体系结构与配置 参考文档(html)

    一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联,涉及...

    最全Hibernate 参考文档

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 三重关联...

    Hibernate+中文文档

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联...

    hibernate3.04中文文档.chm

    7.2.5. 一对多关联(One-to-many Associations) 7.3. 高级集合映射(Advanced collection mappings) 7.3.1. 有序集合(Sorted collections) 7.3.2. 双向关联(Bidirectional associations) 7.3.3. 三重关联...

    Hibernate教程

    7.2.5. 一对多关联(One-to-many Associations) 7.3. 高级集合映射(Advanced collection mappings) 7.3.1. 有序集合(Sorted collections) 7.3.2. 双向关联(Bidirectional associations) 7.3.3. 三重关联...

    Hibernate3+中文参考文档

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 三重关联...

    Hibernate参考文档

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联,...

    jdbc基础和参考

    单向的一对多的关系,在进行关联关系的操作时,会执行不必要的update语句,所以,一般情况下,我们不会做单向一对多的映射。 inverse="true":让其中一方放弃对关联关系的维护 一般在做双向多对一(一对多)关联关系...

    hibernate_reference中文文档.pdf

    1.2.2. 单向 Set-based 的关联 ......................................... 14 1.2.3. 使关联工作 ..................................................... 15 1.2.4. 值类型的集合 ..................................

    Spring面试题

    类与类之间的关系主要体现在表与表之间的关系进行操作,它们都市对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配置文件中的many-to-one、one-to-many、many-to-many、 4. 说下Hibernate的缓存...

    精通hibernate:对象持久化技术孙卫琴第二版part2

    7.1.1 [many-to-one]元素的not-null属性 153 7.1.2 级联保存和更新 155 7.2 映射一对多双向关联关系 156 7.2.1 [set]元素的inverse属性 161 7.2.2 级联删除 163 7.2.3 父子关系 164 7.3 映射一对多双向自身...

    精通Hibernate:对象持久化技术第二版part3

    7.1.1 [many-to-one]元素的not-null属性 153 7.1.2 级联保存和更新 155 7.2 映射一对多双向关联关系 156 7.2.1 [set]元素的inverse属性 161 7.2.2 级联删除 163 7.2.3 父子关系 164 7.3 映射一对多双向自身...

Global site tag (gtag.js) - Google Analytics