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

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

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

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

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

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

有帮助吗?

解决方案

如果使用对象数据库,则不需要关心如何将关系存储在数据库中。您定义了类及其之间的关系。请阅读指导您数据库的参考。关系的例子:

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
}

其他提示

我实际上只能想到两种方法来解决这个问题,您都提到了这两种方法。就我个人而言,我会采用第一种方法(创建映射对象作为 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

哈!

我认为您只是有点挂在关系DB的思维方式上。每个对象中的列表是正确的选择。提交和回滚没有问题,它们发生在投入所有内容或退缩一切的交易中。

在像宝石这样的纯OO数据库中,对象本身具有对其他对象的参考。当从应用程序引用对象时,OODBMS会生成包装对象的代理。这只是持续存在的对象及其对其所指对象的引用的收集。 OODBMS不一定需要链接实体。

使用O/R映射层(假设它足够聪明,可以进行M:M:M:M:M:M:M:M:M:O/R mapper在对象本身上的集合,O/R映射器将其解析为背后的链接实体。场景。并非所有的O/R映射器都这样做,因此您可能拥有一个单独的链接对象。

您是否有任何特殊原因要使用ODBM?对于简单的数据结构(例如对书籍进行分类),您通常不会在ODBM中找到比RDBM的任何优势,实际上,在备受瞩目的RDBMS世界中工作的时间更容易。当您使用复杂的数据类型或动态对象的字面持久性/存储时,ODBM具有非常明显的优势。与RDBM相比,ODBM也被认为更快,更可扩展性,尽管我自己几乎没有洞察力。但是,这里有几页讨论RDBMS与ODBMS:

面向对象的数据库发生了什么事

面向对象的数据库与对象 - 纤维化数据库(SO)

我会避免使用数据重复,因为随后您会遇到合并差异的各种问题。

诀窍是参考。

结果是,我的每个对象都包含对其他对象类型的引用集合,并具有独立的其他对象集合。

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

我将所有对象绑定在一起的方式是通过代码中的事件与某种交易处理程序允许对象状态的缓存。因此,他们没有反对彼此属性,而是要求通过处理程序进行更改,并在回调中等待结果。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top