Как структурировать базу данных DynamoDB, чтобы разрешать запросы для популярных сообщений? - PullRequest
6 голосов
/ 18 февраля 2012

Я планирую использовать следующую формулу для подсчета "трендовых" сообщений:

Trending Score = (p - 1) / (t + 2)^1.5

p = голосов (баллов) от пользователей.t = время с момента отправки в часах.

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

Структура, которую я имел в виду, выглядит следующим образом:

TableName: Users

HashAttribute:  user_id
RangeAttribute: NONE
OtherFields: first_name, last_name

TableName: сообщения

HashAttribute:  post_id
RangeAttribute: NONE
OtherFields: user_id,title, content, points, categories[ ]

TableName: Категории

HashAttribute:  category_name
RangeAttribute: post_id
OtherFields: title, content, points

TableName: Counters

HashAttribute:  counter_name
RangeAttribute: NONE
OtherFields: counter_value

Итак, вот пример типов запросов, которые я бы сделал со следующей настройкой таблицы (пример: user_id = 100):

User Action 1:

Пользователь создает новый пост и отмечает его для 2 категорий (бейсбол, футбол)

Запрос (1):

Проверьте текущее значение для counter_name = 'post_id' и приращения + 1 и используйте новый post_id

Запрос (2): Вставьте в таблицу сообщений следующее:

post_id=value_from_query_1, user_id=100, title=user_generated, content=user_generated, points=0, categories=['baseball','soccer']

Запрос (3):

Добавьте в таблицу категорий следующее:

category_name='baseball', post_id=value_from_query_1, title=user_generated, content=user_generated, points=0

Запрос (4):

Insв таблицу категорий добавьте следующее:

category_name='soccer', post_id=value_from_query_1, title=user_generated, content=user_generated, points=0

Конечная цель - иметь возможность выполнять следующие типы запросов:1. Запрос на последние сообщения2. Запрос на сообщения в определенной категории3. Запрос сообщений с наивысшими баллами

Кто-нибудь знает, как я могу структурировать свои таблицы так, чтобы я мог сделать запрос для трендовых сообщений?Или это то, что я отказываюсь делать, переключаясь на DynamoDB?

1 Ответ

1 голос
/ 19 марта 2012

Я начинаю с примечания к вашему комментарию с отметкой времени и post_id.
Так как вы собираетесь использовать DynamoDB в качестве генератора post_id, тут есть проблема с масштабируемостью. Эти числа по своей сути не масштабируются, и вам лучше использовать объект даты. Если вам нужно быстро создавать посты, вы можете начать читать о том, как это делают твиттеры. http://blog.twitter.com/2010/announcing-snowflake

Теперь вернемся к проверке трендов:
Я считаю, что ваш сценарий неправильно использует DynamoDB.
Допустим, у вас есть одна ГОРЯЧАЯ категория, в которой больше всего постов. По сути, вам придется сканировать все сообщения (так как данные плохо распределяются), и при каждом запуске просматривать точки и проводить сравнения на вашем сервере. Это просто не будет работать или будет очень дорогим, поскольку каждый раз вы, вероятно, будете использовать все свои зарезервированные емкости для чтения.

Подход DynamoDB для такого типа проверки трендов использует MapReduce
Прочитайте здесь, как реализовать это: http://aws.typepad.com/aws/2012/01/aws-howto-using-amazon-elastic-mapreduce-with-dynamodb.html

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

На другой ноте - вы можете оставить список самых модных вопросов "top 10/100" и вы обновляете их в режиме «реального времени», когда за пост проголосовали - вы получаете список, проверяете, нужно ли его обновить с помощью вновь поставленного вопроса, и при необходимости сохраняете его обратно в БД.

...