如何在对象数据库中设计多对多关系?
我认为是时候看看 OO 数据库了,并决定将 db4o 用于我的下一个小项目 - 一个小型库。
考虑以下对象:书籍、类别。
一本书可以属于 0-n 个类别,一个类别可以应用于 0-m 个图书。
我的第一个想法是拥有一个连接对象,例如 BookCatecory,但经过一番谷歌搜索后,我发现这不适合“真正的面向对象”。
因此,另一种方法(许多人推荐)是在两个对象中都有一个列表:Book.categories 和 Category.books。 一侧处理关系:Book.addCategory 将 Category 添加到 Book.categories,将 Book 添加到 Category.books。 当在一个方法调用中更改 2 个对象时,如何处理提交和回滚?
你怎么看? 第二种方法具有明显的优点,但至少对我来说,第一种“感觉”正确(规范更好)。
I thought it was about time to have a look at OO databases and decided to use db4o for my next little project - a small library.
Consider the following objects: Book, Category.
A Book can be in 0-n categories and a Category can be applied to 0-m Books.
My first thought is to have a joining object such as BookCatecory but after a bit of Googling I see that this is not appropriate for 'Real OO'.
So another approach (recommended by many) is to have a list in both objects: Book.categories and Category.books. One side handles the relationship: Book.addCategory adds Category to Book.categories and Book to Category.books. How to handle commits and rollbacks when 2 objects are been altered within one method call?
What are your thoughts? The second approach has obvious advantages but, for me at least, the first 'feels' right (better normed).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我实际上只能想到两种方法来解决这个问题,您都提到了这两种方法。 就我个人而言,我会采用第一种方法(创建映射对象作为 OO 实体)。 这可以防止您保留冗余信息并进行同步; 这也意味着,如果该协会最终拥有自己的字段(比方说,该书被分配到该类别的日期),那么它们可以很容易地合并。 我们将这种方法用于我们系统中的各种关联。
OO 实体看起来像:
这里你必须保持关系对象和两个集合同步; 但是,在这种情况下,集合是可选的。 通常,您可以通过 ORM 查询获得相同的信息,例如:
select b.book from BookCategory b where b.category = MyCategory
另一种方法是进行如下设置:
如果您的 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!
There are really only two ways I can think of to solve this problem, both of which you've mentioned. Personally, I would go with the first approach (creating a mapping object as an OO entity). This prevents you from keeping redundant information around and having to synchronize; it also means that if the association ends up having fields of its own (the date that the book was assigned to that category, let's say), they can be incorporated easily. We use this approach for a variety of associations in our system.
The OO entities would look like:
Here you have to keep the relation object and the two collections in synch; however, the collections are optional in this case. Typically you could get the same information with an ORM query, something like:
select b.book from BookCategory b where b.category = MyCategory
The alternative is to have a setup like:
If your ORM/DB tool automatically maintains the associations, this is fine; otherwise, you are stuck updating both collections. (In Hibernate, one side will have the property: inverse=true on the mapping; this side is not updated, so strictly speaking it doesn't need to be maintained. This seems to me like bad practice, though.)
If you typically only access the relation one way (for example, getting all of the books in a category), you could eliminate the collection on other side; then I think you would have to work around the ORM tool and use a native query in order to access the relationship from the other direction.
We use Hibernate (a java-based Object Relational Mapping tool) on our project; the Hibernate docs are a good reference for OO/relational design problems, though you may have to spend a little time learning Hibernate to make them useful:
http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/#collections-ofvalues
HTH!
如果您使用对象数据库,则无需关心关系如何存储在数据库中。 您定义类以及它们之间的关系。 请阅读您的数据库的参考指南。 关系示例:
If you use object database you don't need to care how relations are stored in database. You define classes and relationships between them. Please read the reference guided to your database. Examples of relationships:
我认为您只是有点迷恋关系数据库的思维方式。 每个对象中的列表是正确的 OO 做法。 提交和回滚没有问题,它们发生在提交所有内容或回滚所有内容的事务中。
I think you're just a little hung up on the relational db way of thinking. Lists in each object is the right OO thing to do. Commits and rollbacks are no problem, they happen in a transaction that commits everything or rolls back everything.
在纯面向对象数据库(例如 GemStone)中,对象本身具有对其他对象的引用的集合。 当从应用程序引用该对象时,OODBMS 会生成一个包装该对象的代理。 其模式只是持久化对象及其所引用的对象的引用集合。 OODBMS 不一定需要链接实体。
通过 O/R 映射层(假设它足够聪明来执行 M:M 关系),M:M 关系表现为对象本身的辅助引用的集合,O/R 映射器将其解析为对象背后的链接实体。场景。 并非所有 O/R 映射器都这样做,因此您可能有一个单独的链接对象。
In a pure OO database such as GemStone the objects themselves have collections of references to other objects. When the object is referenced from the application the OODBMS generates a proxy that wraps the object. The schema for this is just the persisted object and its collection of references to the objects it refers to. The OODBMS does not necessarily need a link entity.
With an O/R mapping layer (assuming it is clever enough to do M:M relationships) the M:M relationship is manifested as a collection of subsidiary references on the object itself which the O/R mapper resolves to the link entity behind the scenes. Not all O/R mappers do this, so you may have a separate link object.
您有什么特别的原因想要使用 ODBMS 吗? 对于简单的数据结构(例如书籍分类),您通常不会发现 ODBMS 相对于 RDBMS 有任何优势,事实上,在更加标准化的 RDBMS 世界中工作会更轻松。 当您处理复杂的数据类型或动态对象的文字持久性/存储时,ODBMS 具有非常明显的优势。 ODBMS 还被认为比 RDBMS 更快、更具可扩展性,尽管我自己对此无法提供什么见解。 不过,这里有几页讨论 RDBMS 与 ODBMS:
面向对象数据库发生了什么
面向对象数据库与对象关系数据库 (SO)
Do you have any particular reason you wanted to use an ODBMS? For simple data structures (such as categorizing books) you generally won't find any advantage in ODBMS over RDBMS, and in fact will have an easier time working in the much-more-standardized world of RDBMS. ODBMS has very tangible advantages when you are working with complex data types or literal persistence/storage of dynamic objects. ODBMS also is cited as being much faster and more scalable than RDBMS, though I can offer little insight into this myself. Here are a couple pages that discuss RDBMS vs. ODBMS, however:
Whatever Happened to Object-Oriented Databases
Object-Oriented Database vs. Object-Rleational Database (SO)
我会避免数据重复,因为这样你会在合并差异时遇到各种问题。
做到这一点的技巧是参考。
结果是,我会让每个对象包含对其他对象类型的引用的集合,并且具有其他对象的独立集合。
匹配表是一个关系概念,除非中间连接类可能具有不可归因于任何一个对象的属性。 它之所以存在,是因为它使查询能够以强大的方式编写,因为它将关系减少为 2 个一对多关系,并大大减少了数据重复。 如果您在没有匹配表的关系数据库中执行此操作,那么事情很快就会变得糟糕 - 更新将如何操作? 就我个人而言,我发现 oo 数据库的吸引力在于摆脱这种
方式,我将所有对象绑定在一起的方式是通过代码中的事件传递给某种事务处理程序,以允许缓存对象状态。 因此,对象不是操纵彼此的属性,而是通过处理程序请求更改并在回调中等待结果。
I would avoid data duplication because then you run into all kinds of problems with merging the differences.
the trick to this is references.
the result is that I would have each object contain a collection of references to the other object type as well as having an independent collection of the other objects.
The matching table is a relational concept, unless that intermediary connecting class may have properties that are not attributable to either of the objects. It is there as it enables queries to be written in a powerful manner as it reduces the relation to 2 one to many relations and greatly reduces data duplication. If you did this in a relation database without the matching table then things would get evil very quickly - how would an update operate? Personally i find the attraction of oo databases to be stepping away from this
the way that i would tie all the objects together is via events in code to some kind of transaction handler to allow the caching of objects states. so rather than objects manipulating each others properties they request a change through the handler and await the result in a callback.