powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Диалоги между пользователями.
25 сообщений из 30, страница 1 из 2
Диалоги между пользователями.
    #37321537
xing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
День добрый.

Все голову поломал. Не получается спроектировать БД для диалогов между пользователями. Переписка между двумя пользователми это и есть диалог. Нужно вывести список всех диалогов для конкретного пользователя с последним сообщением в диалоге. Т.е. вот так:



Каждый пользователь может удалять свои сообщения.

Пока удалось связать таблицы так:

users (id, name)
messages(id, name)
users_has_messages(id, user_id, messages_id)


Запрос на получения списка диалогов, как на рисунке, не получается. Подскажите, пожалуйста, где я ошибаюсь в проектировании.
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37321729
... ... ...
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
xing,

Можно добавить еще одну таблицу, имеющую два поля: user_id и id из таблицы users_has_messages.
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37321734
xing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А что это дает? Запрос получается монструозный и с if ..
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37321752
... ... ...
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Можно будет заселектить все элементы из этой таблицы по нужному нам пользователю... Т.е. - получится вариант, который Вы описали на рисунке. Разве нет?
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37321810
... ... ...
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Блин, кажись протупил... А почему бы не добавить в таблицу users_has_messages еще два поля: id_user'a (которому это сообщение было адресовано) и сам текст этого сообщения... и можно ее как-нить по другому обозвать (имеется ввиду таблицу). Вот... а при добавлении нового сообщения делать проверку на совпадение id'шок пользователей и подменять текст сообщения (в данном случае, конечно же, будет два обращения к таблице: удаление и добавление). Что-то типа... Как-то так...
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37321844
xing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
... ... ...
Спасибо, за ответы. Так пробовал делать, и добавлял в таблицу users_has_messages, id отправител и id получателя. Все равно красиво свернуть все это дело в диалог - не получается (((
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37321854
xing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мне кажется что изначально спроектировал таблицы неправильно. От того запрос составить не получается. А вот как правильно подобрать архитектуру пока хз.
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37321905
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xing users (id, name)
messages(id, name) Что, одно сообщение может иметь множество отправителей и получателей???
Мне кажется, схема должна быть такая:
users (id, name)
messages(id, name, id отправителя, id получателя)
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37321944
xing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alexeyvgxing users (id, name)
messages(id, name) Что, одно сообщение может иметь множество отправителей и получателей???
Мне кажется, схема должна быть такая:
users (id, name)
messages(id, name, id отправителя, id получателя)



Нет. 2 ссылки на одно сообщение (от отправители и получателя). Чтобы каждый пользователь мог удалить сообщение у себя, но при этом у другого пользователя оно отображалось.
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37322138
... ... ...
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мысль, наверное, абсурдная но она имеет право на "жизнь"... что если в таблицу messages (дропаем users_has_messages) добавить четыре поля (в догонку к имеющимся message_id и message_text):
- id_user_from;
- id_user_to;
- flag_for_user_from;
- flag_for_user_to.
Последние два поля составляют костяк абсурда :)
Идея такая - при удалении одним из пользователей выставлять соответствующий флаг в определенное значение (0 например), когда оба флага выставлены в 0 удалять сообщение из таблицы окончательно. С количеством ссылок не проканает (личное мнение) потому, что мы не будем знать "чья" ссылка осталась.
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37322173
xing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
... ... ... , ммм..не очень понял, как это поможет вывести диалоги. Удаление вроде как не проблема.
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37322939
... ... ...
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Почему-то казалось, что основная проблема - удаление :) Ну да ладно... Вывод диалога: селектим все элементы из таблицы по id (скорее всего по полю "to") нужного нам пользователя и выводим, соответственно, от кого и текст сообщения. Может чего не допонимаю.
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37323015
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xing... ... ... , ммм..не очень понял, как это поможет вывести диалоги. Удаление вроде как не проблема. Вывести простым селектом. Непонятно, какая может быть проблема?

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

xingНет. 2 ссылки на одно сообщение (от отправители и получателя). Чтобы каждый пользователь мог удалить сообщение у себя, но при этом у другого пользователя оно отображалось.Нет, у вас пользователь не может удалить сообщение у себя. Вы сохраняете этот факт - создано сообщение от пользователя А пользователю Б. И сам факт вы не удаляете (т.к. второй пользователь может посмотреть это сообщение).

Кроме того, вам не нужно посылать одно сообщение от пользователей А, Б и В пользователям Г и Д. Так зачем это такую возможность предусматривать в схеме данных? Это усложнит разработку и сопровождление базы.

Вам нужно только предусмотреть возможность не-показа сообщения какому-то из 2-х пользователей.

Это всё учитывается в моём варианте и в варианте "... ... ..."
Я только сразу не предусмотрел этих флагов - не знал о необходимости удаления показа.

... ... ...Последние два поля составляют костяк абсурда :)Да вполне нормальные поля.
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37323191
xing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alexeyvg,

