SQL消息表的良好实践

SQL消息表的良好实践,sql,Sql,我有一张留言表 Key - UserId, MsgIndex C1...Cn - some data columns Cn+1 - Date, when message has been added to the table. 问题是处理客户的最佳实践 客户端向服务器请求新邮件 有两个选项可以执行此操作: 检查带有index>lastRxMsgIndex的消息(客户端将保存收到的最后一个消息索引) 检查带有date>lastRxMsgDate的消息(客户端将保存最后一个接收消息日期-服务器将在

我有一张留言表

Key - UserId, MsgIndex
C1...Cn - some data columns
Cn+1 - Date, when message has been added to the table.
问题是处理客户的最佳实践

客户端向服务器请求新邮件

有两个选项可以执行此操作:

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

    保持date/TS或index是相同的,常识是保持date/TS,但msg index是相同的

    MsgIndex位于表主键中,所以搜索日期(当用户将有许多消息时…)是否应该更快

    哪种方式最好

    谢谢
    Yoav

    关于性能的第一个问题:您可以在日期列中添加索引,以提高按日期搜索的性能。您很可能还希望在索引中包含
    用户id
    。例如,您可以在
    (user\u id,id)
    (user\u id,date)
    上使用组合索引,以便单个用户可以快速找到自己的邮件,而无需服务器也扫描其他用户的邮件

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


    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
    来避免这些潜在的问题。

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

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


    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
    来避免这些潜在问题。

    因为
    MsgIndex
    是主键,所以它有一个索引。因此,通过
    MsgIndex
    访问要比使用日期比较快得多。

    因为
    MsgIndex
    是主键,所以它有一个索引。因此,通过
    MsgIndex
    进行访问要比使用日期比较快得多。

    如果您有大量传入消息,您提到的前一种方法肯定会起作用。
    后一种方式,如果你在同一天有两条消息(说同一秒,因为我不认为你可以更细粒度),你就完蛋了;)


    我以前在处理每秒接收大量消息的系统时使用了“按索引”方法。

    如果您有大量传入消息,您提到的前一种方法肯定有效。
    后一种方式,如果你在同一天有两条消息(说同一秒,因为我不认为你可以更细粒度),你就完蛋了;)


    我以前在处理每秒接收大量消息的系统时使用过“按索引”方法。

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

    时间戳列中可能存在非唯一值,但这不会成为问题,除非使用聚合函数,在这种情况下,可以通过在所选字段中包含唯一主键来解决

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

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

    就我个人而言,我会选择时间戳字段,因为阅读代码的其他人很清楚您在做什么,而使用id有点模糊,索引开销也很小。

    如果您在日期字段上有索引,那么应该没有任何区别(假设您使用的是unix时间戳)因为您有两个以升序排列的整数字段,您需要整数大于X的所有帖子

    时间戳列中可能存在非唯一值,但这不会成为问题,除非使用聚合函数,在这种情况下,可以通过在所选字段中包含唯一主键来解决