文章目录
一、产品设计
1.1 分页方案设计
设计方案1: 深度随机跳页
产品设计不合理是导致深度分页查询的一个重要原因,比如下图所示的深度随机跳页设计方案,如果没有特殊原因,正常情况下应避免使用。一方面,随机跳页实际意义有多大有待考究;另一方面,随机性会加大后端的难度,如果随机跳页的页码很大,有可能导致查询超时,甚至异常,反而影响产品的稳定性以及用户体验。
设计方案2: 小范围跳页
小范围跳页涉及方案允许在当前页的前后小范围内翻页,避免随机大范围的跳转,如下如所示。这种产品方案的特点是前几页被访问的概率最高,越往后被访问到的概率越小,极大地降低了深度分页发生的概率。Google、百度等搜索引擎都在使用这种产品方案。
设计方案3: 滚动分页
滚动分页方案的特点是连续,分页都是连续的,避免了随机跳页以及深度分页,常用于移动端等支持手触设备上。
1.2 查询条件设计
分页查询条件的设计,归根结底就两点:控制数据量,避免数据过大;降低复杂度,避免嵌套等过于复杂查询;
1.2.1 控制数据量
- 增加查询维度;
- 缩小时间范围;
1.2.2 控制复杂度
- 避免多表连接、聚合等复杂查询;
二、技术方案
2.1 MySQL架构
2.1.1 滚动分页方案
方案说明: 利用滚动分页的连续性,查看下一页时,分页请求中携带当前页面数据的最大id值,从而将深分页的m降为0,如上图所示。
2.1.2 小范围跳页方案
方案说明: 将K页设为一组,每次从数据库查询时批量查询(需要携带数据的最大id),然后将数据缓存,同组的其它分页查询时,直接从缓存查询即可,如上图所示。
2.2 MySQL + ES架构
2.2.1 From + Size
问题: 页深有限制,m+n最大为1万。页数越深,占用内存越大,可能导致超时、OOM等问题(每个分片的数据先查询出m+n,然后再聚合)。
2.2.2 Scroll
适用于非实时性场景,比如数据导、迁移等。
2.2.3 Search After
原理同Mysql优化方案类似,首次查询时指定某个唯一的字段进行排序,后续每次下一页的查询都是根据上一页的最后一条数据来确定下一页的位置;
三、 DB规范
3.1 建表规范
任何新创建的表,主键都为无符号整型且自增,确保DB性能。
CREATE TABLE `order` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
...
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
参考