首页 » 后端 » PHP » 正文

OSChina 的留言表设计说明 [转]

发布者:站点默认
2012/09/17 浏览数(1,822) 分类:PHP OSChina 的留言表设计说明 [转]已关闭评论

OSChina 的留言表 osc_msgs ,表结构如下:

OSChina 的留言表 osc_msgs 结构

OSChina 的留言表 osc_msgs 结构

字段说明

id : 留言主键字段,自增长
user : 留言的主人
friend : 对方的ID
sender : 留言发送者
receiver : 留言接收者
type : 留言类型(普通消息、系统消息)
content : 留言内容
send_time : 发送时间
read_time : 阅读时间
status : 留言状态

其中 user 和 friend 稍显特殊,其他的字段意义已非常明确不再说明。

当 A 给 B 发送一条留言时,会往 osc_msgs 表中插入两条相同的记录,唯一不同的是 user 和 friend 这两个字段的值是对调的,当然 id 因为是自增长的所以也不同。

为什么要添加两条记录?

1. 一条留言保存两条记录:因为每个人都有收到的留言和已发送留言,当发送人删除了已发送留言,不会影响到接收人查看收到的留言

2. user/friend/sender/receiver 这四个字段是不是多余?

关键的问题就在于此,你还记得 osc 的留言箱吗?进入留言箱里显示的是你最近的留言往来,包含你接收到的和你发出的,它们是按照时间进行排序的。

假设只有 sender/receiver 这两个字段,那么要将接收和发送的留言放在一起,就必须用 UNION 来合并两个查询结果,然后再做排序,而且你还必须有个字段来标注到底是接收到的留言还是发出的留言。这样的 SQL 可能会是这样:

SELECT * FROM (
    SELECT * FROM osc_msgs WHERE type=<接收> AND receiver=<我>
    UNION
    SELECT * FROM osc_msgs WHERE type=<发送> AND sender=<我>
) t ORDER BY send_time DESC

这样的 SQL 语句不用执行都知道性能很差。

那么以冗余来换性能的思路,我们对这个表进行了小改造。

增加两个字段 user 和 friend,当 A 发送留言给 B 时,会写入两条记录:

记录1. user=A,friend=B,sender=A,receiver=B

记录2. user=B,friend=A,sender=A,receiver=B

再来看看在新的表结构下,我们如何改写上面的语句:

SELECT * FROM osc_msgs WHERE user = <我> ORDER BY id DESC

这两个 SQL 语句孰优孰劣,相信大家能比较得出来。

如果是要列出我跟每个人的最后一条留言的话(就好象留言箱首页显示的内容)可以这样写 SQL 语句:

SELECT
	MAX(id) AS id,
	COUNT(id) AS msgCount
FROM osc_msgs
WHERE user = ?
GROUP BY friend
ORDER BY id DESC

本文只是提供一种表结构设计的参考思路,这也不是放之四海而皆准的方法,关键的问题在于你想解决什么样的问题,对 OSC 来说性能很重要,如果能简单的通过冗余来提升性能,这很划算。

<完。原文来自:OSChina 的留言表设计说明

点击返回顶部
  1. 留言
  2. 联系方式