可疑的SQL实践 - 按ID而不是创建时间排序

Ale*_*spo 10 mysql sql database query-optimization

所以我有一个有趣的问题,我不确定是否被视为'黑客'.我查看了一些问题,但没有找到重复,所以在这里.基本上,我需要知道这是不可靠还是被认为是不好的做法.

我有一个非常简单的表,具有唯一的自动递增ID和created_at时间戳.(我的问题的简化版本,以澄清有问题的概念)

+-----------+--------------------+
| id        |created_at          |
+-----------+--------------------+
| 1         |2012-12-11 20:35:19 |
| 2         |2012-12-12 20:35:19 |
| 3         |2012-12-13 20:35:19 |
| 4         |2012-12-14 20:35:19 |
+-----------+--------------------+
Run Code Online (Sandbox Code Playgroud)

这两个列都是动态添加的,因此可以说新的'insert' 总是具有更大的id并且总是有更大的日期.

目标 - 非常简单地按降序抓取created_at排序的结果

SOLUTION ONE - 按日期降序排序的查询

SELECT * FROM tablename
ORDER BY created_at DESC
Run Code Online (Sandbox Code Playgroud)

解决方案两 - 按ID按降序排序的查询

SELECT * FROM tablename
ORDER BY id DESC
Run Code Online (Sandbox Code Playgroud)

解决方案二被视为不良做法吗?或解决方案二是正确的做事方式.任何对你的推理的解释都会非常有用,因为我试图理解这个概念,而不仅仅是简单地得到答案.提前致谢.

dav*_*ell 7

在典型的实践中,您几乎总是可以假设可以对自动增量ID进行排序,以便按创建顺序(任一方向)提供记录.但是,您应该注意,根据您的数据,这不被认为是可移植的.您可以将数据移动到重新创建密钥的另一个系统,但created_at数据是相同的.

实际上有一个很好的StackOverflow讨论这个问题.

基本摘要是第一个解决方案,按created_at排序,被认为是最佳实践.但是,请确保正确索引created_at字段以提供最佳性能.

  • +1用于考虑事后数据会发生什么. (2认同)

Mar*_*ers 6

这两个选项之间存在一些差异。


首先是它们可以给出不同的结果。

的值created_at可能会受到服务器调整时间的影响,但该id列不受影响。如果时间向后调整(手动或由时间同步软件自动调整),您可以获得稍后插入的记录,但时间戳位于较早插入的记录之前。在这种情况下,您将获得不同的订单,具体取决于您订购的列。您认为哪个顺序是“正确的”取决于您。


二是业绩。ORDER BY您的聚集索引可能会更快。

聚集索引如何加快查询速度

通过聚集索引访问一行很快,因为行数据位于索引搜索引导的同一页上。

默认情况下,聚集键是主键,在您的情况下可能是id列。您可能会发现它ORDER BY idORDER BY created_at.


And*_*ter 6

除了唯一标识行之外,您不应该依赖ID.它是一个任意数字,恰好与创建记录的顺序相对应.

说你有这张桌子

ID  creation_date
1   2010-10-25
2   2010-10-26
3   2012-03-05
Run Code Online (Sandbox Code Playgroud)

在这种情况下,对ID而不是creation_date进行排序有效.

现在将来你会意识到,哦,哎呀,你必须将记录ID#2的创建日期改为2010-09-17.您使用ID排序现在以相同的顺序报告记录:

1   2010-10-25
2   2010-09-17
3   2012-03-05
Run Code Online (Sandbox Code Playgroud)

即使新日期应该是:

2   2010-09-17
1   2010-10-25
3   2012-03-05
Run Code Online (Sandbox Code Playgroud)

简短版本:将数据列用于创建它们的目的.不要依赖数据的副作用.