我正在为一个网站编写一个私人消息系统。用户可以与多个其他用户之一(包括他/她自己)进行通信。我有三张桌子
- users
- conversation_list
- conversation_messages
对于我的数据库,如下所示。
该users
表包含所有用户
该conversation_messages
表保存写入的消息,每条消息都有一个 conversation_id
保存每个对话中的conversation_list
参与者列表
当然,每个对话都由唯一的标识conversation_id
现在,我希望从表中查询以下内容:
- getInboxMessages <-- Difficult
Get all new messages directed to a user.
Replies to a message should be grouped as a conversation
and the latest reply previewed
- getOutboxMessages
Get all messages sent by the user.
Replies to messages should be grouped as a conversation
and only the latest reply previewed
- getConversation
Each message with all replies
- isUnreadMessage
Check if a message has been read or not
- getNumberOfUnreadMessages
Get the number of unread messages
到目前为止我所做的如下所示。
getOutboxMessages
, getConversation
,isUnreadMessage
并且getNumberOfUnreadMessages
可以工作,尽管查询可能不是最佳的!我很难获得getInboxMessages
.
我只能在收件箱中获取对话的第一个线程。任何其他线程(回复)都不会作为新消息出现,而是作为已发送消息(发件箱)出现。但是,对消息的任何回复(对话的一部分)都不会显示为新消息!
一个想法?热烈欢迎任何支持获取正确的 getInboxMessages 查询以及优化查询!
CREATE TABLE IF NOT EXISTS `conversation_list` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(50) NOT NULL,
`conversation_id` int(11) NOT NULL,
`added_by` varchar(50) NOT NULL,
`date_created` int(11) NOT NULL,
`date_lastPost` int(11) NOT NULL,
`date_lastView` int(11) NOT NULL,
`status` tinyint(1) NOT NULL,
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `conversation_messages` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sender` varchar(50) DEFAULT NULL,
`conversation_id` int(11) NOT NULL,
`message` text NOT NULL,
`date_created` int(11) NOT NULL,
`status` tinyint(1) NOT NULL,
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `users` (
`username` varchar(30) NOT NULL,
`password` varchar(40) default NULL,
`usersalt` varchar(8) NOT NULL,
`userid` varchar(32) default NULL,
`userlevel` tinyint(1) unsigned NOT NULL,
`email` varchar(50) default NULL,
`timestamp` int(11) unsigned NOT NULL,
`regdate` int(11) unsigned NOT NULL,
PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
查询
getInboxMessages
================
SELECT *
FROM conversation_messages AS m
JOIN
(SELECT mx.conversation_id,
MAX(mx.date_created) AS MaxTime
FROM conversation_messages AS mx
GROUP BY mx.conversation_id) AS mx ON m.conversation_id = mx.conversation_id
AND m.date_created = mx.MaxTime
JOIN
(SELECT mu.conversation_id
FROM conversation_list AS mu
WHERE mu.user_id = :subuser
GROUP BY mu.conversation_id) AS mux ON m.conversation_id = mux.conversation_id
JOIN conversation_list AS mu ON m.conversation_id = mu.conversation_id
GROUP BY mu.conversation_id
ORDER BY m.date_created DESC
getOuboxMessages
================
SELECT *
FROM conversation_messages AS m
JOIN
(SELECT mx.conversation_id,
MAX(mx.date_created) AS MaxTime
FROM conversation_messages AS mx
GROUP BY mx.conversation_id) AS mx ON m.conversation_id = mx.conversation_id
AND m.date_created = mx.MaxTime
JOIN
(SELECT mu.conversation_id, mu.user_id
FROM conversation_list AS mu
WHERE mu.added_by = :subuser
GROUP BY mu.conversation_id) AS mux ON m.conversation_id = mux.conversation_id
JOIN conversation_list AS mu ON m.conversation_id = mu.conversation_id
ORDER BY m.date_created DESC
isUnreadMessage
===============
SELECT * FROM conversation_list WHERE date_created >= date_lastView AND conversation_id = :messageid AND user_id = :subuser
getConversation
===============
SELECT conversation_id, message, sender, date_created
FROM conversation_messages
WHERE conversation_id = :submessage_id
ORDER BY date_created DESC
getNumberOfUnreadMessages
=========================
SELECT l.conversation_id, count(*)
FROM conversation_list l
JOIN conversation_messages m ON m.conversation_id = l.conversation_id AND m.date_created >= l.date_lastview
WHERE l.user_id = :subuser
GROUP BY l.conversation_id