假设有一张用户表,经过分库分表之后,现在均匀分布在2台服务器。每个服务器2张表
1. 全局视野法:因为不清楚按照时间排序之后的第三页数据到底是如何分布在数据库上的,所以必须每个库都返回3页数据,所得到的6页数据在服务层进行内存排序,得到全局视野,再取第3页数据。
优点:通过服务层修改,扩大数据查询量,得到全局视野,业务无损,精确
缺点(显而易见):每个分库都需要返回更多的数据,增大网络传输量;除了数据库要按照time排序,服务层也需要二次排序,损耗性能;随着页码的增大,性能极具下降,数据量和排序量都将大增,性能平方级下降。
2. 业务折中
2.1 禁止跳页查询,不提供“直接跳到指定页面”的功能,只提供下一页的功能。极大的降低技术方案的复杂度。第一页的选取方法和全局视野法一样,但是点击下一页时:
2.1.1先找到上一页的time的最大值,作为第二页数据拉去的查询条件,只取每页的记录数,
2.2.2这样服务层还是获得两页数据,再做一次排序,获取一页数据。
2.2.3改进了不会因为页码增大而导致数据的传输量和排序量增大
3. 允许数据精度丢失:需要考虑业务员上是否接受在页码较大是返回的数据不是精准的数据。
3.1在数据量较大,且ID映射分布足够随机的话,应该是满足等概率分布的情况的,所以取一页数据,我们在每个数据库中取前半页。
3.2当然这样的到的结果并不是精准的,但是当实际业务可以接受的话, 此时的技术方案的复杂度变大大降低。也不需要服务层内存排序了。
4. 二次查询法:既满足业务的精确需求,也无需业务折中。现在假设每页显示10条数据,要查第三页,数据分了两个库。 正常的语句是 select * from table order by time offset 20 limit 10,取偏移20个之后的10个
4.1首次查询查询每个库的select * from table order by time offset 10 limit 10;得到10条数据。这里的offset是总offset/分库数
4.2 服务层得到来自两个分库的结果集,得到最小的time,也就是最顶层的time,这个time满足最少有10条记录在它前面,然后分别记录每个库的最大time
4.3 分别再次查询最小time->每个库上一次的最大time的数据,得到每个库的查询结果
4.4 在每个集合的最小time都是相同的,所以可以得到该最小time在整个数据库中的offset,加起来就是这个最小time在全局库的offset位置。
4.5 再将第二次查询的结果集拼起来和得到的最小time的offset,推导出 offset 20 limit 10的一页记录。
优点:可以精确得到业务数据,且每次返回的数据量都非常小,不会随着页码增加而数据量增大。
缺点:需要进行两次数据库查询
5.通过额外的添加一张关联表,属性中必有id属性,至于是否有库id属性和表id属性(既第几个库和第几个表)可有可无,因为这个可以根据id自行取模获取,注意这张表存放的数据是所有数据,但是胜在属性列少,只有提供索引的几个属性列,这样的话我们只需要select * from brand_temp where … limit 400,10(插叙第41页的数据,每页显示5条数据),然后我们获取了id之后就可以去对应的表中查询了