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

0 前言

有一个离奇的BUG,在查询时,第一页跟第二页有一个共同的数据。有的数据却不显示。
后来发现是在SQL排序时没用主键排序。
解决:使用主键排序
以下是我准备的举例,可以自己试试。

1 数据准备

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页):

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页):

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查询,可以解决此问题。
在这里插入图片描述
在这里插入图片描述

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值