先看BUG现象:

  1. 用户A发送给B一条消息。此时A,B在消息中都能看到对应的消息
  2. 其中一个用户,如A,删除消息。此时A看不到消息,B能看到
  3. 用户A,B之间再发送一条消息,此时A又可以看到已经被删除过的消息

bug不是很严重,下面就从UCenter的表结构来分析一下其产生的原因。

UCenter中,uc_pms表的设计如下,其中注释是我加的:

CREATE TABLE uc_pms (
  pmid int(10) unsigned NOT NULL auto_increment,  // 消息id
  msgfrom varchar(15) NOT NULL default '', // 消息发送人的显示名
  msgfromid mediumint(8) unsigned NOT NULL default '0', // 消息发送人id,如果为0,就是系统消息
  msgtoid mediumint(8) unsigned NOT NULL default '0', // 消息接收人id,如果为0,就是公开消息
  folder enum('inbox','outbox') NOT NULL default 'inbox', // 区分是发送还是接收
  new tinyint(1) NOT NULL default '0', // 区分是否新消息
  subject varchar(75) NOT NULL default '', // 消息显示标题
  dateline int(10) unsigned NOT NULL default '0', // 时间
  message text NOT NULL, // 消息内容
  delstatus tinyint(1) unsigned NOT NULL default '0', // 是否删除
  related int(10) unsigned NOT NULL default '0', // 会话id
  fromappid SMALLINT(6) UNSIGNED NOT NULL DEFAULT '0' // 应用id
) TYPE=MyISAM;

UCH消息中引入了会话(session)的概念。如用户A发送给B一条消息,即在A,B之间建立了会话。两个用户之间最多只有一个会话(但存了2条),这个是通过related字段来记录。当第一次消息产生时,为了区分是谁看,那么数据库中会存3条数据:

  • 2个会话信息,  主要通过related和folder来区分发送方向(其实folder相对于msgfromid,msgtoid来说是冗余的)
  • 1条具体的消息。这个是要点击查看详情才能看到的。

当再产生一条消息时,UCH将会话的subject,message更新,并存入新消息。此时数据库中就有4条数据了。

这样的设计下,用户删除信息时,只是虚假的将自己的那个会话删除了,并没有删除具体的消息,于是出现了开篇提到的小问题。

从表设计的delstatus字段来看,估计uch曾经试图解决这个bug,可惜没处理好。其实将设计稍微修改一点点,就可以修复这个BUG。

不过相对于其它的问题而言,这个bug并不是很紧急或者重要。