3

Web サイト用のプライベート メッセージング システムを作成しています。ユーザーは、複数の他のユーザー (自分自身を含む) と通信できます。私は3つのテーブルを持っています

- 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

これまでに行ったことを以下に示します。

getOutboxMessagesgetConversationisUnreadMessageおよび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
4

0 に答える 0