Добрый день всем форумчанам. Дело вот в чем. Пишу внутреннюю переписку (внешний вид беру с ВКонтакте). Создал таблицу в БД id from to date_send date_read status msg Все построено на ajax+mysql_php. Проблесмка вся вот в чем... Сама система отправки и принятия сообщений работает нормально, а вот есть страничка на которую я хочу вывести список диалогов. Код (PHP): <span class="syntaxdefault">$sel</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">mysql_query</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"SELECT DISTINCT * FROM `messages` WHERE from_usr='"</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">$my_id</span><span class="syntaxkeyword">.</span><span class="syntaxstring">"' OR to_usr='"</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">$my_id</span><span class="syntaxkeyword">.</span><span class="syntaxstring">"' ORDER BY date_send ASC"</span><span class="syntaxkeyword">);<br /> </span><span class="syntaxdefault"></span> Тут я ищу в БД все упоминания личного айди. При таком раскладе выводит вообще все что можно и DISTINCT что есть что нет пофигу. Попробовал такой вариант Код (PHP): <span class="syntaxdefault">$sel</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">mysql_query</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"SELECT DISTINCT * FROM `messages` WHERE from_usr='"</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">$my_id</span><span class="syntaxkeyword">.</span><span class="syntaxstring">"' OR to_usr='"</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">$my_id</span><span class="syntaxkeyword">.</span><span class="syntaxstring">"' GROUP BY from_usr, to_usr ORDER BY date_send ASC"</span><span class="syntaxkeyword">); </span><span class="syntaxdefault"></span> В таком виде выбрасывает диалоги по два раза. Тоесть, смотрит есть ли айди в отправленных и в полученных. Короче, подтолкните к мысле что сделать чтоб все было красиво
Intrerio, ты в курсе, что ВК допускает и более двух участников переписки? Я думаю нужна структура не from+to, а похитрее маленько. У самого ВК вроде бы noSQL какой-то самописный для сообщений, но мы сумеем имитировать на майсиквеле Добавлено спустя некоторое время: Я вижу это как три таблицы (не считая Пользователей): - Темы (Ид, Дата, Заголовок, Ид_Последнего_Сообщения_Темы), - Сообщения (Ид, Ид_Темы, Ид_Пользователя, Текст) и - Участники_Темы (Ид_Темы, Ид_Пользователя) жирным выделил первичный ключ таблиц. Пользователи и Темы связаны как многие-ко-многим, поэтому понадобилась промежуточная таблица-связка. и выборка последних тем для текущего пользователя вот так: Код (PHP): SELECT t.`subject`, m.* FROM `topics` AS t JOIN `messages` AS m JOIN ON m.`id` = t.`last_msg_id` JOIN `topic_users` AS tu ON tu.`topic_id` = t.`id` WHERE tu.`user_id` = :uid ORDER BY m.`msg_date` DESC LIMIT 20 а выборка сообщений конкретной темы: Код (PHP): SELECT t.`subject`, m.* FROM `messages` AS m JOIN `topics` AS t ON t.`id` = m.`topic_id` WHERE m.`topic_id` = :tid ORDER BY m.`msg_date` DESC LIMIT 20 Добавлено спустя 6 минут 49 секунд: [оффтопик]Не используй DISTINCT, ты готовишь его неправильно. Просто забудь, что есть такое слово, это поможет тебе двигаться дальше.[/оффтопик]
На счет ВК. Я не беру технологию ВК я беру лишь отображение ВК. Тоесть есть список диалогов и при клике на диалог - пользователь переходит в диалог с данным пользователем. Вот и вся аналогия с ВК Добавлено спустя 8 минут 40 секунд: Сейчас сделаю доп.таблицы За последних два года самый наглядный ответ в инете)). Я так понимаю что от DISTINCT лучше отказатся не только в этом случае но и в других?
Внес изменения в саму БД, проверил на тестовом скрипте - все норма. Только вот вопрос, в user_id мы вносим один айди отправителя или отправителя и получателя. Просто если только одно айди тогда каким образом система будет понимать что данный диалог нужно отобразить в профиле у двух пользователей?
Если тебе нужно знать id отправителя и получателя и для этого не хватает колонки в таблице, так добавь её. В чём проблема?
Добавлено спустя 2 минуты 21 секунду: проблема в том что если расчитывать на колективный чат а не по принцыпу один на один, то добавляя колонку ничего не изменится. Тут либо добавлять айди через разделитель и в цыкле разбивать массив и искать айди. Словом, хочу услышать совет artoodetoo Добавлено спустя 11 минут 6 секунд: Наконецто понял. Сейчас все сделаю и отпишусь
Надеюсь и правда понял. Отношение многие-ко-многим это типичный кейс. Разберешся один раз, потом будешь на автомате въезжать в другие подобные. Distinct гарантирует, что все перечисленые во фразе SELECT поля будут уникальны. То есть сочетание этих полей в записи, а не каждое поле в отдельности. Distinct равнозначен GROUP BY по полному списку выводимых полей. Чем больше у тебя полей в SELECT, тем вероятнее, что наличие DISTINCT не влияет на результат, но тем больше он жрёт ресурсов. Звездочка в SELECT или наличие GROUP BY это 99.99% вероятности, что DISTINCT здесь не нужен.
Мб не лучший вариант, но я делал так. Таблица с диалогами где есть id диалога и список участников(можно 2 участника). и таблица с сообщениями где id сообщения| id диалога которому принадлежит сообщение| id пользователя| сообщение. Так легко получить все диалоги пользователя, по id диалога найти все сообщения. Ну естественно по сообщениям знаем кто отправлял а по id диалога, кому.