2017-02-16 77 views
2

我期待存儲用戶事件的日誌。這將會是很多參賽作品,所以我認爲DynamoDB會很好,因爲所有其他東西都託管在那裏。DynamoDB針對查詢的NoSQL設計

我需要以兩種方式查詢這些事件,一個日期(範圍)的用戶事件總數和偶爾所有日期事件。

我想將其存儲在一個表作爲user id(鍵),sequence number(鍵),datetimeduration

它應該是多個表嗎?這怎麼能做到最高效?

+0

什麼是序列號?是否應該像引用事件的自動增量字段一樣,或者是什麼?另一個問題:您想查詢所有用戶的日期的所有事件,還是查詢特定用戶的所有事件? – xtx

+0

我們有序列號來使每一行都是唯一的,我們提供這個。我們只需要一次查詢一個用戶。 – Gustaf

回答

0

對於少量的數據,這個結構是可以的。 請記住,序列號(您的範圍鍵)必須由您提供。將日期選爲毫秒精度的unix時間戳作爲排序鍵似乎是個好主意。

不需要額外的表格。 但是,您的結構在很大程度上取決於您想要實現的讀寫容量以及數據大小。

假設您的user_id是您的分區鍵。

對於每個不同的分區鍵值,所有表和索引項的總大小不能超過10 GB。 單個分區可以支持最多3,000個讀取容量單位或1,000個寫入容量單位。

您需要通過考慮這些限制來創建分區鍵。 例如,一個非常活躍的用戶有很多事件,因此您需要超過1000個寫入容量單位。不幸的是,你已經選擇了一個分區的用戶ID。

在這種情況下,您被限制爲1000個寫入容量單位,因此您可能會出現故障。

您需要有不同的結構。例如分區名稱,如 user_id_1 user_id_2等。因此,根據您的應用程序的需要,分區命名機制將數據分區到分區。

查看關於dynamodb限制的這些鏈接。

Tables guidancePartition distribution

0

我會建議爲你的事件表的結構如下:

  • 用戶ID - 哈希鍵
  • 事件的日期/時間(時間戳和毫秒) - 範圍鑰匙
  • 持續時間

讓事件時間戳作爲範圍鍵應該足以爲事件提供唯一性(除非用戶可以在同一毫秒內擁有多個事件),因此您不需要序列號。

擁有這樣的模式,您可以通過使用簡單的query來獲取用戶日期的所有事件。

不幸的是,DynamoDB不支持聚合查詢,因此您無法快速獲取用戶的事件總數(您將不得不查詢所有記錄並手動計算總數)。 所以我建議用戶事件的統計數據是這樣創造一個單獨的表

  • 用戶ID - 哈希鍵
  • 日期 - 範圍鍵
  • events_cnt(事件總數爲用戶約會)

所以,你添加一個新的記錄到你的事件表後,你必須增加事件的統計數據表中的用戶應對如下所示:

var dynamodbDoc = new AWS.DynamoDB.DocumentClient(); 
var params = { 
    TableName : "user_events_stats", 
    Key: { 
     userId: "65716110-f4df-11e6-bc64-92361f002671" , 
     date: "2017-02-17", 
    }, 
    UpdateExpression: "SET #events_cnt = if_not_exists(#events_cnt, :zero) + :one", 
    ExpressionAttributeNames: { 
     "#events_cnt": "events_cnt", 
    }, 
    ExpressionAttributeValues: { 
     ":one": 1, 
     ":zero": 0, 
    }, 
}; 

dynamodbDoc.update(params, function(err, data) { 

});