Все гладко только в теории. Попробуйте по вашей схеме вывести список последних сообщений всех диалогов которые ведет пользователь, причем не важно кто автор последнего сообщения (либо сам пользователь либо его собеседник), оно должно выводиться.
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37323218
xing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторКроме того, вам не нужно посылать одно сообщение от пользователей А, Б и В пользователям Г и Д. Так зачем это такую возможность предусматривать в схеме данных? Это усложнит разработку и сопровождление базы.

Вам нужно только предусмотреть возможность не-показа сообщения какому-то из 2-х пользователей.


users (id, name)

1 Иван Иванов
2 Дмитрий Сидоров


Первый пользователь пишет второму :

messages(id, name)

1 Текст_Сообщения

users_has_messages(id, user_id, messages_id)

1 1 1
2 2 1


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


В чем недостаток схемы, не понимаю что-то. Объясните, пожалуйста, примером.
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37323318
Фотография Chop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
три простых таблицы:

[Пользователи]
Id
Caption

[Диалоги]
Id
IdFrom
IdTo
Caption

[Сообщения]
ID
IdDialog
IdUser
Message
ShowWriter (0/1)
ShowReader (0/1)

все поставленные задачи решаются элементарными запросами
ставить галочку "не показывать мне" может кто угодно
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37323332
xing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Chop, можно пример запроса на считываение диалогов юзера, с последним сообщением в нем?

На всякий выкладываю дамп бд:

http://narod.ru/disk/16994212001/test.sql.html


И собственно запрос, который получает список диалогов с последним сообщением в нем:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
SELECT `users`.`id`, `users`.`email`, `messages`.`text`, `messages`.`created` 
FROM `messages_users` AS `m_users_1` 
JOIN `users` ON (if(`m_users_1`.`sender_id`= 1 ,`m_users_1`.`receiver_id`,`m_users_1`.`sender_id`) = `users`.`id`) 
JOIN `messages` ON (`m_users_1`.`message_id` = `messages`.`id`) WHERE `m_users_1`.`message_id` = (SELECT `message_id` 
FROM `messages_users` AS `m_users_2` 
WHERE (`m_users_2`.`user_id` =  1  AND `m_users_2`.`is_deleted` =  0  AND `m_users_1`.`receiver_id` = m_users_2.receiver_id AND `m_users_1`.`sender_id` = m_users_2.sender_id) OR (`m_users_2`.`user_id` =  1  AND `m_users_2`.`is_deleted` =  0  AND `m_users_1`.`receiver_id` = m_users_2.sender_id AND `m_users_2`.`receiver_id` = m_users_1.sender_id)
 ORDER BY `message_id` DESC LIMIT  1 ) AND `user_id` =  1 
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37323346
xing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вопрос как раз, можно ли это сделать проще ?


Chop, как в вашей реализации будет выглядеть подобный запрос? Приведите, пожалуйста, пример.
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37323367
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xingalexeyvg,

Все гладко только в теории. Попробуйте по вашей схеме вывести список последних сообщений всех диалогов которые ведет пользователь, причем не важно кто автор последнего сообщения (либо сам пользователь либо его собеседник), оно должно выводиться. select * from message where user_id in (user_id_from, user_id_to)

где user_id - идентификатор пользователя (переменная или константа).
xingВ чем недостаток схемы, не понимаю что-то. Объясните, пожалуйста, примером.Недостаток схемы в том, что она не отражает реальных процессов.

