Cassandra 一對多表設計
我是使用 20 年 RDBMS 的 Cassandra 新手,在過去的幾天裡,我一直在閱讀和觀看我能得到的適用於我情況的所有內容。我確定這是一個基本問題,但由於某種原因它沒有點擊,所以如果在其他地方得到回答,請原諒。
我正在嘗試設計一個表來儲存使用者之間的關聯列表。任何使用者都可以有任意數量的關聯使用者。這有點像朋友列表。
現在我有3個欄位:
id (timeuuid) (PK)
使用者 (uuid)
朋友 (uuid)
我希望能夠做到:
SELECT * FROM friends WHERE user = ?
所以因為使用者不是PK,所以不能在查詢中使用。而且,如果我讓它成為 PK 的一部分,它必須是唯一的,這意味著使用者最多只能有 1 個朋友。
我通過在user上使用二級索引解決了這個問題,但我認為這種方法不是最好的主意。該查詢的響應速度相當慢,顯然是因為它必須向我的所有集群節點詢問他們的部分數據。
那麼:設計這張桌子的正確方法是什麼?非常感謝您的任何指導。
Cassandra 中的模式設計,用於高效的表,將不利於您的 RDBMS 體驗;為了效率,Cassandra更喜歡去 規範化,而不是規範化。我的意思是,如果您有一些使用者資訊並且您想使用兩個不同的主鍵來查找該數據,那麼使用 Cassandra,實際上最好使用兩個表(並複制數據)。是的,這意味著更多的儲存空間,但它也允許更快的讀取。
作為旁注,根據我自己的經驗,我建議不要使用二級索引,而只需使用另一個表。Cassandra 中二級索引的處理方式略有不同,後台執行緒會定期更新索引;這使得從索引中讀取不如僅使用表可靠(即更可能以一種不好的方式讓您感到驚訝)。
因此,我會根據您的需要推薦以下兩個表格:
CREATE TABLE users ( id TIMEUUID PRIMARY KEY, user UUID, friend UUID ); CREATE TABLE friends ( id TIMEUUID, user UUID, friend UUID, PRIMARY KEY (user, friend) );
第二個表可以讓您進行 CQL 查詢:
SELECT * FROM friends WHERE user = ?
請注意,此
friends
表使用複合主鍵。這允許有多個friend
值與該單個值相關聯user
。這種多表方法的缺點之一是您的應用程式碼現在必須負責寫入兩個表以進行一次“更新”,並且您必須處理任何潛在的偏差/協調。Cassandra 在許多方面通過避免強制執行外鍵約束等並將其留給應用程序來實現其性能。
希望這可以幫助!