面向文檔的數據庫(特別是RavenDB)真的很吸引我,我想與他們玩一下。然而作爲一個非常習慣於關係映射的人,我試圖想到如何在文檔數據庫中正確地建模數據。我如何模擬像RavenDB這樣的面向文檔的數據庫系統中的heirarchal和關係數據?
說我有一個在我的C#應用程序下面的實體CRM(留出不需要的屬性):
public class Company
{
public int Id { get; set; }
public IList<Contact> Contacts { get; set; }
public IList<Task> Tasks { get; set; }
}
public class Contact
{
public int Id { get; set; }
public Company Company { get; set; }
public IList<Task> Tasks { get; set; }
}
public class Task
{
public int Id { get; set; }
public Company Company { get; set; }
public Contact Contact { get; set; }
}
我想將所有這一切在Company
文件,聯繫人和任務沒有一個公司的目的,大多數時間查詢任務或聯繫人也會顯示關聯公司的信息。
問題出現在Task
實體中。假設企業要求任務始終與公司相關聯,但也可以選擇與任務相關聯。
在關係模型中,這很容易,因爲您只有Tasks
表並且Company.Tasks
與公司的所有任務相關,而Contact.Tasks
僅顯示特定任務的任務。
對於在文檔數據庫建模這一點,我認爲以下三種思路:
型號任務作爲一個單獨的文件。這似乎是一種反文檔數據庫,因爲大多數情況下,當您查看公司或聯繫人時,您會想要查看任務列表,因此必須對文檔進行大量連接。
保留與
Company.Tasks
列表中未與聯繫人關聯的任務,並將與聯繫人關聯的任務與每個單個聯繫人列表相關聯。這不幸意味着如果你想看到公司的所有任務(這可能會很多),你必須將公司的所有任務與每個聯繫人的所有任務結合起來。當您想從聯繫人中分離任務時,我也會發現這很複雜,因爲您必須將其從聯繫人移動到公司將所有任務都保留在
Company.Tasks
列表中,並且每個聯繫人都有一個id列表與其相關聯的任務的值。這似乎是一種很好的方法,除了必須手動獲取id值並且必須爲聯繫人創建Task
實體的子列表。
在面向文檔的數據庫中對此數據建模的建議方法是什麼?
好吧,所以我想我把反規範化做得太過分了,但是把它們分開放棄基於文檔的db的好處,因爲我必須不斷地在文檔之間進行連接? – KallDrexx 2011-06-09 12:57:02
您不會因爲這些索引閃電般快速,並且db.Load發生在服務器上,所以成本很低。你應該考慮你的交易界限在哪裏,只有當你真的需要時才使用這種方法 - 但這確實意味着你可以從兩個世界中獲益。我忘記提及更新非規範化引用(如果名稱更改),則需要運行修補程序來更新引用。這又是一件非常簡單的事 - 但你需要管理一個過程。我發現這是一個很小的代價,它被一個無模式數據庫的好處大大超過了:) –
iwayneo
2011-06-09 16:00:17
這很有道理:)。我非常喜歡文檔(更重要的是無模式)數據庫的想法。謝謝! – KallDrexx 2011-06-09 16:23:10