随着PHP开发框架的普及,越来越多的开发者开始使用ORM进行数据库的操作。
在使用ORM时,数据表间关系的设置往往被很多开发者忽略。
数据表间关系,主要有四种:
- 一对一关系(has one)
- 一对多关系(has many)
- 多对多关系(many to many)
- 从属关系(belongs to)
本文主要讨论一对一关系与从属关系的区别。
一对一关系(has one)
用于主表的定义中,指主表(primary table)每行记录,在从表(foreign table)中只有一行记录对应。
从属关系(belongs to)
用于从表的定义中,指从表(foreign table)中的每行记录,在主表(primary table)中都有一行记录对应。
一对一关系(has one)与从属关系(belongs to)的注意点
从定义上来看,一对一关系与从属关系貌似是一对互反的关系。但请注意以下事实:
- 一对一关系是一对多关系的特殊情况
- 一对多关系与从属关系是互反关系
- 一张表可以设置多个一对多关系
- 一张表可以设置多个从属关系
一对一关系(has one)与从属关系(belongs to)的差别
让我们用一个实例来了解这些关系。以下几张数据表组成了一个简单的博客系统:
- 用户表(users)
- 用户资料表(user_profiles)
- 博文表(blogs)
- 博文分类表(categories)
让我们来建立关系吧
- users
- has one
- user_profiles
- has many
- blogs
- has one
- user_profiles
- belongs to
- users
- belongs to
- blogs
- belongs to
- categories
- users
- belongs to
- categories
- has many
- blogs
- has many
现在,通过强大的ORM系统,我们可以对这几张表进行方便的操作:当读取users表时,相应记录在user_profiles的记录将被读出;当读取blogs表时,不但有其分类的信息,还有作者的信息。
既然has one与belongs to在读取时都能将关联表的信息提出,并且都是提出一条信息(不像has many需要用数组来存储关联记录),那两者到底有何区别呢?
Hackfan认为,两者的区别主要在于逻辑与删除操作的处理上。
逻辑差别
has one表示拥有,belongs to表示属于。因此,A has one B(或B belongs to A),A是根本,B是果实;A是皮,B是毛。有了A,才可能有B;有B,那一定会有A。两者虽然在读取操作时,有一致的逻辑,但是在删除操作上,逻辑就有所区别。
删除操作处理差别
假设A has one B(或B belongs to A),在删除A中记录时,应当删除B中相应的记录;在删除B中记录时,不需要删除A中相应记录。
比如users与user_profiles,当某个用户的帐户被删除时,帐户资料理所应当也应该被删除;而帐户资料被删除时,帐户未必需要被删除。
再比如blogs表。当一篇博文被删除时,其所属的分类、所属的用户,未必需要被删除。但当某个用户被删除,或者是某个分类被删除时,这篇博文往往需要被删除。
从以上两个案例,可以看出has one与belongs to的差别。目前许多ORM在进行关系表记录删除时,并未按照以上逻辑进行操作,也是希望将操作空间最大的留给开发者。
总结
慎用has one与belongs to关系定义,虽说在实际开发时区别不大,甚至可以达到一致的效果,但是两者在逻辑上的区别是十分大的。混淆使用两者将被视为对表关系概念的不理解。在复杂的数据表系统中,混淆使用两者,将会给其他开发者造成理解上的困惑。
同时,当更为自动化的ORM系统出现时,has one与belongs to的错用可能将在数据删除时,产生严重的错误。
因此,请慎用has one与belongs to关系定义。
标签:belongs to, has one, ORM, PHP, 一对一关系, 从属关系