解决MySQL中分页查询时多页有重复数据,实际只有一条数据的问题

0 前言

有一个离奇的BUG,在查询时,第一页跟第二页有一个共同的数据。有的数据却不显示。

后来发现是在SQL排序时没用主键排序。

解决:使用主键排序

以下是我准备的举例,可以自己试试。

1 数据准备

sql 复制代码
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for goods
-- ----------------------------
DROP TABLE IF EXISTS `goods`;
CREATE TABLE `goods`  (
  `id` int NOT NULL COMMENT '自增主键',
  `goods_uuid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '商品uuid',
  `goods_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '商品名',
  `warehousing_time` datetime NULL DEFAULT NULL COMMENT '入库时间',
  `in_goods` int NULL DEFAULT NULL COMMENT '是否在库',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;

-- ----------------------------
-- Records of goods
-- ----------------------------
INSERT INTO `goods` VALUES (1, '43a0d013-142d-b1b1-d484-b7926967e9b0', '麻糕薯', '2023-07-18 08:00:00', 1);
INSERT INTO `goods` VALUES (2, 'e3dd0d6d-ae57-c307-a83d-011e5873605c', '哈密瓜', '2023-07-17 08:00:00', 1);
INSERT INTO `goods` VALUES (3, 'ff707c99-7098-80d3-9d68-e57b2b7c9a83', '鸡排骨', '2023-07-16 08:00:00', 1);
INSERT INTO `goods` VALUES (4, 'e47cc736-0934-9443-dcb2-cb25938681aa', '猪肉脯', '2023-07-15 08:00:00', 1);
INSERT INTO `goods` VALUES (5, '3400bbbe-0da4-7941-9289-26127d8de225', '牛肉干', '2023-07-14 08:00:00', 1);
INSERT INTO `goods` VALUES (6, '4505b5d1-a170-6878-2be1-c243250f56fe', '碧根果', '2023-07-13 08:00:00', 1);
INSERT INTO `goods` VALUES (7, '428865ac-b711-aa5c-8210-620b72e02a5a', '无花果', '2023-07-12 08:00:00', 1);
INSERT INTO `goods` VALUES (8, 'bdd57fcd-7d7c-8dbf-cc5b-77bfa7a82ef9', '开心果', '2023-07-11 08:00:00', 1);
INSERT INTO `goods` VALUES (9, '0c297d45-fbe4-eab7-6a09-c2b61349bca4', '杏仁', '2023-07-10 08:00:00', 1);
INSERT INTO `goods` VALUES (10, '6b7f1a48-8419-c342-e28f-644f745b8d29', '松仁', '2023-07-09 08:00:00', 1);
INSERT INTO `goods` VALUES (11, '16dc36bf-0d6e-3daf-f324-6361d3790d28', '棒棒糖', '2023-07-08 08:00:00', 1);
INSERT INTO `goods` VALUES (12, 'b4ee3289-12c9-1550-eff9-5a7a4a8b0340', '脆皮肠', '2023-07-07 08:00:00', 1);
INSERT INTO `goods` VALUES (13, '862ee658-e25a-f64b-35ce-c6c880963b38', '奥尔良', '2023-07-06 08:00:00', 1);
INSERT INTO `goods` VALUES (14, '86f7e5cd-e0c6-c459-af05-b0db5a7581eb', '汉堡', '2023-07-05 08:00:00', 1);
INSERT INTO `goods` VALUES (15, '71b64da5-bf72-1ba8-01f6-a362168d0a1e', '巧克力', '2023-07-04 08:00:00', 1);
INSERT INTO `goods` VALUES (16, 'c5c874dd-878d-5ecb-7d6f-49e6b7d55b91', '果冻', '2023-07-04 08:00:00', 1);
INSERT INTO `goods` VALUES (17, 'bac4c71c-dbaf-7d15-9058-f59d6dff04fb', '海苔', '2023-07-04 08:00:00', 1);
INSERT INTO `goods` VALUES (18, 'd8e49911-bba5-f6b2-259b-1d15f62c7a4d', '双皮奶', '2023-07-03 08:00:00', 1);
INSERT INTO `goods` VALUES (19, '9d3240a3-8614-c79a-7834-62f8a0bde671', '饼干', '2023-07-02 08:00:00', 1);
INSERT INTO `goods` VALUES (20, '8875c531-2ca4-80eb-aaa1-7f7f4a9666e7', '薯片', '2023-07-01 08:00:00', 1);

SET FOREIGN_KEY_CHECKS = 1;

2 BUG复现

分页查询公式:分页查询--他的公式为(伪代码):[NOT] LIMIT (curPage-1)*pageSize,pageSize

执行SQL(每页4条,第1页):

sql 复制代码
SELECT
	id,
	goods_uuid,
	goods_name,
	warehousing_time,
	in_goods 
FROM
	goods 
WHERE
	in_goods = 1 
ORDER BY
	warehousing_time 
	LIMIT 0,
	4;

我们想得到的应该是时间从小到大,也就是

20 薯片

19 饼干

18 双皮奶

17 海苔

但是实际情况为:

20 薯片

19 饼干

18 双皮奶

16 果冻

执行SQL(每页4条,第2页):

sql 复制代码
SELECT
	id,
	goods_uuid,
	goods_name,
	warehousing_time,
	in_goods 
FROM
	goods 
WHERE
	in_goods = 1 
ORDER BY
	warehousing_time 
	LIMIT 4,
	4;

我们想得到的应该是时间从小到大,也就是

16 果冻

15 巧克力

14 汉堡

13 奥尔良

实际情况为:

16 果冻

17 海苔

14 汉堡

13 奥尔良

可以看到:第一页跟第二页都出现了id为16,name为果冻的数据。

并且id为15,name为巧克力的数据没有出现。

如果在页面上展示就会有问题。

3 解决

因为这个排序条件的数据是可以重复的,所以在查询的时候,MYSQL在排序重复数据的时候会导致数据位置不固定。

所以要使用主键去查询。

使用主键id查询,可以解决此问题。

相关推荐
bug菌¹19 分钟前
滚雪球学Oracle[6.2讲]:Data Guard与灾难恢复
数据库·oracle·data·灾难恢复·guard
一般路过糸.22 分钟前
MySQL数据库——索引
数据库·mysql
Cengineering1 小时前
sqlalchemy 加速数据库操作
数据库
Cikiss1 小时前
微服务实战——平台属性
java·数据库·后端·微服务
小小不董1 小时前
《Linux从小白到高手》理论篇:深入理解Linux的网络管理
linux·运维·服务器·数据库·php·dba
无敌少年小旋风2 小时前
MySQL 内部优化特性:索引下推
数据库·mysql
柒小毓2 小时前
将excel导入SQL数据库
数据库
bug菌¹2 小时前
滚雪球学Oracle[2.5讲]:数据库初始化配置
数据库·oracle·数据库初始化·初始化配置
一休哥助手2 小时前
Redis 五种数据类型及底层数据结构详解
数据结构·数据库·redis
翔云1234562 小时前
MVCC(多版本并发控制)
数据库·mysql