ORM中,belongs to与has one的区别

2010年2月18日 由 Hackfan | 有 452 人次阅读 留言 »

随着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
  • user_profiles
    • belongs to
      • users
  • blogs
    • belongs to
      • categories
      • users
  • categories
    • has many
      • blogs

现在,通过强大的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关系定义。

标签:, , , , ,

相关日志

留下评论