2009-07-01 212 views
14

我想應該是時候看看OO數據庫,並決定使用db4o的我的下一個小項目 - 一個小型圖書館。如何設計對象數據庫中的多對多關係?

考慮以下對象:圖書,類別。

一本書可以是0-n的種類和類別可以應用到0-m的圖書。

我首先想到的是有一個連接對象,如BookCatecory但有點谷歌搜索我看到,這是不恰當的「真正的'00」後。

所以另一種方法(由許多推薦)就是在兩個對象的列表:Book.categories和Category.books。一方處理關係:Book.addCategory將類別添加到Book.categories和Book到Category.books。如何在一個方法調用中更改兩個對象時提交和回滾?

你的想法是什麼?第二種方法有明顯的優勢,但至少對我來說,第一種「感覺」是正確的(更好的規範)。

回答

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 
} 
1

我覺得你只是一個小掛了思維的關係數據庫的方式。每個對象中的列表是正確的OO事情。提交和回滾沒有問題,它們發生在提交所有內容或回滾所有內容的事務中。

1

在純粹的面向對象數據庫(如GemStone)中,對象本身具有對其他對象的引用的集合。當從應用程序引用對象時,OODBMS將生成一個包裝對象的代理。這個模式只是持久化對象及其所引用對象的引用的集合。 OODBMS不一定需要鏈接實體。 O/R映射層(假設它足夠聰明,可以執行M:M關係)M:M關係表現爲O/R映射器解析爲對象本身的輔助引用的集合鏈接實體幕後。並非所有的O/R映射器都這樣做,所以你可能有一個單獨的鏈接對象。

1

您是否有什麼特別的理由想要使用ODBMS?對於簡單的數據結構(例如書籍分類),您通常不會發現ODBMS在RDBMS方面的優勢,事實上在RDBMS的更加標準化的世界中工作會更容易。當您處理複雜數據類型或文字持久性/動態對象存儲時,ODBMS具有非常明顯的優勢。 ODBMS也被認爲比RDBMS更快,更具可擴展性,儘管我自己幾乎沒有提供這方面的信息。這裏有幾頁是討論RDBMS與ODBMS,但是:

Whatever Happened to Object-Oriented Databases

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

+0

我想看看是否可以避免創建一個dbschema,創建表,創建對象,將表映射到對象等等等等等等等等。看起來odbms可以切掉很多驢工作... – paul 2009-07-01 14:23:04

+0

它可能會刪除了一些這樣的工作,但是一個體面的ORM層也是如此。我並不是說ODBMS是錯誤的選擇,但有些替代品可以爲您提供更好或更好的服務。 – 2009-09-01 18:44:54

0

我會避免數據重複,因爲你遇到的各種與合併的差異問題。

這個技巧就是參考。

結果是我會讓每個對象都包含一個對另一個對象類型的引用的集合,並且具有其他對象的獨立集合。

匹配表是關係概念,除非中介連接類可能具有不歸屬於任何對象的屬性。因爲它使查詢能夠以強大的方式編寫,因爲它減少了一對多關係的關係並大大減少了數據重複。如果你在沒有匹配表的關係數據庫中這樣做了,那麼事情會很快變得邪惡 - 更新如何操作?就我個人而言,我發現oo數據庫的吸引力正在逐步遠離這種方式,我將所有對象綁定在一起的方式是通過代碼中的事件到某種事務處理器來允許緩存對象狀態。所以不是操作其他屬性的對象,而是通過處理程序請求更改並等待回調結果。

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文檔對於面向對象/關係設計問題是一個很好的參考,儘管你可能需要花一點時間學習Hibernate來使它們有用: http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/#collections-ofvalues

HTH!