如何在对象数据库中设计多对多关系?

时间:2009-07-01 13:36:03

标签: oop db4o object-oriented-database

我认为现在是时候看看OO数据库并决定将db4o用于我的下一个小项目 - 一个小型库。

考虑以下对象:Book,Category。

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

我的第一个想法是拥有一个像BookCatecory这样的连接对象,但经过一些谷歌搜索后,我发现这不适合'真实的OO'。

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

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

6 个答案:

答案 0 :(得分:8)

我真的只有两种方法可以解决这个问题,你提到过这两种方法。就个人而言,我会采用第一种方法(创建一个映射对象作为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!

答案 1 :(得分:5)

如果使用对象数据库,则无需关心如何在数据库中存储关系。您可以定义它们之间的类和关系。请阅读引导到您的数据库的参考。关系的例子:

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 :(得分:1)

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

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

您是否有任何特殊原因要使用ODBMS?对于简单的数据结构(例如书籍分类),您通常不会在ODBMS中找到任何优于RDBMS的优势,事实上将更容易在更加标准化的RDBMS世界中工作。当您处理复杂数据类型或动态对象的文字持久性/存储时,ODBMS具有非常明显的优势。 ODBMS也被认为比RDBMS更快,更具可扩展性,尽管我自己也无法提供这方面的知识。这里有几页讨论RDBMS与ODBMS,但是:

Whatever Happened to Object-Oriented Databases

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

答案 5 :(得分:0)

我会避免数据重复,因为这会因合并差异而遇到各种各样的问题。

这是诀窍。

结果是我会让每个对象包含对另一个对象类型的引用的集合,以及具有其他对象的独立集合。

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

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