2017-02-16 3 views
2

Я ищу для хранения журнала пользовательских событий. Это будет много записей, поэтому я думал, что DynamoDB будет хорош, так как там размещается все остальное.DynamoDB Дизайн NoSQL для запросов

Мне нужно запросить эти события двумя способами: totalt событий для пользователя для даты (диапазона) и иногда всех событий для даты.

Я думал, чтобы хранить его в одной таблице, как user id (ключ), sequence number (ключ), date, time и duration.

Должно ли быть несколько таблиц? Как это можно сделать наиболее эффективным?

+0

Каков порядковый номер? Предполагается, что это как поле автоинкремента только для ссылки на событие или что? Другой вопрос: хотите ли вы запросить все события для даты для всех пользователей или всех событий для определенного пользователя? – xtx

+0

У нас есть порядковый номер, чтобы сделать каждую строку уникальной, и мы это обеспечиваем. Нам нужно только запрашивать одного пользователя за раз. – Gustaf

ответ

0

Для небольшого количества данных эта структура в порядке. Имейте в виду, что порядковый номер (ваш ключ диапазона) должен быть предоставлен вами. Кажется хорошей идеей выбрать дату как временную метку unix с миллисекундной точностью в качестве ключа сортировки.

Нет необходимости в дополнительных столах. Однако ваша структура во многом зависит от читаемой емкости записи, которую вы хотите достичь, и размера данных.

Предположим, что ваш user_id является вашим ключом раздела.

Для каждого отдельного значения ключа раздела общие размеры всех элементов таблицы и индекса не могут превышать 10 ГБ. Один раздел может поддерживать до 3000 единиц емкости чтения или 1000 единиц мощности записи.

Вам необходимо создать ключи раздела, учитывая эти ограничения. Например, у очень активного пользователя много событий, поэтому вам нужно более 1000 единиц мощности записи. К сожалению, вы выбрали в качестве раздела идентификатор пользователя.

В этом случае вы ограничены 1000 единиц мощности записи, поэтому у вас могут быть сбои.

У вас должна быть другая структура. Например, имя раздела, например user_id_1 user_id_2 и т. Д. Поэтому механизм именования разделов распределяет данные по разделам в соответствии с потребностями вашего приложения.

Проверьте эти ссылки на ограничения dynamodb.

Tables guidance, Partition distribution

0

Я хотел бы предложить следующую структуру для вашей таблицы событий:

  • идентификатор пользователя - хэш-ключа
  • Дата события/времени (временная метка с миллисекундах) - диапазон ключ
  • продолжительность

Наличие метки времени в качестве ключа диапазона должно быть достаточным для обеспечения уникальности события (если только пользователь не может иметь несколько событий в той же миллисекунде), поэтому вам не нужен порядковый номер.

Имея такую ​​схему, вы можете получить все события для пользователя для даты, используя простой query.

К сожалению, DynamoDB не поддерживает агрегированные запросы, поэтому вы не можете быстро получить общее количество событий для пользователя (вам придется запрашивать все записи и вычислять итоговые вручную). Поэтому я бы предложил создать отдельную таблицу для статистики пользовательских событий, как это:

  • идентификатора пользователя - хэш-ключ
  • даты - диапазон ключей
  • 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) { 

});