Схема NoSQL (MongoDB / DynamoDB) - PullRequest
       14

Схема NoSQL (MongoDB / DynamoDB)

2 голосов
/ 13 февраля 2012

Я собираю серию продуктов с веб-сайтов и храню их в БД. На данный момент я использую MySQL с двумя таблицами:

products (product_id, site, product_description, etc)
    e.g. (1234, "xyz.com", "nice product", etc)
product_history (product_id, scrape_timestamp)
    e.g. (1234, 2012-01-02 10:53:09)
         (1234, 2012-01-03 11:02:09)

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

Я рассматриваю переход на NoSQL, потому что (i) я часто получаю разные поля с разных сайтов и (ii) объем данных будет составлять около 5-10 миллионов продуктов в год. Я вижу два способа структурирования схемы

Вариант 1: «Встроенный список»

product_id,  site,      product_description, scrape_timestamp
1234,        "xyz.com", "test product",      {2012-01-02 10:53:09, 2012-01-03 11:02:09}

Вариант 2: «Вторичный индекс»

keep both tables as above with the relational schema

Я думаю, что вариант 1 будет работать в чем-то вроде MongoDB, где разрешены вторичные индексы, тогда как вариант 2 будет работать либо в MongoDB, либо в DynamoDB. (Я рассматриваю эти два, потому что я хочу, чтобы что-то было размещено в облаке с нулевыми накладными расходами для меня).

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

1 Ответ

2 голосов
/ 15 февраля 2012

Вы говорите, что пытаетесь решить следующую проблему хранения данных:

  1. 10 миллионов или около того исторических точек данных в год
  2. разнородных точек данных

10 миллионов или около того исторических точек данных в год

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

Что касается решения проблемы исторических данных на основе MongoDB, у вас, вероятно, будет коллекция для product_historyданные, и вам просто нужно решить, сколько записей поместить в каждый документ.Некоторые варианты: один на продукт;один на продукт / метку времени;один на продукт / временную метку в течение определенного периода времени, напримеродин день или один месяц.Еще несколько подробностей:

  • Документация mongo предполагает, что встраивание данных в массив будет иметь смысл "для определенных случаев использования".Ваш вариант звучит как один из таких вариантов использования, т. Е. Я бы НЕ создавал один документ на продукт / временную метку.
  • Вам также не нужен один документ на продукт, потому что mongo не очень хорош для выращивания очень длинных массивов.
  • Таким образом, оставшаяся опция - одна для продукта / метки времени в течение определенного периода времени.Иди с этим.К сожалению, вам придется попробовать несколько вещей, чтобы точно определить, как структурировать этот документ.Вот несколько вещей, которые можно попробовать:
    • Используйте атрибут «period», чтобы указать время начала рассматриваемого периода.Создайте индекс для продукта / периода.
    • Когда вы добавляете к структуре данных в этом документе, вы можете упростить свой код с помощью функциональности upsert mongo.
    • Укажите продолжительность периода(ежечасно, ежедневно, ежемесячно и т. д.) в зависимости от того, как часто поступают новые точки данных. Вероятно, вам нужно настроить эту продолжительность на основе нагрузочного теста.
    • Самый простой способ структурировать документ за период - этоиспользуйте один массив для хранения данных.Однако монго плохо подходит для добавления к очень длинным массивам, поэтому некоторые люди улучшили производительность, создав простое дерево в документе.Например, если у вас есть ежедневный документ, вы можете использовать отдельный массив в час в течение дня:
{
  "0" : [ 123, 456 ],
  "1" : [ 789 ]
}

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

разнородные точки данных

Что касается решения СУБД для вашей проблемы, вот наиболее распространенные подходы, которые я видел:

  • Денормализация данных.Вы говорите, что у вас есть 85 атрибутов на продукт?Затем создайте таблицу с 85 столбцами!Вы говорите, что другой продукт имеет 20 различных атрибутов?Затем добавьте еще 20 столбцов к вашей таблице!Это решение:
    • Простое.
    • Работает хорошо, поскольку применяются все обычные преимущества денормализации.
    • Подрывает некоторые преимущества использования реляционной базы данных.Например, большинство ваших столбцов не могут иметь ограничение «не ноль».
  • Нормализовать данные.Создайте одну таблицу для захвата атрибутов типа X, другую таблицу для захвата типа Y и т. Д. Если у вас новый тип продукта, добавьте новую таблицу.Это решение:
    • Может быть сложным.Например, как вы решаете, в какую таблицу помещать определенные общие атрибуты?
    • Может плохо работать. Например, если вам нужно объединить 10 таблиц, чтобы получить какую-либо полезную информацию из базы данных, у вас возникла проблема.
    • Порадует пуристов базы данных.
  • Использовать строки вместо столбцов. Это решение:
    • Сложен и сложен в обслуживании.
    • плохо работает.
    • Подрывает некоторые преимущества использования реляционной базы данных.

(Обратите внимание, что существуют другие решения на основе RDBMS. Например, некоторые люди любят помещать документы XML в DB2 .)

Вы пробуете последний подход, поэтому неудивительно, что вы несчастны! Если вы собираетесь использовать RDBMS, я бы рекомендовал перейти на один из других подходов, которые я перечислил.

Теперь вернемся к вашему вопросу о NoSQL. База данных NoSQL на основе документов, такая как MongoDB, является привлекательным решением вашей проблемы «разнородных точек данных», поскольку она не требует схем. Вы можете перечислить спецификацию продукта в одном документе, и когда вы хотите добавить новые атрибуты, тогда вы просто делаете это. MongoDB позволяет индексировать атрибуты, поэтому, если вы хотите найти продукт с атрибутом A, вы можете сделать это быстро с помощью индекса. (Здесь нет ничего волшебного: как и в любой базе данных, обслуживание индексов может быть дорогостоящим, поэтому создавайте их экономно).

...