Здравствуйте, никак не могу придумать хорошую структуру для обмена диалогами на сайте с учетом условий:
1. Пользователь может общаться тет-а-тет с другим пользователем.
2. Может общаться с группой пользователей (беседа)
Сама Система сообщений аналог системы диалогов социальной сети ВКонтакте.
К примеру есть таблицы:
user
id, email ...
Dialog
id, name
Message
Id, sender_id, dialog_id, text
UserDialog
user_id, dialog_id
Вот дальше уже моя голова не варит - как правильно проверять наличие диалогов между пользователями. Я предполагаю, что мы сначала создаём сообщение и выбираем получателя, потом проверяем если ли ранее такой диалог между пользователями. Если он есть, тогда получаем id диалога записываем в таблицу сообщений и сохраняемся. Если нет, то создаём.
Подозреваю, Message должен иметь ещё и получателя (чат, а не пользователь), а Dialog и UserDialog не нужны, если имеется в виду диалог двух людей, лучше что-то общее - Беседа или Чат, которые могут содержать любое количество отправителей и получателей. Соответственно, сообщение отправляется в чат, а оттуда по пользователям распределяется.
Валерий Гутин, благодарю. У меня в принципе похожая система. Только не пойму здесь связующую таблицу user_to_dialog. Правильно ли я понял, что при диалоге двух пользователей записывается два user_id и id диалога?
Если да, то как потом проверять наличие диалога между этими двумя пользователями? У меня в этом проблема и на моей схеме...
Максим Ворожцов, по-моему, типичный MVC: участники чата - подписчики на событие, их можно быть любое количество, в то же время все они имеют возможность в него писать, каждое сообщение - событие.
Сергей Мелодин, а можете примерно написать таблицу? Не очень понимаю как это сделать в сообщениях.
Я предполагал просто в связующей таблице добавлять пользователей, которые имеют доступ к диалогу.
В вашем случае получится некий костыль. То есть кто кому будет писать в диалоге? Как-то будет не эффективное использование этих двух колонок. По-моему мнению. Ведь в диалоге эти значения будут пустыми.
Мне нравится вариант выше. Однако не понимаю как проверить наличие диалога между этими пользователями.
имхо вы серьезно множите сущности на простой задаче. Думаю достаточно 2 таблиц для хранения всего.
1) собственно месажи
id | sender_id | reciver_id | chatroom_id | message | datetime | readed
2) чатрум( поля на выбор)
и логикой рулить уже что это.
Если есть сендер и ресивер но нет чатрумид - личный диалог,
Если нет ресивера и есть чатрум - общий чат,
Если есть все 3 - общий чат с личным обращением, как раз как в вк.
UPD: если есть необходимость в уровнях доступа к чатам - тогда естественно понадобится дополнительная таблица с рестрикшн полиси и группами пользователей, но это уже имхо немного выходит за рамки первоначальной задачи.
Благодарю) Пожалуй то что нужно)) А то весь мозг сломал как лучше сделать. Однако от таблицы "dialog" не буду избавляться из-за дальнейшего проектирования. Чтобы не нагружать базу данных при выборке только диалогов. Диалогов может быть не много, а вот сообщений может быть много. И при большом объеме может быть нагрузка на базу...
2) Для бд средней и низкой нагрузкой считается выборка из таблиц с количеством около 1 миллиона записей, если индексы расставлены верно. я бы не множил сущности и делал в одной таблице.
Хотя и подход с делением на несколько таблиц будет верным решением в некоторых случаях, например если понадобится разный функционал для чата и личек. Можно создать общий базовый класс и от него наследовать отдельно диалоги и отдельно чаты.
мелочи:
таблицы принято называть не кэмелкейсом а через андерскор.
что содержит userdialog? что с чем объединяют его поля?
нет даты сообщения, их надо как-то сортировать, и как то примерно видеть кто когда отвечал.
name в диалоге зачем? Создайте запись в таблице чатрум: id | name и там храните имя, по чатрум_ид объединяйте с диалогом и получите имя, хранить имя диалога 400 раз не есть оптимально.
2)
— Что соединять UserDialog?
Она соединяет пользователя и диалог. Своеобразный доступ к диалогу. Чтобы не делать запрос в Сообщения сначала делаем запрос на наличие такого диалога.
—Нет даты Сообщения.
В данном случае не предусмотрел, однако это уже детали наработок. На реальной таблице они, конечно, есть. Так же как статус: Сообщения (прочитан не прочитан), скрытие сообщение от пользователя (удалён, виден)
— зачем роле name в диалоге?
Когда диалог не является приватным, то можно задать название беседы (комнаты).