2012-10-12 102 views
3

我不明白關於Cassandra的一件事。說,我有類似的Facebook網站,人們可以分享,評論,上傳圖片等。構建cassandra數據庫

現在,讓我們說,我想所有的事情我的朋友們:

  • USERNAME1喜歡你對此有何評論
  • 用戶名2更新了他的個人資料圖片

等。

所以大量的閱讀後,我想我需要做的是爲每一個單一的東西創造新柱族,例如:user_likesuser_commentsuser_shares。基本上,任何你可以想到的,甚至在我這樣做之後,我仍然需要爲大多數列創建二級索引,以便我可以搜索數據?即使如此,我怎麼知道哪些用戶是我的朋友呢?我需要首先獲取我的所有朋友ID,然後搜索所有這些列家庭爲每個用戶ID?

編輯 行,所以我做了一些更多的閱讀,現在我明白的事情更好一點,但我仍然無法真正弄清楚如何構建我的表,所以我將一個賞金,我想得到我的表應該看起來怎麼樣,如果我想存儲在這樣的順序檢索數據的一個明顯例子:

  • 所有
  • 喜歡
  • 評論
  • 收藏
  • 下載
  • 股份
  • 消息

所以我們可以說,我想找回我所有的朋友10頁最後上傳的文件或我關注的人,這是它會是什麼樣子:

John uploaded song AC/DC - Back in Black 10 mins ago

和評價,比如和股每一件事情是類似於......

現在可能最大的挑戰將是檢索所有類別的10個最後的東西在一起,所以列表將是所有東西的組合...

現在我不需要一個完整的詳細表的答案,我只需要一些非常清晰的例子,我將如何構建和檢索數據,如我將在mysqljoins

+1

是的,您需要定義二級索引才能搜索您的數據。沒有,你只能通過密鑰獲取數據.. –

+1

不,你不傻,順便說一句。藉助Cassandra,您需要詳細瞭解您想要存儲的內容以及訪問方式。只有這樣,您才能真正進入您的專欄家族的最佳模式。 –

回答

4

使用sql,您可以構建表來規範化數據,並使用索引和聯接進行查詢。有了cassandra,你不能這樣做,所以你構造你的表來服務你的查詢,這需要非規範化。

你想要查詢你的朋友上傳的項目,一種方法是每個用戶只有一張表,並且每當該用戶的某個朋友上傳某個內容時寫入該表。

friendUploads { #columm family 
    userid { #column 
     timestamp-upload-id : null #key : no value 
    } 
} 

爲例,

friendUploads { 
    userA { 
     12313-upload5 : null 
     12512-upload6 : null 
     13512-upload8 : null 
    } 
} 

friendUploads { 
    userB { 
     11313-upload3 : null 
     12512-upload6 : null 
    } 
} 

注意上傳6被複制到兩個不同的列,誰做upload6既是用戶A和用戶B的朋友現在

到查詢好友的朋友上傳顯示,在userid列上做一個限制爲10的getSlice。這將返回前10個項目,按鍵排序。

要最先放置最新的項目,請使用reverse comparator,它可以在較小的時間戳之前排序較大的時間戳。

這個代碼的缺點是,當用戶A上傳一首歌,你所要做的ň寫入更新friendUploads列,其中N是人誰是用戶A.

的朋友對於數與每個timestamp-upload-id關鍵字相關聯的值,您可以存儲足夠的信息以顯示結果(可能在json blob中),或者您可以不存儲任何內容,並使用uploadid獲取上載信息。

爲了避免重複寫入,您可以使用如下所示的結構,

userUploads { #columm family 
    userid { #column 
     timestamp-upload-id : null #key : no value 
    } 
} 

此存儲爲特定用戶上傳的視頻。現在,當想要顯示用戶B的朋友上傳時,您必須爲用戶B的每個朋友執行N個查詢,並將結果合併到您的應用程序中。查詢速度較慢,但​​編寫速度較快。如果用戶可以有成千上萬的朋友,那麼您可以使用第一個方案,並且執行更多的寫入而不是更多的查詢,因爲您可以在用戶上傳後在後臺執行寫入操作,但查詢必須當用戶在等待時發生。

作爲反規範化的一個例子,看看有多少個twitter rainbird在單個click occurs上寫數據。每次寫入都用於支持單個查詢。

1

在某些方面,您可以將noSQL視爲關係存儲。在其他情況下,你可以通過非規範化來加快速度。例如,PlayOrm的@OneToMany存儲在許多像這樣

user1 -> friend.user23, friend.user25, friend.user56, friend.user87 

這是寬行的辦法,所以當你發現你的用戶,你把所有的外鍵給他的朋友。每行可以有不同的長度。您可能還存儲以及反向參考,因此用戶可能不得不標誌着他爲好友的人引用,但他並沒有將它們標記回來(我們稱之爲哥們),所以你可能有

user1 -> friend.user23, friend.user25, buddy.user29, buddy.user37 

公告如果設計正確,您可能不需要「搜索」數據。也就是說,使用PlayOrm,您仍然可以執行可伸縮SQL並進行連接(您只需要弄清楚如何對錶進行分區,以便可以擴展到數以萬億計的行)。

一行可以有數百萬列或只有10行。我們實際上正在更新PlayOrm中的許多文檔和本月的noSQL模式,所以如果你留意這一點,那麼你也可以在那裏瞭解更多關於通用noSQL的知識。

院長

1

地考慮每個數據庫查詢的請求到另一臺機器上運行的服務。您的目標是最大限度地減少這些請求的數量(因爲每個請求都需要網絡往返)。

下面是與RDBMS範例的主要區別:在SQL中,您通常會使用連接和輔助索引。在cassandra連接是不可能的,因爲相關數據將駐留在不同的服務器上。類似物化視圖的東西在cassandra中用於相同的目的(用單個查詢獲取所有相關數據)。

我建議你閱讀這篇文章: http://maxgrinev.com/2010/07/12/do-you-really-need-sql-to-do-it-all-in-cassandra/

,並尋找到twissandra樣本項目https://github.com/twissandra/twissandra 這是優化工藝的那種你描述項目的集合不錯。