对象/模型之间的关联大家都是怎么处理的?“双向关联”和“单向关联”的选择问题。

2014-11-14 21:42:17 +08:00
 huanglk
今天看《重构》一书说到“双向关联”和“单向关联”的转换。
比如`Customer`和`Order`之间的关系,很多时候我们需要根据Customer来对相关的orders做操作(增删查改),很直接的做法是在Customer里直接添加一个字段来保存一个list或者set,这就形成一个单向关联的关系了。之后如果又需要根据Order来获取对应的customer的话,一般你们会怎么选择?在Order里面增加一个字段来保存?还是以性能为代价,设置一个getCustomer()函数来遍历所有的customers并返回符合要求的customer?
这类问题我之前第一次独自做web后台模型层时自己把自己绕晕了,因为用了双向关联,而且字段都存了ID,没有用SQL的外键(不太希望数据库帮自己做一些自己还不是很了解的事情),最终导致各种不一致,比如删除一个customer没有删除对应的orders等低级问题,而且最后解决这些问题也是很痛苦的过程,这或许也是我想看《重构》这类书的原因之一,但还是觉得自己的变成经验还是太少了,只一两个做过小型网站,所以感觉自己对这一块的思想还不是很清晰,请大家多多指教~
3910 次点击
所在节点    编程
4 条回复
meta
2014-11-14 21:51:09 +08:00
一个订单难道不是只能有一个客户吗,如果一个订单都有多个客户了,那么这不形成一个多对多关系了吗,这种多对多的关系显然应该拆成两个一对多关系嘛。另外,本身关系数据库处理这种事情就比较麻烦的,所以现在大家不都nosql了吗。
incompatible
2014-11-14 21:54:23 +08:00
个人愚见:
Customer中没有必要保存List<Order> 不然莫非List<Address> List<Favorite>这些都要各存一份?
通常只要提供OrderService.listOrderOfCustomer(customerId)这种服务就够了

关于你的不一致的问题:
不知你使用的是什么语言及orm工具。一些orm工具是可以支持级联删除的
我自己在这种场景下通常不依赖数据库外键或orm工具,在一个事务中先后做删除Customer和Order的操作即可
huijiewei
2014-11-15 00:03:03 +08:00
为什么要在 Customer 里面保存 Order 的关联?

按照一般业务逻辑,一个订单肯定属于一个用户的,一个用户可以有多个订单,那么这就是一对多关系,一对多关系,应该在“多”的那个实体上存储“一”的关联。

多对多关系的话,应该建立一个关联表来进行关联。

一对一,一对多,多对多这种关联是很基础的,不管是关系型数据库还是 NoSQL 处理起来都是非常成熟了。

级联删除一般自己使用事务处理。
JamesRuan
2014-11-15 08:23:05 +08:00
缺乏数据库知识的表现,这类问题前人早就思考过了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/146615

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX