Я создал систему обмена сообщениями для пользователей, что позволяет им отправлять сообщение другому пользователю. Если это первый раз, когда они говорили, начинается новый разговор, если не старый разговор продолжается.
Входящие пользователей перечисляют все разговоры, которые пользователь имел со всеми другими пользователями, которые затем упорядочиваются по цепочке, в которой есть последняя запись.
Пользователь может иметь только один разговор с другим пользователем.
Когда пользователь нажимает на одну из этих бесед, они переходят на страницу, показывающую весь разговор, который у них был с самыми новыми сообщениями вверху. Так что это похоже на функциональность чата обмена сообщениями.
У меня есть две таблицы:
- userconversation
- UserMessages
userconversation
Содержит идентификатор автоматического инкремента, который является идентификатором разговора, вместе с userId и friendId.
Тот, кто инициирует первый разговор, всегда будет userId и получателем friendId, это никогда не изменится для этого разговора.
+----+--------+----------+
| id | userId | friendId |
+----+--------+----------+
UserMessages
Содержит конкретные сообщения, а также флаг чтения, время и диалогId
+----+---------+--------+------+------+----------------+
| id | message | userId | read | time | conversationId |
+----+---------+--------+------+------+----------------+
Как это работает
Когда пользователь переходит к сообщению другого пользователя, будет запущен запрос, чтобы проверить, совпадают ли оба пользователя в таблице пользовательского диалога, если используется conversationId
, и разговор продолжается, если не создается новая строка для них с уникальным conversationId
.
Где он усложняется
До сих пор все хорошо, однако когда дело доходит до отображения сообщения "Входящие" всех разговоров, отсортированного по последнему сообщению, сложно сделать один запрос.
Чтобы иметь возможность перечислять разговоры, вы должны сначала найти последнюю запись каждого разговора, но поскольку вы не можете заказать ее перед группой, это невозможно сделать с одним запросом на две таблицы, поэтому я должен использовать следующее:
SELECT
c.id,
c.userId,
c.friendId,
m2.message,
m2.read,
UNIX_TIMESTAMP(m2.time),
user1.username,
user2.username
FROM
(SELECT MAX(m1.id) AS MessageID
FROM usermessages m1
GROUP BY m1.conversationId) latest_msg
INNER JOIN usermessages m2 ON latest_msg.MessageID = m2.id
INNER JOIN userconversation c ON m2.conversationId = c.id
INNER JOIN user user1 ON c.userId = user.id
INNER JOIN user user2 ON c.friendId = user.id
WHERE c.userId = :userId OR c.friendId = :userId
ORDER BY m2.id DESC
LIMIT 10
Я просто не думаю, что это лучший способ, которым это можно сделать, но не может думать о том, как другие методы тоже подходят к нему?
Таблица базы данных - это InnoDB, чтобы ускорить объединение и улучшить целостность данных, поэтому я не могу иметь две строки автоматического увеличения.
Есть ли другой способ избавиться от таблицы userconversation и создать уникальный идентификатор, который будет помещен в столбец talkId? Я мог бы просто переместить userId и friendId на usermessages... но это создаст много избыточных данных?