2012-01-04 36 views
3

我們有兩個實體用戶和角色。一個用戶可以擁有多個角色,和單角色可以由許多用戶共享 - 典型M:N的關係。 角色也是動態的,我們預計數量巨大(百萬)。爲共享記錄卡桑德拉設計圖案(M:N)

它是安靜簡單的關係數據庫這樣的數據模型。我想知道什麼時候可以在卡桑德拉。

目前我看到了兩個解決方案:

A)使用標準化的模型,並建立類似的東西內加入

創建用戶記錄外鍵引用的角色在不同的CF每一個角色和存儲。

親:角色不會被複制和維護簡單

禁忌:爲了獲得單用戶多網絡調用的所有角色都是必要的。用戶記錄只包含FK,角色存儲 使用隨機分區,在這種情況下,每個角色可以存儲不同卡桑德拉節點上。

B)進行非標準化模式和複製的作用,避免往返 在卡桑德拉這種情況下用戶記錄包含了所有用戶角色的副本。

親:這是可能的一個查詢中所有角色讀取用戶。這保證了短的加載時間。

contra:每個共享角色被複制多次 - 在每個相關用戶上。保持角色非常困難,特別是如果我們有大量的數據。例如:一個角色由1000個用戶共享。此角色的更改需要更新1000個用戶記錄。 對於非常大的數據集,這種更新必須作爲異步作業執行。上述

解決方案是非常有限的,meybie Cassandra是不是M右:正關係?你知道任何卡桑德拉設計模式這樣的問題?

感謝, 馬切伊

回答

2

你想設計一個數據存儲在卡珊德拉的方式是start with the queries you plan to execute並使其所以你可以得到你需要一次的所有信息。非規範化是這裏遊戲的名稱;如果您不在每個用戶節點中複製角色信息,則不會避免磁盤搜索,並且讀取性能會受到影響。連接沒有意義;如果您需要關係數據庫,請使用關係數據庫。

有人猜測,你會問很多關於用戶角色以及他們應該怎麼做的問題,所以你一定要在每個用戶條目中重複角色信息 - 可能每個角色角色獲得自己的專欄(role-ROLE_KEY => serialized-capability-info而不是roles => [serialized array of capability info])。您的應用程序將需要一些方法來遍歷所有這些列本身。

您可能會想要了解用戶在某個角色中的位置,因此您應該在角色列族中存儲該視圖所需的所有用戶信息(儘管全部用戶的子集記錄會做)。

當您運行更新並從角色添加/刪除用戶時,您需要確保您同時更新角色的用戶列表和用戶的角色。由於您爲每個關係使用了一列,而不是單個共享的序列化Blob,即使您正在編輯同時共享同一用戶的兩個不同角色,它也可以工作:Cassandra可以合併更新,包括刪除。

如果查詢需要異步,那麼請讓你的應用程序處理它。請記住,Cassandra是一個最終一致性的數據存儲,您不應該期望更新立即到處都可見。

+1

卡桑德拉可以是最終一致的,但它不一定是。更好的描述是,它基於複製因子和讀寫一致性級別([R + W>一致性級別爲您提供了強大的一致性])(http://wiki.apache.org/cassandra/API#ConsistencyLevel)具有可調整的一致性。 ) – psanford 2012-01-05 00:54:06

+0

感謝您的好評! - 我期待那樣。在我的情況下,保持這種角色將是痛苦的 - 尤其是當我需要更新數百萬用戶共享的角色......但我看不到其他選擇 – 2012-01-05 08:44:18

1

這些天的另一種選擇是使用可以爲你加入的playORM;)。你只是決定如何分割你的數據。它使用Scalabla JQL這是一個簡單的加法上JQL如下

@NoSqlQuery(名稱= 「findJoinOnNullPartition」,查詢=「PARTITIONS噸( '賬戶',:PARTID)選擇噸從貿易爲t INNER JOIN t.security as s where s.securityType =:type and t.numShares =:shares「)

因此,我們可以最終在noSQL系統上標準化我們的數據並同時進行縮放。我們不需要放棄具有某些益處的正常化。

院長