原先做了一个message表,用来存放站内消息。如下:create table if not exists `message`(
`id` int unsigned not null auto_increment primary key,
`byuserid` int unsigned not null, #发送者userid
`touserid` int unsigned not NULL, #接收者userid
`msg` text not null,
`bytime` timestamp(14), #发送时间
`state` tinyint default 0, #状态,接收者是否已读
`bydel` tinyint default 0, #发送者是否删除该消息
`todel` tinyint default 0, #接收者是否删除消息
INDEX msg_user_by_id(`byuserid`),
INDEX msg_user_to_id(`touserid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;但发觉不对,因为当发送者delete时,接收者再delete的话则要先判断`bydel`是否为1,如果是则删除整个消息,否则就update todel = 1。因此需要两条语句。
后来想创建两个表,一个`receive_message`,另一个`send_message`,`msg`表内容相同(复制内容),则在删除方面没有问题,但在插入消息时需要插入两张表,还是执行两条语句。
如果将`message`拆分为两张表,一个`message`纯粹放置内容,另一个是`user_2_message`,那又回到了最开始的问题。
如果发送者完全不能删除自己已经发送的消息的话则在删除方面完全没有麻烦,问题是没有哪个用户不想看自己以前发送过什么消息!怎么办?各位都是有经验的老手,回答一下我这个初级阶段的幼稚问题吧。

解决方案 »

  1.   

    接受者delete的动作  没太明白为什么要去判断发送者是不是delete状态  不是直接update就可以了吗
      

  2.   

    或者只设置一个delete标志  加一个owner字段 每次插入两条数据 owner分别是发送者和接受者
      

  3.   

    一条消息分别给发送者和接收者引用,并可以分别删除,发送者删除的是“已发送消息”,接收者删除的是“已收到消息”,但实体消息只有一条,即msg列内容,这就造成了一个困境,第一个删除者并不能真正删除该消息,这应该留给第二个删除者执行。
    我现在想到了一个办法,就是采用概率计算定时/不定时删除message表中bydel = 1 && todel = 1的表。因此发送者和接收者在删除时实际上是执行update set bydel= 1 / todel = 1。然后当击中概率值时另执行一条真正的命令删除message中不再需要的行。
    概率发生的条件可以参照php session gc的回收:class Delete_Message{
       const DELPROVALUE = 5;
       ...
       protected function gc(){
          if (rand(0,9) === DELPROVALUE) {
             $query = "delete low_priority from message where bydel = 1 and todel = 1"; // 延时删除,不等结果
          }
          $mysql->query($query);
       }
       ...
    }
    我想这应该比较完善了。
      

  4.   

    一条消息分别给发送者和接收者引用,并可以分别删除,发送者删除的是“已发送消息”,接收者删除的是“已收到消息”,但实体消息只有一条,即msg列内容,这就造成了一个困境,第一个删除者并不能真正删除该消息,这应该留给第二个删除者执行。
    我现在想到了一个办法,就是采用概率计算定时/不定时删除message表中bydel = 1 && todel = 1的表。因此发送者和接收者在删除时实际上是执行update set bydel= 1 / todel = 1。然后当击中概率值时另执行一条真正的命令删除message中不再需要的行。
    概率发生的条件可以参照php session gc的回收:class Delete_Message{
       const DELPROVALUE = 5;
       ...
       protected function gc(){
          if (rand(0,9) === DELPROVALUE) {
             $query = "delete low_priority from message where bydel = 1 and todel = 1"; // 延时删除,不等结果
          }
          $mysql->query($query);
       }
       ...
    }
    我想这应该比较完善了。上面的写错了,应该是删除表中完全没有引用的行。class Delete_Message{
       const DELPROVALUE = 5;
       ...
       protected function gc(){
          if (rand(0,9) === self::DELPROVALUE) {
             $query = "delete low_priority from message where bydel = 1 and todel = 1"; // 延时删除,不等结果
             $mysql->query($query);
          }      
       }
       ...
    }