V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
huanglk
V2EX  ›  编程

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

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

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

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

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

    级联删除一般自己使用事务处理。
    JamesRuan
        4
    JamesRuan  
       2014-11-15 08:23:05 +08:00 via Android
    缺乏数据库知识的表现,这类问题前人早就思考过了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1743 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 16:40 · PVG 00:40 · LAX 08:40 · JFK 11:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.