Если вы сделаете схему, которая просто позволит показать на экране то, что вам надо, это называется "простокод", а такие программисты - "простокодеры" :-)

Вы, как разработчик мождели БД, должны создать такую модель данных, чтобы никакой программист не смог ввести неправильные данные или написать программу, которая покажет на экране что то невразумительное.
Просто что бы у него сама собой для этой модели данных получалась хорошая программа, а для написания ошибок ему пришлось бы сильно поломать голову.

Например, для вашей схемы программист сможет заполнить таблицу такими данными
users_has_messages(id, user_id, messages_id)
1,1,1
2,1,1
3,2,1
4,3,1
5,4,1

Что нужно отобразить на экране? Кто, кому и какое сообщение отправил?

Разумеется, создавать правильные модели необязательно, и заботиться о том, что там будет после вас - тоже, но если есть желание сделать хорошую модель данных, то она ИМХО непохожа на вашу. Или я неправильно понимаю задачу (вам конечно виднее, вы же её знаете).
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37323387
Фотография Chop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xingChop, можно пример запроса на считываение диалогов юзера, с последним сообщением в нем?
можно

где-то так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT
   DISTINCT(tab_Dialog.Id),
   tab_Writer.Caption,
   tab_Message.Message
FROM tab_Message
LEFT JOIN tab_Dialog                   ON tab_Dialog.Id       = tab_Message.IdDialog
LEFT JOIN tab_User AS tab_Writer       ON tab_Writer.Id       = tab_Message.IdUser
LEFT JOIN tab_User AS tab_WriterDialog ON tab_WriterDialog.Id = tab_Dialog.IdFrom
LEFT JOIN tab_User AS tab_ReaderDialog ON tab_ReaderDialog.Id = tab_Dialog.IdTo

WHERE tab_WriterDialog.Id = $MyID OR tab_ReaderDialog.Id = $MyID
  AND tab_Message.Id = SELECT 
                          MAX(tab_Message.Id)
                       FROM tab_Message
                       WHERE tab_Message.IdDialog = tab_Dialog.Id
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37323492
xing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alexeyvg , спасибо за помощь.
Код: plaintext
1.
select * from message where user_id in (user_id_from, user_id_to)
Этим запросом выводятся все сообщения всех диалогов. А нужно именно как на рисунке, все диалоги юзера с текстом последнего сообщения в нем.


Chop , большое спасибо за помощь. Наши запросы идейно похожи. Именно поэтому создал тему, чтобы попробовать уйти от такого громоздкого варианта.
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37323578
Фотография Chop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xing...создал тему, чтобы попробовать уйти от такого громоздкого варианта.да куда уже проще... :)
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37323625
skol
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ндаа...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
create table users(
id
name
)
create table messages(
id
from
to
mbody
from_deleted
to_deleted
)

select dlg, lastid, mbody
from (
select if(from={$USER},to,from) as dlg, max(id) as lastid from messages where to = {$USER} or from = {$USER}
group by if(from={$USER},to,from)
) lastmessages
join messages on messages.id = lastmessages.lastid
where if(messages.from={$USER},from_deleted,to_deleted) =  0 

Здесь, если юзер отметит последнее сообщение как удаленное, диалог исчезнет из списка (до появления нового сообщения в диалоге)
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37323749
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xingЭтим запросом выводятся все сообщения всех диалогов. А нужно именно как на рисунке, все диалоги юзера с текстом последнего сообщения в нем.А, именно как на рисунке?

Ну чего же проще-то...

select u.name,
(
select top 1 m.name
from messages m
where u.user_id in (m.user_id_from, m.user_id_to)
order by m.date desc
) as messages_name
from users u
...
Рейтинг: 0 / 0
Диалоги между пользователями.
    #37323811
xing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
skol, спасибо большое за наводку. пытаюсь победить теперь проблему:

авторесли юзер отметит последнее сообщение как удаленное, диалог исчезнет из списка (до появления нового сообщения в диалоге)
...
Рейтинг: 0 / 0
25 сообщений из 30, страница 1 из 2
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Диалоги между пользователями.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]