如何实现基于最后 ID 的双向分页(上一页/下一页)
发布时间 - 2025-12-29 00:00:00 点击率:次本文介绍一种不依赖连续 id 的 mysql 双向分页方案:通过记录边界 id 并结合 `array_reverse()` 实现稳定、高效、容错的上一页/下一页导航,完美解决因数据删除导致 id 不连续带来的翻页错乱问题。
在基于 ID 的分页实践中,常见的“游标分页”(Cursor-based Pagination)通常采用 WHERE id 上一页却容易陷入误区:若简单使用 WHERE id 当前页起始 ID 为下界进行反向查询。
✅ 正确思路是:
- 下一页:WHERE id
- 上一页:WHERE id > $first_id LIMIT 21 → 获取更大 ID 的数据(自然升序),再反转数组,使其视觉顺序与用户预期一致(即顶部显示 ID=99,底部显示 ID=120)。
以下是完整 PHP + MySQL 实现示例(含关键注释):
prepare("SELECT * FROM table_name WHERE id > ? LIMIT ?");
$stmt->execute([$_GET['prev'], $limit]);
$results = array_reverse($stmt->fetchAll(PDO::FETCH_ASSOC));
} elseif ($isNext) {
// 下一页:查比 $last_id 更小的 21 条(降序)
$stmt = $db->prepare("SELECT * FROM table_name WHERE id < ? ORDER BY id DESC LIMIT ?");
$stmt->execute([$_GET['next'], $limit]);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
} else {
// 首页:取最大的 21 条
$stmt = $db->prepare("SELECT * FROM table_name ORDER BY id DESC LIMIT ?");
$stmt->execute([$limit]);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// 渲染数据(假设按 id 降序展示)
foreach ($results as $row) {
echo "ID: {$row['id']} | {$row['title']}";
}
// 生成分页按钮(关键:传递正确的边界 ID)
$firstId = !empty($results) ? $results[0]['id'] : null;
$lastId = !empty($results) ? end($results)['id'] : null;
// 上一页按钮:传当前页第一条记录的 ID(即上一页的「最小 ID」应 > 它)
if ($firstId !== null) {
echo '← 上一页';
}
// 下一页按钮:传当前页最后一条记录的 ID(即下一页的「最大 ID」应 < 它)
if ($lastId !== null && count($results) === $limit) {
echo '下一页 →';
}
?>⚠️ 重要注意事项:
- 必须确保 id 字段有索引(如主键或唯一索引),否则 WHERE id > ? 查询将全表扫描,性能急剧下降;
- 避免混合使用 OFFSET:传统 LIMIT offset, size 在大数据量下效率低下,且无法精准支持“上一页”逻辑;
- 边界 ID 必须来自当前页真实数据:切勿用计算(如 $firstId - 21),因 ID 不连续;
- 前端需禁用重复提交:防止用户快速点击导致状态错乱;
- 考虑添加 created_at 辅助排序:若存在同 ID 冲突(极罕见),可加二级排序保障稳定性,如 ORDER BY id DESC, created_at DESC。
该方案彻底摆脱对 ID 连续性的依赖,即使中间大量删除数据,翻页依然精准、响应迅速,是高并发、大数据量场景下的推荐实践。
# mysql
# php
# 前端
# 大数据
# 并发
# 上一页
# 下一页
# 分页
# 升序
# 当前页
# 更大
# 降序
# 翻页
# 不连续
# 使其
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?
javascript中数组(Array)对象和字符串(String)对象的常用方法总结
新三国志曹操传主线渭水交兵攻略
如何在HTML表单中获取用户输入并结合JavaScript动态控制复利计算循环
成都品牌网站制作公司,成都营业执照年报网上怎么办理?
为什么要用作用域操作符_php中访问类常量与静态属性的优势【解答】
Laravel如何创建自定义Artisan命令?(代码示例)
Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转
Python文件操作最佳实践_稳定性说明【指导】
ai格式如何转html_将AI设计稿转换为HTML页面流程【页面】
做企业网站制作流程,企业网站制作基本流程有哪些?
如何在景安云服务器上绑定域名并配置虚拟主机?
如何快速查询域名建站关键信息?
javascript基于原型链的继承及call和apply函数用法分析
Midjourney怎样加参数调细节_Midjourney参数调整技巧【指南】
如何在IIS中新建站点并配置端口与物理路径?
Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】
如何快速建站并高效导出源代码?
如何在Windows虚拟主机上快速搭建网站?
如何在服务器上配置二级域名建站?
轻松掌握MySQL函数中的last_insert_id()
Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)
如何登录建站主机?访问步骤全解析
为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】
如何在七牛云存储上搭建网站并设置自定义域名?
浅析上传头像示例及其注意事项
Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
黑客入侵网站服务器的常见手法有哪些?
中山网站制作网页,中山新生登记系统登记流程?
Windows10如何更改计算机工作组_Win10系统属性修改Workgroup
Laravel如何实现多对多模型关联?(Eloquent教程)
使用PHP下载CSS文件中的所有图片【几行代码即可实现】
CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】
魔方云NAT建站如何实现端口转发?
Laravel如何实现用户角色和权限系统_Laravel角色权限管理机制
三星网站视频制作教程下载,三星w23网页如何全屏?
Laravel中DTO是什么概念_在Laravel项目中使用数据传输对象(DTO)
phpredis提高消息队列的实时性方法(推荐)
电视网站制作tvbox接口,云海电视怎样自定义添加电视源?
Laravel怎么发送邮件_Laravel Mail类SMTP配置教程
javascript日期怎么处理_如何格式化输出
Laravel用户认证怎么做_Laravel Breeze脚手架快速实现登录注册功能
如何快速搭建高效简练网站?
阿里云网站搭建费用解析:服务器价格与建站成本优化指南
详解Android图表 MPAndroidChart折线图
制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?
如何快速搭建高效WAP手机网站?
详解阿里云nginx服务器多站点的配置
javascript读取文本节点方法小结

