【问题标题】:How to design many-to-many relationships in an object database?如何在对象数据库中设计多对多关系?
【发布时间】:2010-11-07 08:07:42
【问题描述】:

我认为是时候看看 OO 数据库了,因此决定将 db4o 用于我的下一个小项目 - 一个小型库。

考虑以下对象:书籍、类别。

一本书可以属于 0-n 个类别,一个类别可以应用于 0-m 本书。

我的第一个想法是有一个连接对象,例如 BookCatecory,但经过一番谷歌搜索后,我发现这不适合“真正的 OO”。

所以另一种方法(许多人推荐)是在两个对象中都有一个列表:Book.categories 和 Category.books。一方面处理关系:Book.addCategory 将 Category 添加到 Book.categories 并将 Book 添加到 Category.books。在一个方法调用中更改 2 个对象时如何处理提交和回滚?

你的想法是什么?第二种方法具有明显的优势,但至少对我来说,第一种“感觉”是正确的(更好的规范)。

【问题讨论】:

    标签: oop db4o object-oriented-database


    【解决方案1】:

    如果您使用对象数据库,则无需关心关系是如何存储在数据库中的。您定义类和它们之间的关系。请阅读您的数据库的参考指南。关系示例:

    n:n attribute, referencing from the parent
    ------------------------------------------------------------------
    class Person {
        List addresses;
    }
    
    class Address {
    }
    
    
    n:n attribute, referencing from the child
    ------------------------------------------------------------------
    class Person {
    }
    
    class Address {
        List persons
    }
    
    n:n attribute, bidirectional references
    ------------------------------------------------------------------
    class Person {
        List addresses;
    }
    
    class Address {
        List persons
    }
    

    【讨论】:

      【解决方案2】:

      我真的只有两种方法可以解决这个问题,你已经提到了这两种方法。就个人而言,我会采用第一种方法(将映射对象创建为 OO 实体)。这可以防止您保留冗余信息并且必须同步;这也意味着,如果协会最终拥有自己的字段(比如说,书籍被分配到该类别的日期),它们可以很容易地合并。我们将这种方法用于我们系统中的各种关联。

      OO 实体如下所示:

      BookCategory {
       Book book
       Category category
      }
      Book {
       Collection <BookCategory> categories
      }
      Category {
       Collection <BookCategory> categories
      }
      

      这里你必须保持关系对象和两个集合同步;但是,在这种情况下,集合是可选的。通常,您可以使用 ORM 查询获得相同的信息,例如: 从 BookCategory b 中选择 b.book 其中 b.category = MyCategory

      另一种方法是进行如下设置:

      Book {
       Collection<Category> categories
      }
      
      Category {
       Collection<Books> books
      }
      

      如果您的 ORM/DB 工具自动维护关联,这很好;否则,您将无法更新这两个集合。 (在 Hibernate 中,一侧将在映射上具有属性:inverse=true;这一侧未更新,因此严格来说不需要维护。不过,在我看来,这似乎是一种不好的做法。)

      如果您通常仅以一种方式访问​​关系(例如,获取一个类别中的所有书籍),则可以消除另一侧的集合;那么我认为您必须使用 ORM 工具并使用本机查询才能从另一个方向访问关系。

      我们在项目中使用 Hibernate(一种基于 java 的对象关系映射工具); Hibernate 文档是 OO/关系设计问题的一个很好的参考,尽管您可能需要花一点时间学习 Hibernate 以使其有用: http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/#collections-ofvalues

      HTH!

      【讨论】:

      • 我应该提到我对db40不熟悉;这个答案一般适用于您所描述的 ORM 问题,我希望 =)
      【解决方案3】:

      我会避免数据重复,因为在合并差异时会遇到各种问题。

      诀窍在于引用。

      结果是我将让每个对象都包含对其他对象类型的引用的集合,以及拥有其他对象的独立集合。

      匹配表是一个关系概念,除非该中间连接类可能具有不属于任何一个对象的属性。它在那里,因为它使查询能够以强大的方式编写,因为它将关系减少到 2 个一对多关系并大大减少了数据重复。如果您在没有匹配表的关系数据库中执行此操作,那么事情会很快变得糟糕 - 更新将如何操作?就我个人而言,我发现 oo 数据库的吸引力正在远离这一点

      我将所有对象绑定在一起的方式是通过代码中的事件到某种事务处理程序,以允许缓存对象状态。因此,它们不是通过处理程序请求更改并在回调中等待结果,而不是对象相互操纵其他属性。

      【讨论】:

        【解决方案4】:

        您有什么特别的原因想要使用 ODBMS?对于简单的数据结构(例如对书籍进行分类),您通常不会发现 ODBMS 比 RDBMS 有任何优势,事实上,在更加标准化的 RDBMS 世界中工作会更容易。当您处理复杂的数据类型或动态对象的字面持久性/存储时,ODBMS 具有非常明显的优势。 ODBMS 也被认为比 RDBMS 更快且更具可扩展性,尽管我自己对此几乎没有什么见解。但是,这里有几页讨论 RDBMS 与 ODBMS:

        Whatever Happened to Object-Oriented Databases

        Object-Oriented Database vs. Object-Rleational Database (SO)

        【讨论】:

        • 我想看看我是否可以避免创建 dbschema、创建表、创建对象、将表映射到对象等。似乎 odbms 可以省去很多笨重的工作。 ..
        • 它可能会减少一些工作,但体面的 ORM 层也会如此。我并不是说 ODBMS 是错误的选择,但有一些替代方案可能对您同样有效或更好。
        【解决方案5】:

        在诸如 GemStone 之类的纯 OO 数据库中,对象本身具有对其他对象的引用集合。当从应用程序引用对象时,OODBMS 会生成一个包装该对象的代理。这个模式只是持久化的对象及其对它所引用的对象的引用集合。 OODBMS 不一定需要链接实体。

        使用 O/R 映射层(假设它足够聪明地处理 M:M 关系),M:M 关系表现为对象本身的附属引用的集合,O/R 映射器将其解析为链接幕后的实体。并非所有的 O/R 映射器都这样做,因此您可能有一个单独的链接对象。

        【讨论】:

          【解决方案6】:

          我认为您只是有点沉迷于关系数据库的思维方式。每个对象中的列表是正确的 OO 事情。提交和回滚没有问题,它们发生在提交所有内容或回滚所有内容的事务中。

          【讨论】:

            猜你喜欢
            • 2012-09-30
            • 2011-05-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-13
            • 2011-08-23
            相关资源
            最近更新 更多