2017-07-10 147 views
2

說我想設計一個系統,用戶可以創建帖子,每個帖子屬於一個用戶,但用戶可能有多個帖子。另外,假設我想支持查找給定用戶ID的所有帖子,以及通過postId簡單查找帖子。我還想存儲用戶特定的帳戶詳細信息,例如帳戶創建日期。造型在Cassandra中建立一對多關係的最佳方式是什麼?

的一種方式,這將是如下:

CREATE TABLE user (
    userId int, 
    name varchar, 
    userDetail1, 
    userDetail2, 
    ..., 
    PRIMARY KEY(userId) 
); 

CREATE TABLE post (
    postId int, 
    postDetail1, 
    postDetail2, 
    ..., 
    userId int, 
    PRIMARY KEY(postId) 
); 

從我讀過,推測這是不是最佳的查詢由特定用戶的帖子成爲記憶效率低下。它是否正確? Cassandra不支持索引userId上的發佈表的原因是什麼?

那麼理想的解決方案如下?

CREATE TABLE user (
    userId int, 
    name varchar, 
    userDetail1, 
    userDetail2, 
    ..., 
    PRIMARY KEY(userId) 
); 

CREATE TABLE post (
    postId int, 
    postDetail1, 
    postDetail2, 
    ..., 
    userId int, 
    PRIMARY KEY(postId) 
); 

CREATE TABLE user_to_post (
    userId int, 
    postId int, 
    userDetail1, 
    userDetail2, 
    ..., 
    postDetail1, 
    postDetail2, 
    ..., 
    PRIMARY KEY(userId, postId) 
); 

使用組合鍵,查詢特定用戶的帖子效率更高。但是通過這種設計,會有一張專門用於表達職位的表格?同樣,在這個設計中,我希望查找特定用戶發佈的帖子,並且還想快速鏈接到發佈帖子的特定用戶。我做了大量的閱讀,但對於如何在Cassandra中精確設計一對多關係感到非常困惑。

回答

3

它很大程度上取決於您嘗試實現的所有請求。如果我理解正確的話,你希望能夠:

  1. 通過其ID
  2. 獲取特定用戶獲取職位列表中的用戶

這大部分我的意見,從來自DataStax的優秀頁面Basic Rules of Cassandra Data Modeling。你必須首先了解這個問題沒有明確的答案。它高度依賴於你試圖運行的查詢,以及你準備做出的折衷。例如:您是否預計特定用戶的帖子數量爲真的是高(數千或數百萬)?什麼是最頻繁的查詢(即模擬數據的查詢)?

  • 第一個模型似乎打破了規則2:最小化分區讀取次數。 posts表的分區鍵是post ID(我認爲是隨機的,比如UUID),結果將是帖子遍佈在集羣中。因此,假設您擁有特定用戶的帖子列表(實際上需要非常低效的羣集掃描),那麼如果每個用戶的帖子數量足夠大,您的請求將不得不擊中羣集中的每個服務器。這是最糟糕的情況,絕對不是你想要的。

  • 第二種模式本質上更好,因爲每個請求都可以使用單個請求來實現。您正在爲閱讀性能進行交易存儲,這通常是一件非常好的事情。我可能會建議看看Materialized Views(Cassandra 3.0+),這對你幫助很多人維護這樣的表格 - 雖然完全按照你對MV提出的建議很複雜,因爲你只能提供一個表格作爲視圖來源(即帖子)。

我也可以建議一個替代模式,它修正從第一個提案的設計缺陷而不重複數據(這是再次,不是問題。)這裏的關鍵是使用了帖子用戶ID作爲分區鍵,並將帖子ID作爲集羣鍵。這允許將特定用戶的所有帖子存儲在同一個節點上,因此爲請求來自特定用戶的帖子提供良好的性能。

CREATE TABLE user (
    userId int, 
    name varchar, 
    userDetail1, 
    userDetail2, 
    ..., 
    PRIMARY KEY(userId) 
); 

CREATE TABLE post (
    userId int, 
    postId int, 
    postDetail1, 
    postDetail2, 
    PRIMARY KEY(userId, postId) 
); 

這種解決方案的主要缺點是,它稍微complexifies檢索單篇文章的過程:你必須通過了解,除了後ID的用戶ID。這可能不是一個問題,因爲兩者都有內在聯繫。

再一次記住,除非是非常簡單的情況,否則在計算機科學中做任何事情的最佳方式是不太可能存在的。它取決於您嘗試最大化的哪組指標,您準備做出的折衷,更重要的是存儲系統,您將運行的工作負載。

相關問題