I have created a messaging system for users, it allows them to send a message to another user. If it is the first time they have spoken then a new conversation is initiated,
How to create a fast Facebook-like messages system. tested and widely used by Arutz Sheva users - http://www.inn.co.il (Hebrew).
create a "topic" (conversation) table:
CREATE TABLEpb_topics
(t_id
int(11) NOT NULL AUTO_INCREMENT,t_last
int(11) NOT NULL DEFAULT '0',t_user
int(11) NOT NULL DEFAULT '0', PRIMARY KEY (t_id
), KEYlast
(t_last
) ) ENGINE=InnoDB AUTO_INCREMENT=137106342 DEFAULT CHARSET=utf8
create link between user and conversation:
CREATE TABLEpb_links
(l_id
int(11) NOT NULL AUTO_INCREMENT,l_user
int(11) NOT NULL DEFAULT '0',l_new
int(11) NOT NULL DEFAULT '0',l_topic
int(11) NOT NULL DEFAULT '0',l_visible
int(11) NOT NULL DEFAULT '1',l_bcc
int(11) NOT NULL DEFAULT '0', PRIMARY KEY (l_id
) USING BTREE, UNIQUE KEYtopic-user
(l_topic
,l_user
), KEYuser-topicnew
(l_user
,l_new
,l_topic
) USING BTREE, KEYuser-topic
(l_user
,l_visible
,l_topic
) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=64750078 DEFAULT CHARSET=utf8
create a message
CREATE TABLEpb_messages
(m_id
int(11) NOT NULL AUTO_INCREMENT,m_from
int(11) NOT NULL,m_date
datetime NOT NULL DEFAULT '1987-11-13 00:00:00',m_title
varchar(75) NOT NULL,m_content
mediumtext NOT NULL,m_topic
int(11) NOT NULL, PRIMARY KEY (m_id
), KEYdate_topic
(m_date
,m_topic
), KEYtopic_date_from
(m_topic
,m_date
,m_from
) ) ENGINE=InnoDB
A conversation can be with 2 or more friends (BCC was added like email, but you can skip it).
Insert a new message: 1. Create new topic 2. Create Links for users (from/to) 3. Add Message (4. Update users cache table - user have messages)
Add Message to topic: Add Message
Select folder:
select
z.*, group_concat(u_name) as users_name from
(select max(m_id) as m_id, m_topic as t_id, m_From, m_title,m_date, l_new
from pb_links as l1, pb_messages
where l1.l_user= and m_from < If(inbox, "<>", "=") > and m_topic=l_topic and l1.l_visible=1
group by m_topic order by m_id desc limit " & iPage * 35 & ",35) z
left join pb_links l2 on (l2.l_topic=t_id)
left join users on (l_user=u_id and l_bcc=0 and l_user)
group by l_topic order by m_date desc;
In details:
The first is the inner select - this is the fastest way (I was check about 7 other options, checked also in Percona/MariaDB versions) to get all messages, and get also the last message to display in the list. Also look in the inner IF - in inbox, the last message is anyone but not me, and In outbox - the opposite. LIMIT used for paging.
The outer one used to add user list (just name comma name string) and more information for only one message per topic, and after paging (I need to add user list just to the 35-per-page messages, and not for all my large history).
Also, I wrote in hebrew here: http://blogs.microsoft.co.il/blogs/moshel/archive/2010/08/12/quot-x-quot.aspx to create a simple cache table, and forbid the workload of select count from busy message table.