Требуется помощь специалистов

1. horoshinkin777 (27.01.2019 / 10:22)
Вот набросал скрипт личных сообщений с диалогами. Как вам такой вариант? Пока функционал только вывести список диалогов и сообщений

<?php

require 'db.php';
$start = microtime(true);


$my_login = $_SESSION['my_login'];
$nomy_login = $_GET['u'];





$row = mysqli_query($db, "SELECT dialog1, dialog2 FROM messages2 WHERE (otkogo = '$my_login' OR komu = '$my_login') AND (dialog1 != '$my_login' OR dialog2 != '$my_login') AND (dialog1 != '') AND (dialog2 != '') ORDER BY tdialog DESC;");


while($r=mysqli_fetch_array($row))
{
if ($r['dialog1'] == $my_login){echo '<a href="dialogs2.php?u='.$r['dialog2'].'">'.$r['dialog2'].'</a><br>';}else{echo '<a href="dialogs2.php?u='.$r['dialog1'].'">'.$r['dialog1'].'</a><br>';}

}



$row = mysqli_query($db, "SELECT * FROM messages2 WHERE (otkogo = '$my_login' AND komu = '$nomy_login') OR (otkogo = '$nomy_login' AND komu = '$my_login') ORDER BY id DESC;");


while($r=mysqli_fetch_array($row))
{

echo $r['otkogo'].$r['message'].'<br>';
}



$end = microtime(true);
$tt = $end-$start;
echo '<br>Время выполнения '.$tt;
?>

сама таблица состоит из колонок:
айди, откого, кому, сообщение, диалог1, диалог2, время последнего обновления диалога.

где диалог1 и диалог2 это участники диалога

2. horoshinkin777 (27.01.2019 / 11:00)
Может что то исправить можно чтоб быстрее работало?

3. JiGaN (27.01.2019 / 12:48)
Не совсем понятно, если есть от кого и кому в проверке запроса, для чего еще проверка диалога?

4. horoshinkin777 (27.01.2019 / 12:54)
JiGaN, ну если общаются 100 человек на сайте то чтобы узнать к какому диалогу отнести сообщение.
в диалоге максимум 2 человека

Добавлено через 03:36 сек.
при отправке сообщения идет проверка есть ли диалог с таким юзером или нет. Если нет то создается новый один раз на все сообщения. если есть диалог то просто обновление метки времени диалога

5. Андрей (27.01.2019 / 14:08)
типа если применить JOIN то вполне возможно вытащить все нужные запросы

6. horoshinkin777 (27.01.2019 / 14:21)
Андрей, я их итак все могу вытащить. мне интересно этот скрипт норм?

7. ZiGR (27.01.2019 / 20:48)
horoshinkin777, нет, не норм. MySQL - это реляционная СУБД. Тут ничем подобным не пахнет. Ещё и логины текстовые используются в каждой записи, да?

Как минимум, физическую схему базы данных нужно посмотреть.
И схеме приложить те функции, которые должны быть удовлетворены при помощи предлагаемой схемы.

8. horoshinkin777 (28.01.2019 / 05:07)
ZiGR, ниче не понял из твоих слов))

9. Вантуз-мен (28.01.2019 / 14:33)
horoshinkin777, я тебе уже говорил, что так не проектируют таблицы, у тебя очень много индексов будет, таблица не оптимальна, не нормализована
если у тебя обычная переписка, то можно обойтись двумя полями user_id, author_id
где user_id это мой id, а author_id - id отправителя
теперь чтобы получить все переписки достаточно сделать составной индекс из 2-х полей
Все переписки where user_id = 1
все диалоги нужны группируй по author_id

Если у тебя диалоги со множеством пользователей, нужно делать еще отдельную таблицу, типа dialogs

а в messages добавить поле dialog_id
и группировать по диалогам,
в плане нормализации https://habr.com/ru/post/254773 , вариант который я предложил с двумя участниками не прям уж очень правильный, но вполне оптимальный для работы

а то что ты придумал, прости, но это только на помойку

Добавлено через 07:07 сек.
select
   * 
from
   `messages` 
   inner join
      (
         select
            `author_id`,
            max(created_at) as last_created_at 
         from
            `messages` 
         where
            `user_id` = 1
         group by
            `author_id`
      )
      as `latest_message` 
      on `messages`.`created_at` = `latest_message`.`last_created_at` 
      and messages.author_id = latest_message.author_id 
where
   `user_id` = 1
order by
   `created_at` desc
Это список диалогов

Добавлено через 07:59 сек.
А это просмотр диалога
select * from `messages` where `user_id` = 1 and `author_id` = 2 order by `created_at` desc


10. Вантуз-мен (28.01.2019 / 14:44)
Explain

11. horoshinkin777 (28.01.2019 / 18:34)
Вантуз-мен, c моим кодом из 1000000 сообщений ищет диалоги в которых я учавствовал всего за 0.06 сек. Это разве плохо?

12. Денис (28.01.2019 / 20:00)
horoshinkin777, тут другой вопрос... Когда из 1000000 сообщений тысяч 10 пользователей в один момент запрашивать свои диалоги будут, как оно будет?

13. Вантуз-мен (28.01.2019 / 20:26)
horoshinkin777, скинь структуру пожалуйста таблицы, я дома потестирую

14. nickzakharevich (29.01.2019 / 01:34)
Всё нормально. Чтобы быстрее работало ограничивай запросы лимитом. Догружай остальное при необходимости. Товарищ Хорошинкин777, всё уже придумано и реализовано не одну тысячу раз. И вывод на страницу должен быть в конце и единожды.

15. horoshinkin777 (29.01.2019 / 07:49)
переделал короче все. для диалогов сделал отдельную таблицу

16. horoshinkin777 (29.01.2019 / 08:04)
dialog

Добавлено через 02:07 сек.
Сообщения

Добавлено через 04:21 сек.
Выборка диалогов
$query1 = mysqli_query($db, "SELECT u1, u2 FROM dialog WHERE u1 = '$my_id' OR u2 = '$my_id'");

Выборка сообщений
$query1 = mysqli_query($db, "SELECT otkogo, text FROM test WHERE did = '$did'");

Добавлено через 05:48 сек.
Такой вариант наверно проще и лучше

17. horoshinkin777 (29.01.2019 / 16:14)
Вантуз-мен, ну скинул

18. nickzakharevich (02.02.2019 / 11:30)
Не хватает лимитов и дальнейшей подгрузки при необходимости.

URL: https://visavi.net/topics/44138