Масштабируемая база данных MySQL для почтовых сообщений - PullRequest
5 голосов
/ 10 февраля 2010

Предположим, у нас есть популярный сайт. Нам нужно реализовать почтовый обмен сообщениями между пользователями. Типичное решение - использовать 2 таблицы:

Пользователи (user_id)

Сообщения (message_id, sender_id (указывает на user_id), receive_id (ссылается на user_id), тему, тело).

Этот метод имеет 2 существенных ограничения

  1. Все сообщения всех пользователей хранятся в одной таблице, что приводит к высокой загрузке и снижению общей производительности базы данных.
  2. Когда кому-то нужно отправить сообщение нескольким пользователям одновременно, сообщение копируется (receients_count) раз.

В другом решении используются 3 таблицы:

Пользователи (user_id)

Sent_messages (sent_id, sender_id (ссылки user_id), тема, тело)

Received_messages (sent_id, receive_id (ссылки на user_id), тема, тело)

тема и текст полученного сообщения копируются из соответствующих полей sent_messages.

Этот метод приводит к

  1. Денормализация базы данных путем копирования информации из одной таблицы в другую
  2. Пользователи могут фактически удалять отправленные / полученные сообщения, не удаляя их из получателей / отправителей.
  3. Сообщения занимают примерно в 2 раза больше места
  4. Каждая таблица загружается примерно в 2 раза меньше.

Итак, вот вопросы:

  1. Какой из рассмотренных проектов лучше подходит для высокой нагрузки и масштабируемости? (Я думаю это второй)
  2. Есть ли другой дизайн базы данных, который может справиться с высокой нагрузкой? Что это? Каковы ограничения?

Спасибо!

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

UPDATE

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

Ответы [ 2 ]

3 голосов
/ 10 февраля 2010

Возможно, вы захотите избежать многократного копирования тела сообщения в случае, если сообщение отправлено нескольким получателям. Вот еще один вариант, который вы можете рассмотреть:

  • пользователи (user_id)

  • сообщений (message_id, sender_id, subject, тело)

  • полученные_ сообщения (идентификатор сообщения, идентификатор пользователя, адрес_режима, удален)

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

Правила таковы:

  • Сообщение может отправлять только один пользователь, указанный в sender_id каждого сообщения.
  • Каждый получатель будет определен в таблице receive_messages. Поле address_mode может определять, было ли сообщение отправлено получателю напрямую, или как CC, или, возможно, как BCC. Это поле явно необязательно.
  • Удаленные сообщения получателей помечают удаленный флаг в таблице receive_messages.
  • Переадресованные и отвеченные сообщения должны быть воссозданы с новым sender_id. Тело сообщения может быть затем изменено.

Вот некоторые из преимуществ:

  • Это занимает меньше места, чем две опции, упомянутые в исходном вопросе, особенно если пользователи обычно отправляют сообщения нескольким получателям.
  • Более простое кэширование таблицы сообщений, поскольку сообщения никогда не дублируются.
  • Получатель, удаляющий сообщение, не удалит информацию о том, что сообщение было отправлено этому пользователю. Он будет просто помечен как «удаленный» в таблице receive_messages.
  • И вы также получите нормализованную модель.

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

1 голос
/ 10 февраля 2010

В целом размер базы данных не будет сильно беспокоить. Скорость намного важнее.

Поэтому я бы соблазнился пойти на второй вариант. Как вы упомянули, это значительно упрощает удаление сообщений, и я уверен, что это очень распространенный способ сделать это.

...