数据库分表分页实现方案

数据库水平分表后,分页查询如何实现?

两种解决方案

1.多库分别按条件查询,查询后按照条件重新筛选,筛选后选择对应的数据,同时记录好这次每个库的最大取值,作为下一页的条件

优点:查询简单,

缺点:该方案只能应对不跳页的场景的实现方案

2.计算偏移量方法

第一步:根据当前页和每页条数,计算偏移量

eg:查询第200页,每页5条的数据 SQL语句为select * from T  limit 5 offset 1000;

这里的1000为总偏移量,即200*5;

如果分表为两张,则每张表的偏移量为500,三张表,即为333.

第二步:根据每张表的偏移量查询每张表的分页数据select * from T  limit 200 offset 333;

假设查询结果如下

数据库分表分页实现方案_第1张图片

第三步:根据结果找出上面每个查询结果的最大值和最小值,每个结果的最小值比较,找出最小值min(1487501123),每个结果的最大值max作为查询的自己的查询最大值,作为条件,select from T where time between min and max;对于分库一:即为select from T where time between 1487501123 and 1487501523;

查询结果如下:

数据库分表分页实现方案_第2张图片

可以看到:

由于min来自原来的分库一,所以分库一的返回结果集和第一次查询相同(所以其实这次访问是可以省略的);

分库二的结果集,比第一次多返回了1条数据,头部的1条记录(time最小的记录)是新的(上图中粉色记录);

分库三的结果集,比第一次多返回了2条数据,头部的2条记录(time最小的2条记录)是新的(上图中粉色记录);

在第一个库中,time_min在第一个库的offset是333

在第二个库中,(1487501133, uid_aa)的offset是333(根据第一次查询条件得出的),故虚拟min在第二个库的offset是331

在第三个库中,(1487501143, uid_aaa)的offset是333(根据第一次查询条件得出的),故虚拟min在第三个库的offset是330

综上,min在全局的offset是333+331+330=994

数据库分表分页实现方案_第3张图片

 

第二次查询在各个分库返回的结果集是有序的,又知道了min在全局的offset是994,一路排下来,容易知道全局offset 1000 limit 5的一页记录(上图中黄色记录)。

是不是非常巧妙?这种方法的优点是:可以精确的返回业务所需数据,每次返回的数据量都非常小,不会随着翻页增加数据的返回量。

总结来说,就是根据偏移量找出其中最小值,在取出当前库最小值和最大值的数据,拿出来排序,去掉差值,再取分页条数。

 

 

你可能感兴趣的:(数据库分表分页实现方案)