当您不能依赖ID的原义顺序时,如何批处理SELECT语句?

时间:2019-07-13 15:54:41

标签: mysql sql

我所说的字面意思是,尽管ID是自动递增的,但通过业务逻辑,可能应该是8排在4后面,而本来应该在5后面。也就是说,如果ID发生删除,则不会重新索引

这是我的行的外观(表名称为wp_posts):

+-----+-------------+----+--+--+--+
| ID  | post_author | .. |  |  |  |
+-----+-------------+----+--+--+--+
| 4   | ..          |    |  |  |  |
+-----+-------------+----+--+--+--+
| 8   | ..          |    |  |  |  |
+-----+-------------+----+--+--+--+
| 124 | ..          |    |  |  |  |
+-----+-------------+----+--+--+--+
| 672 | ..          |    |  |  |  |
+-----+-------------+----+--+--+--+
| 673 | ..          |    |  |  |  |
+-----+-------------+----+--+--+--+
| 674 | ..          |    |  |  |  |
+-----+-------------+----+--+--+--+

ID是具有int特征的auto-increment但删除帖子后,不会重新分配ID。它只会被删除,并且由于它是自动递增的,因此您仍然可以假设,从垂直方向看,正在查看的项目之后的项目总是比之前的项目大。

我正在查询ID:SELECT ID FROM wp_posts,以获得我需要的所有ID的列表。现在,碰巧我需要使用AJAX请求对所有这些进行批处理,因为一旦检索到ID,就需要对其进行操作。

问题是,我不太了解如何将数据传递回AJAX。 LIMIT的作用是,如果我提供2个参数,例如:SELECT ID FROM wp_posts LIMIT 1,3,它将返回4,8,124,因为它查看的是行号。但是,下次通话我该怎么办?是的,第一次呼叫始终以1开始,但是一旦我需要启动第二个AJAX请求以执行另一个SELECT,我怎么知道应该从哪里开始呢?就我而言,我想从4重新开始,因此,我的第二个查询将是SELECT ID FROM wp_posts LIMIT 4, 7,依此类推。

我真的需要发送该计数器吗(即使我可以使它自动化,因为您看到它的增加是3)?

SQL是否无法自动处理此问题?

3 个答案:

答案 0 :(得分:1)

您的问题中有很多困惑。让我尝试清除一些基本的内容。

首先,自动递增键是表的主键。您无需担心差距。实际上,密钥基本上应该是没有意义的。它满足以下条件:

  • 保证是唯一的。
  • 保证按插入顺序排列。

允许间隙,而无需担心。没有重新索引。这是个坏主意,因为:

  • 主键唯一地标识每一行,并且此映射在时间上应该保持一致。
  • 其他表中使用主键来引用值,因此重新索引将使这些关系无效或需要对许多表进行大量更改。
  • 重新编制索引的前提是,该值在没有意义的情况下是有意义的。

第二,查询,例如:

SELECT ID
FROM wp_posts
LIMIT 1, 3;

可以返回 any 三行。为什么?因为您没有指定ORDER BY,而没有ORDER BY的SQL结果集是无序的。没有任何保证。因此,您应该始终习惯使用ORDER BY

第三,如果您想对结果进行“分页”,请使用OFFSET中的LIMIT功能(如上所示):

SELECT ID
FROM wp_posts
ORDER BY ID
LIMIT @offset, 3;

这将使您可以重置@offset值并转到所需的行。

答案 1 :(得分:0)

似乎,您想返回按当前现有ID值排序的查询的前三行(无论在表wp_posts上应用了所有DML语句之后,它们是什么)。

然后,考虑使用辅助迭代变量@i提供一个从1开始并以23,...递增的有序整数集。差距:

select t.*
  from 
  ( 
   select @i :=  @i + 1 as rownum, t1.*
     from tab t1
     join (select @i:=0) t2
  ) t 
 order by rownum 
 limit 0,3; 

Demo

答案 2 :(得分:0)

第一个查询:

SELECT ID FROM wp_posts ORDER BY ID LIMIT 3

这将返回您所说的4,8,124。在您的客户端中,将最大ID值保存在变量中

后续查询:

SELECT ID FROM wp_posts WHERE ID > ? ORDER BY ID LIMIT 3

使用上一个结果的扩展ID值将参数发送到此查询中。它仍然在变量中。

这也有助于使查询更快,因为它不必每次都跳过所有这些初始行。使用LIMIT / OFFSET在大型数据集上分页效率很低。 SQL实际上必须读取所有这些行,即使它不会返回它们。

但是,如果您使用WHERE ID > ?,则SQL可以在正确的位置(将包括在结果的第一行中)有效地开始扫描。