SQL消息表的良好实践

时间:2012-02-10 14:57:42

标签: sql

我有一张消息表

Key - UserId, MsgIndex
C1...Cn - some data columns
Cn+1 - Date, when message has been added to the table.

问题是与客户有关的最佳做法......

客户向服务器询问新消息......

有两种选择:

  1. 检查index > lastRxMsgIndex的消息(客户端将保存最后收到的消息索引)
  2. 检查date > lastRxMsgDate的消息(客户端将保存最后一个rx消息日期 - 服务器将在获取消息结果时将其提供给他)
  3. 哪个更好更快...

    保持日期/ TS或索引是相同的,常识说要保持日期/ TS,但它对于msg索引是相同的。

    MsgIndex位于表主键中,因此搜索日期(用户将有多条消息...)时速度会更快。

    哪种方式最好?

    由于 约阿夫

4 个答案:

答案 0 :(得分:2)

首先关于性能:您可以在日期列中添加索引,以提高按日期搜索的性能。您很可能还希望在索引中包含user_id。例如,您可以在(user_id, id)(user_id, date)上使用组合索引,以便各个用户可以快速找到他们拥有的邮件,而服务器也不必扫描其他用户的邮件。

关于功能:将日期时间用作关键字的一个潜在问题是时间戳通常是唯一的。如果您根据日期进行搜索,则可能(但不太可能)您将错过一条消息。以下是演示此问题的示例场景:


在16:01:04.312,该表包含两条消息:

id    date                  message
1     2012-02-10 14:23:54   foo
2     2012-02-10 16:01:04   bar

客户端之前已收到第1行,现在请求并收到最新的行:

SELECT * FROM your_table WHERE date > '2012-02-10 14:23:54'
(1 row)

然后在16:01:04.420,一个新行以相同的时间戳进入数据库:

id    date                  message
1     2012-02-10 14:23:54   foo
2     2012-02-10 16:01:04   bar
3     2012-02-10 16:01:04   baz

客户请求最新的行,但没有得到它:

SELECT * FROM your_table WHERE date > '2012-02-10 16:01:04'
(0 rows)

另一个问题是服务器的时间是否向后调整。这可能导致以后的消息插入更早的时间戳。如果您使用日期查找最新消息,也会错过这些消息。最好使用id来避免这些潜在的问题。

答案 1 :(得分:2)

由于MsgIndex是主键,因此它具有索引。因此,MsgIndex的访问速度比使用日期比较快得多。

答案 2 :(得分:1)

如果您有大量收到的消息,您提到的前一种方式可以保证正常工作 后一种方式,如果你在同一天有两条消息(比如同一秒,因为我认为你不能更细粒度),你就搞砸了;)

我在使用每秒接收大量消息的系统之前使用了'go by index'方法。

答案 3 :(得分:1)

如果日期字段上有索引,则应该没有任何区别(假设您使用的是unix时间戳),因为您有两个整数按升序排列的字段,您希望所有的整数都大于X

timestamp列中可能存在非唯一值,但除非您使用聚合函数,否则这不会有问题,在这种情况下,您可以通过在所选字段中包含唯一主键来修复它。

鉴于这一事实,您只需要考虑:

  • 每次插入数据时计算日期列索引的(非常小的)开销是否值得
  • 使用的ID或使用的时间戳,您编写的代码是否更具可读性。

就个人而言,我会选择timestamp字段,因为对于其他读取代码的人来说,你正在清楚地知道你在做什么,而使用id有点模糊,索引开销很小。