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查询,可以解决此问题。