文档章节

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

猪刚烈
 猪刚烈
发布于 2014/10/12 11:40
字数 1034
阅读 6
收藏 0

 

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


2013年1月29日:补充:

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

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

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

我们先来看外键关联:

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

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

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

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

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

本文转载自:http://blog.csdn.net/bluishglc/article/details/5550251

共有 人打赏支持
猪刚烈
粉丝 22
博文 708
码字总数 110
作品 1
海淀
程序员
私信 提问
@OneToMany、@ManyToOne以及@ManyToMany讲解

一、一对多(@OneToMany) 1、单向一对多模型 假设通过一个客户实体可以获得多个地址信息。 对于一对多的实体关系而言,表结构有两种设计策略,分别是外键关联和表关联。 (1) 映射策略---外键...

gxchan
2015/12/23
249
0
@OneToMany、@ManyToOne以及@ManyToMany讲解(五)

一、一对多(@OneToMany) 1、单向一对多模型 假设通过一个客户实体可以获得多个地址信息。 对于一对多的实体关系而言,表结构有两种设计策略,分别是外键关联和表关联。 (1) 映射策略---外键...

半夏alvin
2012/11/27
0
2
Java程序员从笨鸟到菜鸟之(五十四)细谈Hibernate(五)Hibernate一对多关系映射

前几篇系列博客: 细谈Hibernate(一)hibernate基本概念和体系结构 细谈Hibernate(二)开发第一个hibernate基本详解 细谈Hibernate(三)Hibernate常用API详解及源码分析 细谈Hibernate(四...

长平狐
2012/11/12
457
0
JPA实体关系映射:@ManyToMany多对多关系、@OneToMany@ManyToOne一对多多对一关系和@OneToOne的深度实例解析。

本文由作者三汪首发于简书。 为什么要有实体关系映射 答:简化编程操作。把冗余的操作交给底层框架来处理。 例如,如果我要给一位新入学的学生添加一位新的老师。而这个老师又是新来的,在学...

三汪
2017/08/01
0
0
Hibernate一对多、多对多、一对一关联映射方法

对象之间的关系:关系映射之间的关系只的是对象之间的关系,并不指数据库表的关系(外键关系),当然,数据库表该如何映射,编程上如何实现这两件事密不可分。 1、对象之间的关联关系: 一对多...

ifnotme
2016/08/02
139
0

没有更多内容

加载失败,请刷新页面

加载更多

java框架学习日志-7(静态代理和JDK代理)

静态代理 我们平时去餐厅吃饭,不是直接告诉厨师做什么菜的,而是先告诉服务员点什么菜,然后由服务员传到给厨师,相当于服务员是厨师的代理,我们通过代理让厨师炒菜,这就是代理模式。代理...

白话
今天
21
0
Flink Window

1.Flink窗口 Window Assigner分配器。 窗口可以是时间驱动的(Time Window,例如:每30秒钟),也可以是数据驱动的(Count Window,例如:每一百个元素)。 一种经典的窗口分类可以分成: 翻...

满小茂
今天
15
0
my.ini

1

architect刘源源
今天
14
0
docker dns

There is a opensource application that solves this issue, it's called DNS Proxy Server It's a DNS server that solves containers hostnames, if could not found a hostname that mat......

kut
今天
15
0
寻找数学的广度——《这才是数学》读书笔记2700字

寻找数学的广度——《这才是数学》读书笔记2700字: 文|程哲。数学学习方式之广:国内外数学教育方面的专家,进行了很多种不同的数学学习方式尝试,如数学绘本、数学游戏、数学实验、数学步道...

原创小博客
今天
26
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部