对象设计时如何选择“一对多”与“多对一”关系

做面向对象设计的时候,我们常常面对这样一个问题。当对象之间存在一对多关系的时候,在物理设计的时候应该选择一对多关系还是多对一关系?举例来说,假设有一个订单对象,每个订单对象对应多个订单条目。这个时候我们在设计的时候有两中选择,一种是在订单对象中加入一个订单条目集合,另外一种方法是在订单条目中引用订单对象。分别对应以下两种设计。

                     

最简单一种方法是同时保留两种关系,也就是既在订单对象中保留订单条目集合,也在订单条目上引用订单对象。这也是很多根据数据库生成对象模型的工具的默认选择。但是这样做存在一个性能问题,很多OR Mapping的工具在保存具有一对多关系的对象时,都会将“多方”的对象每个都重新保存一遍(以Nhibernate为例,如果订单对象引用了订单条目对象的集合,那么如果在保存订单对象时,订单对象是脱钩对象,Nhibernate会把所有订单条目对象重新保存一遍)。

从上面的例子可以看到,使用一对多关系在很多情况下,在很多情况下都会引入性能问题。那是不是可以说在做对象设计的时候不要使用一对多关系,每次仅使用多对一关系就可以了呢?答案当然是不。那什么时候可以使用一对多关系呢?主要有两中情况,第一种情况是,一对多关系中的多方在保存时需要参照多方中其它的对象,才可以确认是不是可以保存。还是以订单对象为例,假设订单条目对象有一个金额,如果每个订单下的订单条目金额的总和不能超过一个特定的值,这种情况下一定要使用一对多关系。因为单独看一个订单条目的情况无法确认该订单条目是否可以保存,而每次保存都把和该订单条目在同一订单下的所有订单条目读出来,而且还要避免保存冲突问题需要大量的代码,这种情况下就不如使用一对多关系了。另外一种情况相对比较少见,那就是多方的对象直接的顺序有严格的要求,这种情况也必须使用一对多关系。这种情况在开发工作流设计器时经常会出现,每个工作流会有多个活动,而活动的执行顺序是一个很重要的属性,如果出现问题会导致工作流整体执行的异常。必须保证工作流与工作流活动的每次保存都是整体保存,如果两个人同时保存了一个工作流,即便保存的是不同的活动,只要调整了活动的顺序,都可能会让整个工作流的执行顺序出现异常,这种情况下最好也是使用一对多关系。

时间: 2024-07-29 03:08:06

对象设计时如何选择“一对多”与“多对一”关系的相关文章

数据库中根据数据一对一,一对多,多对多关系设计

做一个项目,必然是少不了数据库设计的!在学习阶段,基本都是单表.然而在实际开发过程中,一对多,多对多的表处处都是!简单整理一下,一对多,多对多表如何设计整理一下思路: 数据库实体间有三种对应关系:一对一,一对多,多对多. 一对一关系示例: 一个学生对应一个学生档案材料,或者每个人都有唯一的身份证编号. 一对多关系示例: 一个学生只属于一个班,但是一个班级有多名学生. 多对多关系示例: 一个学生可以选择多门课,一门课也有多名学生. 1.一对多关系处理: 通过学生和班级问题了解一对多: 设计数据库表

Hibernate中一对多和多对一关系

1.单向多对一和双向多对一的区别? 只需要从一方获取另一方的数据时 就使用单向关联双方都需要获取对方数据时 就使用双向关系 部门--人员 使用人员时如果只需要获取对应部门信息(user.getdeptarment())不需要 从部门下的人员信息时,就配置成单向 多对一 使用部门时如果只需要获取部门下人员信息(deptartmanet.getusers())不需要 从人员获取部门信息时,就配置成单向 一对多 既要获取部门下人员 deptartmanet.getusers()又要从人员获取部门信息

Django 一对多,多对多关系解析

[转]Django 一对多,多对多关系解析 Django 的 ORM 有多种关系:一对一,多对一,多对多. 各自定义的方式为 : 一对一: OneToOneField 多对一: ForeignKey 多对多: ManyToManyField 上边的描述太过数据而缺乏人性化,我们来更人性化一些: 多个属于一个,即 belong to :  ForeignKey,多个属于一个 一个有一个,即 has one: OneToOneField 一个有很多个,即 has many:  lots of A b

JPA一对多和多对一关系

1-m:多的一方为关系维护端,关系维护端负责外键纪录的更新,关系被维护端没有权力更新外键纪录. 维护端注解 Java代码   @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE, CascadeType.REMOVE }, fetch = FetchType.EAGER, mappedBy = "order") 被维护端注解 Java代码   @ManyToOne(casc

数据库一对一、一对多、多对多关系

数据库一对一.一对多.多对多关系 一.首先给出三种关系的实例 一对一关系实例 ? 一个人对应一张身份证,一张身份证对应一个人 一对多关系实例 ? 一个公司的部门拥有多个职员,一个职员只能够属于某个部门 多对多实例 ? 一本图示可以拥有多个作者,一个作者可以写很多本书. 一对一关系 一对多,是最常见的一种设计.就是 A 表的一条记录,对应 B 表的多条记录,且 A 的主键作为 B 表的外键.这主要看以哪张表为中心. 优点 便于管理.可提高一定的查询速度 减轻 CPU 的 IO 读写,提高存取效率.

EF里一对一、一对多、多对多关系的配置和级联删除

      参考 EF里一对一.一对多.多对多关系的配置和级联删除 EF里的默认映射以及如何使用Data Annotations和Fluent API配置数据库的映射

Hibernate入门(三)—— 一对多、多对多关系

一.一对多关系 1.概念 ? 一对多关系是关系型数据库中两个表之间的一种关系.通常在数据库层级中,两表之间是有主外键关系的.在ORM中,如何通过对象描述表之间的关系,是ORM核心. 2.Hibernate的一对多关联映射[重点] 2.1表关系的分析 MySql语句 CREATE TABLE `t_category` ( `cid` int(11) NOT NULL AUTO_INCREMENT, `cname` varchar(255) DEFAULT NULL, PRIMARY KEY (`c

Hibernate自身一对多和多对多关系映射

一对多关系映射大家都明白,关系双方都一个含有对方多个引用,但自身一对多很多同学都不明白什么意思,那么首先我就说明一下什么是自身一对多,其实也很好理解,自身一对多就是自身含有本身的多个引用,例如新闻类别,新闻包含体育新闻和政治新闻,体育新闻内有含有足球新闻和篮球新闻,其实他们都属于新闻,只是名字不同而已,下面我们就以新闻类别为例来具体说明一下: 首先我们来看一下新闻类别的类图: 类图:category 从上面的图我们可以看出:每一个新闻类别都有一个父类别和一个孩子类别的set集合,这个父类别和孩子

jango 模型管理数据model,数据库外键主键与一对一,一对多,多对多关系

四.models.py 定义和管理模型: 4.1模型class的属性就映射与数据库的字段参数 继承models.Model class TestClass(models.Model): 4.2在数据库生成数据表: #django默认在makemigrations会为表对象创建主键id,id = models.AutoField(primary_key=True) 你也可以自定义一个主键对象: 4.2.1: 生成迁移文件python manage.py makemigrations 4.2.2执行