Какая база данных подходит для работы?

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

У нас есть приложение Rails, использующее MySQL. У нас нет проблем с MySQL, и он отлично работает. Но для новой функции мы решаем, оставаться ли MySQL или нет. Чтобы упростить задачу, предположим, что существует модель User и Message. Пользователь может создавать сообщения. Сообщение доставляется другим пользователям на основе их связи с плакатом.

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

Таким образом, сообщение может выглядеть так:

{
  id: 1,
  message: "Hi",
  created_at: 1234567890,
  metadata: {
    user_id: 555,
    category_1: null,
    category_2: null,
    category_3: null,
    ...
  }
}

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

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

Лично у меня есть опыт работы с MySQL и MongoDB. Я начал исследовать Cassandra, HBase, Riak и CouchDB. Мне не помешала бы помощь людей, которые, возможно, провели исследование относительно того, какая база данных подходит для моей задачи.

И да, таблица сообщений может легко вырасти до миллионов или строк.


person Jey Balachandran    schedule 19.08.2011    source источник


Ответы (6)


Это очень открытый вопрос, поэтому все, что мы можем сделать, это дать совет, основанный на опыте. Первое, что нужно рассмотреть, это хорошая идея решить использовать что-то, что вы не использовали раньше, вместо того, чтобы использовать MySQL, с которым вы знакомы. Скучно не использовать новые блестящие вещи, когда у вас есть возможность, но поверьте мне, это ужасно, когда вы загнали себя в угол, потому что думали, что новая игрушка будет делать все, что написано на коробке. Ничто никогда не работает так, как написано в сообщениях блога.

У меня в основном есть опыт работы с MongoDB. Это ужасный выбор, если только вы не хотите тратить много времени, пробуя разные вещи и понимая, что они не работают. Как только вы немного масштабируетесь, вы в основном не можете использовать такие вещи, как вторичные индексы, обновления и другие вещи, которые делают Mongo в остальном удивительно хорошим инструментом (большая часть этого связана с его глобальной блокировкой записи и форматом базы данных на диске, это в основном отстой в параллелизме и очень легко фрагментирует, если вы удаляете данные).

Я не согласен с тем, что о HBase не может быть и речи, у него нет вторичных индексов, но вы все равно не можете их использовать, когда превысите определенную нагрузку трафика. То же самое касается Cassandra (которую проще развернуть и с ней работать, чем с HBase). По сути, вам придется реализовать собственную индексацию, какое бы решение вы ни выбрали.

Что вы должны учитывать, так это то, нужна ли вам согласованность с доступностью или наоборот (например, насколько плохо, если сообщение потеряно или задержано, по сравнению с тем, насколько плохо, если пользователь не может опубликовать или прочитать сообщение), или если вы будете обновлять свои данные (например, данные в Riak — это непрозрачный блоб, чтобы изменить его, вам нужно прочитать его и записать обратно, в Cassandra, HBase и MongoDB вы можете добавлять и удалять свойства без предварительного чтения объекта). Простота использования также является важным фактором, и Mongo, безусловно, прост в использовании с точки зрения программиста, а HBase ужасен, но просто потратьте некоторое время на создание собственной библиотеки, которая инкапсулирует неприятные вещи, это того стоит.

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

person Theo    schedule 19.08.2011

Я бы порекомендовал посмотреть презентацию о Почему базы данных не подходят для обмена сообщениями который в основном нацелен на то, почему вы не должны использовать базы данных, такие как MySQL, для обмена сообщениями.

Я думаю, что в этом случае лента изменений CouchDB может пригодиться, хотя вам, вероятно, также придется создавать более сложные представления на основе запроса метаданных сообщений. Если скорость критична, попробуйте также взглянуть на redis, который действительно быстр и поставляется с pub/sub. MongoDB с поддержкой специальных запросов также может быть достойным решением для этого варианта использования.

person yojimbo87    schedule 19.08.2011

Я думаю, вы правильно храните метаданные вместе с каждым сообщением! Жертвовать хранилищем ради более быстрого поиска — это, вероятно, правильный путь. Обратите внимание, что это может усложниться, если вам когда-нибудь понадобится изменить метаданные пользователя и распространить их на все сообщения. Вы должны подумать, как часто это может происходить, действительно ли вам нужно будет обновлять все записи сообщений, и исходя из этого, стоит ли платить цену за меньшее количество запросов (вероятно, оно того стоит, но это зависит от особенности вашей системы).

Я согласен с @Andrej_L, что Hbase не является правильным решением этой проблемы. Кассандра попадает туда по той же причине.

CouchDB может решить вашу проблему, но вам придется определить представления (материализованные индексы) для любых метаданных, которые вы собираетесь запрашивать. Если весь смысл отказа от использования MySQL здесь состоит в том, чтобы избежать индексации всего, то Couch, вероятно, тоже не является правильным решением.

Riak был бы гораздо лучшим вариантом, поскольку он запрашивает ваши данные с помощью map-reduce. Это позволяет вам создавать любые запросы без необходимости предварительной индексации всех ваших данных, как на диване. Миллионы строк не являются проблемой для Riak — не беспокойтесь. Если возникнет необходимость, он также очень хорошо масштабируется, просто добавляя больше узлов (и он также может балансировать сам себя, так что это действительно не проблема).

Поэтому, основываясь на собственном опыте, я бы порекомендовал Riak. Однако, в отличие от вас, у меня нет прямого опыта работы с MongoDB, поэтому вам придется судить об этом самому Риаку (или, может быть, кто-то еще здесь может ответить на это).

person Elad    schedule 19.08.2011
comment
Самое приятное то, что мне не нужно беспокоиться об изменении метаданных. Как только сообщение было создано с метаданными, оно закрепляется за этим сообщением. - person Jey Balachandran; 19.08.2011

Исходя из моего опыта работы с Hbase, это не очень хорошее решение для вашего приложения. Так как:

  1. Не содержит вторичного индекса по умолчанию (вы должны установить плагины или что-то в этом роде). Таким образом, вы можете эффективно искать только по первичному ключу. Я реализовал вторичный индекс, используя hbase и дополнительные таблицы. Таким образом, вы не можете использовать это в онлайн-приложении, потому что для получения результата вы должны запустить задание map/reduce, и это займет много времени для миллионов данных.

  2. Очень сложно поддерживать и настраивать эту БД. Для эффективной работы вы будете использовать HBAse с Hadoop и нужны мощные компьютеры или несколько.

  3. Hbase очень полезен, когда вам нужно создавать сводные отчеты по большому количеству данных. Кажется, вам не нужно.

person Andrej Ludinovskov    schedule 19.08.2011

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

Похоже, вам нужно соединение, поэтому вы можете в основном забыть о CouchDB, пока они не разберутся с многопрофильным кодом, над которым работали (на самом деле не уверен, что он все еще работает).

person Bruno Rohée    schedule 19.08.2011
comment
это только одноуровневое отношение. Так что объединение — не единственный вариант. вы можете: а) встроить запись № пользователя в запись сообщения или б) встроить метаданные, чтобы вам не приходилось искать запись пользователя - person BenG; 06.12.2011

Riak может запрашивать так же быстро, как вы это делаете, зависит от узлов

Mongo позволит вам создать индекс для любого поля, даже если это массив.

CouchDB очень отличается, он строит индексы с использованием сохраненного Map-Reduce (но без сокращения), которые они называют «представлением».

RethinkDB позволит вам использовать SQL, но немного быстрее TokuDB тоже

Redis убьет всех по скорости, но он целиком хранится в оперативной памяти

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

person BenG    schedule 06.12.2011