2010-11-06 52 views
12

在我對Mnesia的理解中,我仍然在用關係術語思考。所以我會把我的努力放在這裏,並尋求解決它們的最好方法。幫助我理解mnesia(NoSQL)建模

一個一對多-關係 說我有一堆人,

-record(contact, {name, phone}). 

現在,我知道我可以定義手機始終保存爲一個列表,讓人們可以有多個電話號碼,我想這就是這樣做的方式(是嗎?然後我怎麼看這個反過來說,找到一個數字的名字?)。 。

多到多對多關係 現在讓我們假設我有多個組,我可以把人組名沒有任何意義,他們只是名稱;該概念是「unix系統組」或「標籤」。天真,我將這個成員作爲一個字段的「接觸」的記錄中從上面,建模爲proplist這樣,像

{groups [{friends, bool()}, {family, bool()}, {work, bool()}]} %% and so on... 

例如。如果我希望能夠快速查找基於組名的所有成員,並希望能夠查找個人註冊的所有組,那麼在mnesia中建模的最佳方法是什麼?當然,我也可以將其作爲僅包含組標識符的列表進行建模。用於mnesia,建模的最佳方式是什麼?

我很抱歉,如果這個問題是愚蠢的。有很多關於mnesia的文檔,但它缺乏(IMO)整體使用的一些很好的例子。

+1

沒有必要道歉恕我直言,這個問題並非愚蠢的所有+1那 – 2010-11-06 17:02:13

回答

3

對於第一個例子,考慮這樣記載:

-record(contact, {name, [phonenumber, phonenumber, ...]}). 

contact是兩個領域,namephone其中手機的電話號碼列表中的記錄。正如user425720所說的,如果將它們存儲爲字符串以外的其他東西,例如,如果您對小存儲空間有極高的要求,則可以採用這種方式。

現在我們來看看難以獲得鍵值存儲的部分:您還需要存儲反向關係。換句話說,你需要類似下面的內容:

-record(phone, {phonenumber, contactname}). 

如果你在你的應用程序中抽象出數據庫處理層,你可以把它隨時添加/添加/更改聯繫人時更改電話記錄。

-

對於第二個例子,考慮這兩個記錄:

-record(contact, {uuid, name, [group_id, group_id]}). 
-record(group, {uuid, name, [contact_id, contact_id]}). 

最簡單的方法是隻存儲指向相關記錄的ID。由於Mnesia沒有參照完整性的概念,如果您例如刪除一個組而不從所有用戶中刪除該組,則可能會失去同步。

如果你需要存儲組的類型上的聯繫人記錄,你可以使用以下命令:

-record(contact, {name, [{family, [group_id, group_id]}, {work, [..]}]}). 

-

你的第二個問題也可以通過使用一箇中間的記錄來解決,您可以將其視爲「成員資格」。

-record(contact, {uuid, name, ...}). 
-record(group, {uuid, name, ...}). 
-record(membership, {contact_uuid, group_uuid}). # must use 'bag' table type 

可以有任意數量的「成員資格」記錄。每個用戶組將有一條記錄。

+0

我會接受這個答案。謝謝。 – 2010-12-21 16:31:08

-1

首先,您要求提供鍵值存儲設計模式。非常好。 在我嘗試回答你的問題之前,讓我們先說清楚 - Mnesia是什麼。它是k-v DB,包含在OTP中。因爲它是本地的,所以從Erlang使用起來非常舒服。不過要小心。這是具有非常古老假設的舊數據庫(例如具有線性散列的數據分佈)。因此,請繼續學習並使用它,但是對於生產來說,花點時間並瀏覽NoSQL商店即可找到滿足您需求的最佳選擇。

@telephone示例。不要將東西存儲爲字符串(list()) - 對於GC非常重要。我會將諸如phone_1 :: < < <二進制>>,phone_2 :: < < < < <二進制>>,phone_extra :: [< <二進制>>]並在最頻繁的查詢字段上構建索引。此外,mnesia的痕跡很棘手 - 當節點崩潰並且上升時,他們需要重建自己(可能需要很長時間)。

@family示例。平面命名空間非常困難。你可以玩更復雜的鍵。也許爲TheGroup創建單獨的表並保留成員的標識符?或者每個成員都擁有他所屬團體的ID(難以維護..)。如果你想認識朋友,我會在呈現數據之前執行某種契約(A是B的朋友,如果B是A的朋友) - 這種方法將應對數據中的最終一致性和衝突。

+0

嘿,也許有人評論之前,這downvote? – user425720 2010-11-07 15:36:42

+0

雖然我沒有投票給你,但在我看來很清楚你沒有得到我在第二個問題中提出的問題(或者我沒有說清楚)。我想模擬多對多的關係; 「家人」和「朋友」並沒有特別提到任何概念。我也已經指出,與會員名單是一種方式,但要求更好的方式。 – 2010-11-07 17:01:44

+0

是啊,內夫。然而,你的元組示例似乎是我在第二部分寫的。第一部分說要將多對多模型作爲單獨的表格來存放成員的鍵。這取決於數據庫。在Riak中有兩級關鍵結構(存儲桶,關鍵) - (值),因此您可以在一個存儲桶中擁有所有關聯成員。從定義來看,KV商店並不擅長表示關係。 – user425720 2010-11-07 17:49:59