按ID(int PK)排序还是按创建时间排序?

3

假设我有一篇博客文章的评论。在插入时,它们会获得当前的UTC日期时间作为它们的创建时间(通过sysutcdatetime默认值),并且它们会获得一个ID(通过整数标识列作为PK)。现在我想按照它们的年龄降序排列评论。只使用ORDER BY ID是否安全,还是必须使用创建时间?我在考虑“并发”提交和回滚插入以及读取提交的隔离级别。是否可能ID有时不代表插入顺序?

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

  • 我不需要为创建时间建立索引。
  • 按ID排序可能更快
  • 我不需要在datetime2列上具有高精度,因为这仅在排序时才需要(为了不具有相同的创建时间的两行)。

这个回答表示,当您没有创建时间时,这是可能的,但它总是安全的吗?

这个回答表示对于标识列不安全。但是当它也是PK时,该回答给出了按ID排序的示例,没有提到这是否安全。

编辑:

这个回答建议先按日期排序,然后再按ID排序。

3个回答

4
是的,ID可能会混乱,因为ID生成不是插入事务的一部分。这是为了不使所有插入事务都在表上串行化。
最正确的排序方式是ORDER BY DateTime DESC, ID DESC,如果生成了多个相同的日期,则添加ID作为绑定器。在排序中使用绑定器非常重要,可以实现确定性结果。例如,您不希望在页面多次刷新时显示不同的数据。
您可以在DateTime DESC,ID DESC上定义覆盖索引,并实现与按CI键排序相同的性能。 CI和NCI之间没有相关的物理差异。
由于您在某个地方提到了PK,我想指出选择PK并不影响任何内容。只有索引才有影响。查询处理器从不关心PK和唯一键。

一个小细节:按年龄降序排序意味着我需要 DateTime ASC,ID ASC - user764754

2
我会按照ID排序。
从技术角度来看,按照ID排序和按时间排序可能会得到不同的结果。 sysutcdatetime 返回事务开始时的时间。而 ID 可能在事务中的某个时间生成。此外,任何计算机上的时钟都会漂移。当计算机时钟与时间源同步时,时钟可能会向前或向后跳动。如果经常进行同步,则跳跃量将很小,但它确实会发生。
从实际角度来看,如果两条评论在一秒内发布,那么哪条评论先显示可能并不重要。
我认为重要的是显示结果的一致性。如果系统以某种方式决定评论A应该在评论B之前,那么这个顺序应该在整个系统中保持不变。
因此,即使使用最高精度的datetime2(7)列,也有可能有两个具有完全相同时间戳记的评论,如果仅按此时间戳记排序,则有时它们将显示为A,B,有时则显示为B,A
如果按照ID(主键)排序,则可以保证其唯一,因此顺序将始终定义良好。
我会按照ID排序。
再思考一下,我会按时间和ID排序。
如果向用户显示评论的时间,则按照此时间显示评论非常重要。为了保证一致性,请按时间和ID进行排序,以防止两个评论具有相同的时间戳。

这里提出了很好的观点。以下情况可能会发生吗?:我按ID排序,结果的时间列不是完全按顺序排列的。如果我的目标是始终保持相同的顺序并按创建时间排序,那么我应该按ID和时间进行排序,还是仅按ID即可? - user764754
如果必须按时间排序,那么就按时间排序。比如说,你要向最终用户展示评论的时间。如果你仅在内部按ID排序,那么展示看起来似乎是错乱的评论将不会好看。你可以用秒精度甚至分钟精度来展示这个时间。我认为你不会用微秒精度来展示它。因此,你可以使用你将要展示的精度存储这个时间,例如 datetime2(0),然后按 time, ID 排序以使顺序保持一致,知道有可能存在两个相同的时间戳。 - Vladimir Baranov

0

如果你按照ID降序排序并基于用户筛选,那么你的博客将自动显示最新的帖子在上面,这样就能完成你的工作。所以不要使用日期作为排序方式。


我的问题不是关于排序顺序,而是关于ID和创建时间之间的一致性。 - user764754

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接