2012-03-12 110 views
1

如果我想有隻爲查詢:卡桑德拉高分

1. Username, Xp, OtherUserData 
2. User with the N-th highest Xp 

我怎麼會做的數據結構和查詢。

對於1,我會類似的結構: {用戶名:{XP中,OtherUserData}}

我只是要對所有用戶提供2.做一個查詢,或者是有一個更好的選擇?

回答

3

我不能完全肯定你問,但這裏有一個猜測(是XP用戶的得分?):

存儲用戶數據,爲每個用戶創建一個行,鍵入他們的用戶名(假設這是獨特的,固定的),然後對每個項目的列:

username -> Xp  other ... 
      value value ... 

爲了保持高得分表,使用單個行(可能在不同的列系列),與所有用戶(或與上述一個某些閾值),列名稱爲分數,並指定一個數字(LongType)比較器,以便列按照分數排序:

highscores -> 1000  1001  99999999 ... 
       user123 user345 user789 ... 

然後,您可以通過查詢此排序行中的最後或前N列來檢索最高N個分數。如果它太大,你可以從這一行刪除低分。

更新:正如您指出的那樣,多個用戶可能具有相同的分數。快速和骯髒的解決辦法是使價值用戶的列表:

highscores -> 1000  
       "user123, user567, user899" 

這是可以容忍的,如果你是不可能得到大量同分的用戶,雖然尷尬,因爲你需要閱讀,更新並寫入列表。

您可以使用超級列,但通常不建議這些列。

否則,您可能可以使用composite column keys,以便您可以區分用戶,但保留按分數排序的列。

+0

是,XP =經驗值 – Daniel 2012-03-14 12:35:00

+0

我怎麼能處理2個用戶與TE同樣的比分? – Daniel 2012-03-14 12:38:11

+0

查看最新的答案... – DNA 2012-03-14 12:59:52

1

僅使用一行進行分類可能會非常危險,因爲每行只能在Cassandra的一個實例上進行。因此,系統中的所有玩家都會在一臺機器上寫入該ONE密鑰,從而有可能導致羣集中的節點過載。這可能會導致所有羣集失敗,原因是嘗試恢復時,嘗試恢復正在關閉的節點負載的節點的怪異連鎖反應(我們在我們的生產機器上發生過這種情況,因爲存在硬編碼測試鍵會收到所有寫入所有人的單獨行)。

一個解決辦法是通過自己的分數來鬥你的用戶:

  • 0-> 1000 = bucketA
  • 1001 - > 5000 = bucketB
  • 5001 - > 15000 = bucketC 等。

我會建議讓較低級別的桶變小。

寫你與列名作爲複合柱: 的CompositeType

因此,例如,如果你使用UUID作爲玩家ID和多頭的分數(LongType,UTF8Type)我們將有:

  • 500089845:f7bc41d8-c1c6-489c-bb2c-f86fccc7681c
  • 4100085589:2ae91e9f-1512-4ef8-8441-9f48e21fb11b

你可以做它與串聯字符串,但你必須寫所有的前導零,以便UTF8比較器,但所有的分數在正確的順序。

  1. 000000500089845:f7bc41d8-c1c6-489c-bb2c-f86fccc7681c
  2. 000004100085589:2ae91e9f-1512-4ef8-8441-9f48e21fb11b

沒有前導零將

  1. 000004100085589: 2ae91e9f-1512-4ef8-8441-9f48e21fb11b
  2. 000000500089845:f7bc41d8-c1c6-489c-bb2c-f86fccc7681c

這種方式你不必閱讀修改矢量,json,複合或超級列的人有相同的分數,因爲每個分數是一個單獨的列。你可以在列中放置任何你想要的信息,這樣你就可以在一次讀取中獲得所有信息(而不必通過另一次讀取獲取播放器信息,我個人會用一個json或一個字節序列化的對象來包含我需要的所有東西) 。

要閱讀:你想要的行上的反向範圍查詢(最高優先)將做的伎倆。

只要您有足夠的行觸及所有節點,即可在整個令牌環上共享負載,您也可以通過更改存儲桶的性質來改變系統的風格。

希望這是有益