За последние 24 часа нас посетили 22774 программиста и 1273 робота. Сейчас ищут 756 программистов ...

Система сообщений

Тема в разделе "Решения, алгоритмы", создана пользователем Intrerio, 21 мар 2016.

  1. Intrerio

    Intrerio Активный пользователь

    С нами с:
    20 мар 2015
    Сообщения:
    176
    Симпатии:
    7
    Добрый день всем форумчанам. Дело вот в чем.
    Пишу внутреннюю переписку (внешний вид беру с ВКонтакте). Создал таблицу в БД
    id from to date_send date_read status msg

    Все построено на ajax+mysql_php.
    Проблесмка вся вот в чем... Сама система отправки и принятия сообщений работает нормально, а вот есть страничка на которую я хочу вывести список диалогов.
    Код (PHP):
    1. <span class="syntaxdefault">$sel</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">mysql_query</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"SELECT&nbsp;DISTINCT&nbsp;*&nbsp;FROM&nbsp;`messages`&nbsp;WHERE&nbsp;from_usr='"</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">$my_id</span><span class="syntaxkeyword">.</span><span class="syntaxstring">"'&nbsp;OR&nbsp;to_usr='"</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">$my_id</span><span class="syntaxkeyword">.</span><span class="syntaxstring">"'&nbsp;ORDER&nbsp;BY&nbsp;date_send&nbsp;ASC"</span><span class="syntaxkeyword">);<br />&nbsp;</span><span class="syntaxdefault"></span>
    Тут я ищу в БД все упоминания личного айди. При таком раскладе выводит вообще все что можно и DISTINCT что есть что нет пофигу.
    Попробовал такой вариант
    Код (PHP):
    1. <span class="syntaxdefault">$sel</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">mysql_query</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"SELECT&nbsp;DISTINCT&nbsp;*&nbsp;FROM&nbsp;`messages`&nbsp;WHERE&nbsp;from_usr='"</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">$my_id</span><span class="syntaxkeyword">.</span><span class="syntaxstring">"'&nbsp;OR&nbsp;to_usr='"</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">$my_id</span><span class="syntaxkeyword">.</span><span class="syntaxstring">"'&nbsp;GROUP&nbsp;BY&nbsp;from_usr,&nbsp;to_usr&nbsp;ORDER&nbsp;BY&nbsp;date_send&nbsp;ASC"</span><span class="syntaxkeyword">);&nbsp;</span><span class="syntaxdefault"></span>
    В таком виде выбрасывает диалоги по два раза. Тоесть, смотрит есть ли айди в отправленных и в полученных.
    Короче, подтолкните к мысле что сделать чтоб все было красиво
     
  2. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.632
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    В смысле?

    Городишь еще один страничка <матное слово>?
     
  3. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.074
    Симпатии:
    1.237
    Адрес:
    там-сям
    Intrerio, ты в курсе, что ВК допускает и более двух участников переписки? Я думаю нужна структура не from+to, а похитрее маленько. У самого ВК вроде бы noSQL какой-то самописный для сообщений, но мы сумеем имитировать на майсиквеле ;)

    Добавлено спустя некоторое время:
    Я вижу это как три таблицы (не считая Пользователей):
    - Темы (Ид, Дата, Заголовок, Ид_Последнего_Сообщения_Темы),
    - Сообщения (Ид, Ид_Темы, Ид_Пользователя, Текст) и
    - Участники_Темы (Ид_Темы, Ид_Пользователя)
    жирным выделил первичный ключ таблиц.

    Пользователи и Темы связаны как многие-ко-многим, поэтому понадобилась промежуточная таблица-связка.

    и выборка последних тем для текущего пользователя вот так:
    Код (PHP):
    1. SELECT t.`subject`, m.*
    2. FROM 
    3.   `topics`      AS t JOIN
    4.   `messages`    AS m JOIN ON m.`id` = t.`last_msg_id` JOIN
    5.   `topic_users` AS tu ON tu.`topic_id` = t.`id`
    6. WHERE
    7.   tu.`user_id` = :uid
    8. ORDER BY m.`msg_date` DESC
    9. LIMIT 20
    а выборка сообщений конкретной темы:
    Код (PHP):
    1. SELECT t.`subject`, m.*
    2. FROM 
    3.   `messages`    AS m JOIN
    4.   `topics`      AS t  ON t.`id` = m.`topic_id` 
    5. WHERE
    6.   m.`topic_id` = :tid
    7. ORDER BY m.`msg_date` DESC
    8. LIMIT 20
    Добавлено спустя 6 минут 49 секунд:
    [оффтопик]Не используй DISTINCT, ты готовишь его неправильно. Просто забудь, что есть такое слово, это поможет тебе двигаться дальше.[/оффтопик]
     
  4. Intrerio

    Intrerio Активный пользователь

    С нами с:
    20 мар 2015
    Сообщения:
    176
    Симпатии:
    7
    На счет ВК. Я не беру технологию ВК я беру лишь отображение ВК. Тоесть есть список диалогов и при клике на диалог - пользователь переходит в диалог с данным пользователем. Вот и вся аналогия с ВК

    Добавлено спустя 8 минут 40 секунд:
    Сейчас сделаю доп.таблицы

    За последних два года самый наглядный ответ в инете)).

    Я так понимаю что от DISTINCT лучше отказатся не только в этом случае но и в других?
     
  5. Intrerio

    Intrerio Активный пользователь

    С нами с:
    20 мар 2015
    Сообщения:
    176
    Симпатии:
    7
    Внес изменения в саму БД, проверил на тестовом скрипте - все норма. Только вот вопрос, в user_id мы вносим один айди отправителя или отправителя и получателя. Просто если только одно айди тогда каким образом система будет понимать что данный диалог нужно отобразить в профиле у двух пользователей?
     
  6. Alex5646

    Alex5646 Новичок

    С нами с:
    29 дек 2015
    Сообщения:
    277
    Симпатии:
    4
    Адрес:
    От верлюда
    Если тебе нужно знать id отправителя и получателя и для этого не хватает колонки в таблице, так добавь её. В чём проблема?
     
  7. Intrerio

    Intrerio Активный пользователь

    С нами с:
    20 мар 2015
    Сообщения:
    176
    Симпатии:
    7
    Добавлено спустя 2 минуты 21 секунду:
    проблема в том что если расчитывать на колективный чат а не по принцыпу один на один, то добавляя колонку ничего не изменится. Тут либо добавлять айди через разделитель и в цыкле разбивать массив и искать айди. Словом, хочу услышать совет artoodetoo

    Добавлено спустя 11 минут 6 секунд:
    Наконецто понял. Сейчас все сделаю и отпишусь
     
  8. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.074
    Симпатии:
    1.237
    Адрес:
    там-сям
    Надеюсь и правда понял. Отношение многие-ко-многим это типичный кейс. Разберешся один раз, потом будешь на автомате въезжать в другие подобные.

    Distinct гарантирует, что все перечисленые во фразе SELECT поля будут уникальны. То есть сочетание этих полей в записи, а не каждое поле в отдельности. Distinct равнозначен GROUP BY по полному списку выводимых полей.
    Чем больше у тебя полей в SELECT, тем вероятнее, что наличие DISTINCT не влияет на результат, но тем больше он жрёт ресурсов. Звездочка в SELECT или наличие GROUP BY это 99.99% вероятности, что DISTINCT здесь не нужен.
     
  9. VirusXS

    VirusXS Новичок

    С нами с:
    21 ноя 2016
    Сообщения:
    1
    Симпатии:
    0
    Мб не лучший вариант, но я делал так. Таблица с диалогами где есть id диалога и список участников(можно 2 участника). и таблица с сообщениями где id сообщения| id диалога которому принадлежит сообщение| id пользователя| сообщение.
    Так легко получить все диалоги пользователя, по id диалога найти все сообщения. Ну естественно по сообщениям знаем кто отправлял а по id диалога, кому.