【问题标题】:Sorting on ID (int PK) vs creation time按 ID(int PK)与创建时间排序
【发布时间】:2016-01-11 11:21:23
【问题描述】:

假设我有博客文章 cmets。在插入时,他们将当前 utc 日期时间作为其创建时间(通过 sysutcdatetime 默认值),并获得一个 ID(通过整数标识列作为 PK)。

现在我想按年龄对 cme​​ts 进行降序排序。只做ORDER BY ID 是否安全,或者是否需要使用创建时间?我正在考虑插入的“并发”提交和回滚以及已提交读取的隔离级别。是否有可能 ID 有时不代表插入顺序?

我之所以这么问,是因为如果按 ID 排序是安全的,那么我可以获得以下好处:

  • 我不需要创建时间的索引。
  • 按 ID 排序可能更快
  • 我不需要 datetime2 列的高精度,因为无论如何排序都需要这样(为了不让两行具有相同的创建时间)。

This 回答说没有创建时间是可能的,但它总是安全的吗?

This 回答说使用标识列不安全。但是当它也是 PK 时,答案给出了一个按 ID 排序的示例,而没有提及这是否安全。

编辑:

This 回答建议先按日期排序,再按 ID。

【问题讨论】:

    标签: sql-server database


    【解决方案1】:

    是的,ID 可能会混乱,因为 ID 生成不是插入事务的一部分。这是为了不序列化表上的所有插入事务。

    最正确的排序方法是ORDER BY DateTime DESC, ID DESC,并将 ID 添加为决胜局,以防多次生成相同的日期。各种类型的决胜局对于实现确定性结果很重要。例如,您不希望页面的多次刷新显示不同的数据。

    您可以在DateTime DESC, ID DESC 上定义一个覆盖索引,并获得与按 CI 键排序的相同性能(此处为:ID)。 CI 和 NCI 之间没有相关的物理差异。

    既然你在某处提到了 PK,我想指出的是,PK 的选择不会影响这一切。只有索引可以。查询处理器从不关心 PK 和唯一键。

    【讨论】:

    • 一件小事:按年龄降序排序意味着我需要DateTime ASC, ID ASC 我会说。
    【解决方案2】:

    我会通过ID订购。


    从技术上讲,按 ID 排序与按时间排序时,您可能会得到不同的结果。

    sysutcdatetime 将返回事务开始的时间。 ID 可能会在交易期间稍后的某个地方生成。此外,任何计算机上的时钟总是会漂移。当计算机时钟与时间源同步时,时钟可能会向前或向后跳跃。如果你经常进行同步,跳跃会很小,但它会发生。

    从实际的角度来看,如果两个 cmets 在相隔一秒的时间内发布,那么这些 cmets 中的哪一个先显示真的很重要吗?

    我认为重要的是显示结果的一致性。如果系统以某种方式决定评论 A 应该排在评论 B 之前,那么这个顺序应该在整个系统的任何地方保留。

    因此,即使使用最高精度 datetime2(7) 列,也可能有两个具有完全相同时间戳的 cmets,如果您仅按此时间戳排序,有时它们可​​能会显示为 A, B,有时显示为 @ 987654326@.

    如果您通过ID(主键)订购,您可以保证它是唯一的,因此订单将始终被明确定义。

    我会通过ID订购。


    再想一想,我会按时间和 ID 排序。

    如果您向用户显示评论的时间,则根据该时间显示 cmets 很重要。在两个 cmets 具有相同时间戳的情况下,保证按时间和 ID 排序的一致性。

    【讨论】:

    • 好点在这里。会发生以下情况吗?:我按 ID 排序,然后结果的时间列的顺序不准确。如果我的目标是顺序始终相同并且创建时间按顺序排列,我应该同时按 ID 和时间排序还是 ID 就足够了?
    • 好吧,如果你必须按时间订购,那么是的,按时间订购。比如说,您向最终用户显示评论的时间。当您在内部仅按 ID 排序时,以错误的顺序显示 cmets 看起来不太好。您可以以秒甚至一分钟的精度显示这个时间。我认为您不会以微秒的精度显示它。因此,您可以以您将显示的精度存储此时间,例如,datetime2(0),然后按time, ID 排序,以使顺序一致,因为知道可能有两个相等的时间戳。
    【解决方案3】:

    如果您根据降序对 id 进行排序,并且根据用户进行过滤,那么您的博客将自动显示上面的最新帖子,这将为您完成这项工作。所以不要使用日期作为排序

    【讨论】:

    • 我的问题不是关于排序顺序,而是关于 ID 和创建时间之间的一致性。
    猜你喜欢
    • 2018-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 2012-12-09
    • 1970-01-01
    • 2015-06-17
    • 1970-01-01
    相关资源
    最近更新 更多