16

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

我有一个非常简单的表,它有一个唯一的自动递增 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 |
+-----------+--------------------+

这两列都是动态添加的,因此可以说新的“插入”总是有更大的 id 并且总是有更大的日期。

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

解决方案一- 按日期降序排列的查询

SELECT * FROM tablename
ORDER BY created_at DESC

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

SELECT * FROM tablename
ORDER BY id DESC

解决方案二是否被认为是不好的做法?或者解决方案二是正确的做事方式。当我试图理解这个概念时,对你的推理的任何解释都会非常有帮助,而不仅仅是简单地得到答案。提前致谢。

4

5 回答 5

12

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

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

基本总结是第一个解决方案,按 created_at 排序,被认为是最佳实践。但是,请务必正确索引 created_at 字段以提供最佳性能。

于 2012-12-22T19:04:14.747 回答
8

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

假设你有这张桌子

ID  creation_date
1   2010-10-25
2   2010-10-26
3   2012-03-05

在这种情况下,按 ID 排序而不是 creation_date 有效。

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

1   2010-10-25
2   2010-09-17
3   2012-03-05

即使有了新的日期,它们应该是:

2   2010-09-17
1   2010-10-25
3   2012-03-05

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

于 2012-12-22T19:24:23.687 回答
6

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


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

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


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

聚集索引如何加速查询

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

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

于 2012-12-22T19:03:37.357 回答
4

按插入顺序按 id排序。

如果您有可能延迟插入的用例,例如批处理,那么您必须按 created_at 排序才能按时间排序。

如果它们满足您的需求,两者都是可以接受的。

于 2012-12-22T19:11:48.760 回答
3

主键,尤其是代理类型的主键,通常不代表任何类型的有意义的数据,除了它们的功能是允许唯一可识别的记录。由于在这种情况下日期确实代表了有意义的数据,这些数据在其主要功能之外具有意义,我想说根据日期进行排序是一种更合乎逻辑的方法。

于 2012-12-22T19:07:18.743 回答