Как построить базу данных под личные сообщения?

Доброго вечера!

Связал XMPP с HTTP и теперь застрял на вопросе - каким образом организовать данные в базе данных для хранения истории переписки пользователей с минимальными нагрузками на сервер под MySql с расчетом на большой поток данных в перспективы, дабы избежать перестройки проекта в будущем.

Очень надеюсь на то, что тут мне подскажут правильное направление. Спасибо
  • Вопрос задан
  • 9282 просмотра
Решения вопроса 1
@JoveLebedev Автор вопроса
оставлю это здесь habrahabr.ru/post/66151
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
yokotoka
@yokotoka
Python guru
Знаю, что многие нагруженные сервисы просто делают денормализацию данных (не только для чатов, но и для новостей и т.п.). Как правило, каждое отправленное сообщение в общем чате (или один на один) попадает одновременно каждому участнику чата в его личную ленту/таблицу/плоский файл. Это решает проблемы загруженности (каждый пользователь читает только свой набор отдельных файлов/таблиц/строк и не нагружает общие хранилища данных, где могут быть миллиарды записей при решении задачи "в лоб"). Также это решает проблему с удалением сообщений (один может удалить переписку, а другой - оставить себе на память). А ещё это автоматически решает проблему видимости сообщений в общем чате - если человека пригласили в беседу только что, то он не видит предыдущие сообщения участников. За попадание сообщений в "личную зону" каждого пользователя отвечает не база, а контроллер, который дублирует сообщения всем.

Да, некоторые операции усложнятся, но часто ли вам нужно количество отправленных пользователем личных сообщений, или какая-нибудь статистика по личным перепискам всех пользователей, чтобы ради небольшого выигрыша по скорости доступа к этим данным делать всю систему отправки сообщений с тормозами? Для всех таких редко нужных запросов можно прикрутить отдельный поисковый индексатор и счётчики, map/reduce-алгоритмы и т.п.

Представьте, что вы отправляете копии пригласительные на свадьбу друзьям и родственникам. Каждая копия - это отдельная сущность. И если один приглашение разорвёт - то у остальных оно не должно разорваться автоматически. Кто-то захочет что-то на нём написать, например, телефон сантехника. Кто-то сомнёт и подложит под ножку качающегося стола. Кто-то сделает ксерокопию и пригласит ещё кого-то на вашу свадьбу без вашего ведома. При этом - это будут разные пригласительные, с одинаковым содержанием. То же самое с сообщениями и чатами.

Кстати, необязательно хранить систему личных сообщений в базе. Можно, но необязательно. Для этого даже тупо xml'ы/json'ы подойдут. Ведь что чаще всего нужно от чата собеседнику? Чтобы 1) отправить сообщение, чтобы его прочитали; 2) получить сообщение; 3) заглянуть в историю чата. Это прекрасно ложится на модель "каждому пользователю - по отдельной копии каждого чата". Да, денормализация, но почитайте выше пример про пригласительные и ксерокс. В вашем случае контроллер будет делать "ксерокопии" письма и отправлять их всем адресатам. А что с этим письмом делать дальше - уже дело каждого.
Ответ написан
thewind
@thewind
php программист, front / backend developer
Так вы напишите, как сами придумали и в чем сомневаетесь. А то получается не сайт советов и помощи, а сайт решения чужих проблем под ключ.
Ответ написан
smart
@smart
вы меня знаете
Главный вопрос - каковы планируемые характеристики системы? Сколько юзеров, сколько сообщений, какая нагрузка чтение-запись, сколько надо хранить сообщения, какие требования по отказоустойчивости, наконец, какие ресурсы для разработки доступны и т.п.

И исходя из этого можно дать советы. Подозреваю, что главным советом будет вопрос - а зачем вам mysql? Есть множество способов организовать механику и хранение чата более эффективно: redis (в нем есть механизм publish/subscribe, удобный для организации чатов), mongodb (тоже можно сделать pubsub через tailable cursor), riak (шикарно скейлится) и так далее.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы