2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > mysql 查询偶数 mysql分库分表后 – 数据库 – 前端 php sql server mysql

mysql 查询偶数 mysql分库分表后 – 数据库 – 前端 php sql server mysql

时间:2021-12-07 09:37:06

相关推荐

mysql 查询偶数 mysql分库分表后 – 数据库 – 前端 php sql server mysql

这种情况下的分库分表非常好处理,因为大家能够强制的按照时间线将订单存储到不同的库中。但是,有可能大家的电商系统用户量大,订单量多,一天就有几十万单,可能仅仅半个月,大家的订单量就会上千万,再加上订单的商品数据表,如果不分表,订单表可能就会把系统给拖垮。

那么大家就必须面临将1个月内的数据也要按照一定的规则进行分库分表。大家可以将订单表一分为二,分为了OrderDB1,OrderDB2,按照大家按照订单号来进行区分。订单号是单数,大家就放到OrderDB1中,订单号是双数,大家就放到OrderDB2中。如此一来,订单表的数据就被平均的分配到了两个数据库的表中了,单表的压力也就降低了。

而这样分库分表以后,大家的订单表如果需要进行分页的排序就非常困难了,两个数据库中的数据如何进行跨库的分页排序查询呢?

一般大家有三种方法,分别是:全局视野方式、允许精度损失方式、二次查找方式。

先说全局视野方式

通常情况下大家要查找第三页的100条订单数据,大家会写一个SQL

select * from T order by time offset 200 limit 100;

但是分库以后,这100条数据可能存在很多种方式。

有可能是平均分布(极端情况)

也有可能是全部来自一个库(极端情况)

还有可能是散乱分布的(通常情况)

由于情况根据大家的Order By条件有很多的可能,所以大家很难知道第三页的数据到底从哪个库的哪个位置开始取数。如果大家需要精准的取到数据,那么就必须重新还原单库的那种全局视野。

如何还原全局视野呢?

还是用大家要查询第三页的数据来举例,大家之所以失去了全局视野,是因为大家无法一次性得到所有的数据结果,那么还原全局视野的方式就是让大家能够得到所有的数据结果。因此,大家可以将两个库中的从第一页到第三页的全部数据查询出来,然后在内存中合并后再进行排序,然后就能够取出正确的第三页数据了。

自然,大家的sql也就发生了变化,从

select * from T order by time offset 200 limit 100;

改为

select * from T order by time offset 0 limit 100+200;

使用全局视野方式的好处很明显,就是数据绝对的精准。但是缺点也同样明显,当查询的数据量大时,内存的消耗就会变多,而且在页码增大的时候,查询效率会急速的下降。当大家有N个数据库,大家需要从查询X到X+Y区间的数据时,那么大家的内存中将会需要组合N*(X+Y)条数据然后排序。

既然全局查询的方式有缺点,那大家就来解决这个缺点,但是肯定会有一些其他方面的牺牲。

允许精度损失方式

允许精度损失其实非常的好理解,就是偶不去管数据在两个DB中是如何的分布的,偶只是平均的从两个库中排序后取出50条数据,然后组合成为100条进行显示。

当然,这种方式的精度就是根据你排序的条件和数据存储的方式不同而变化的了。假设大家的数据都是按照时间有序的存储的,大家的排序也是根据时间来进行排序的,那么大家得到的结果就会比较精准。

但如果大家的数据是随机插入多个DB的,大家要按照时间进行排序查找,或者大家的数据是按照时间顺序插入DB的,但是大家需要根据其他条件进行查找时,数据的精度就会很差。这就看大家对于业务的需要是什么样的了。

不过,使用这种方式查找,大家就可以不用考虑性能上的问题,查询的复杂程度很低,只要大家的业务没有过多的要求,那么使用这种查找方式是最为推荐的。

当然,如果你的业务不允许这样的情况出现,还需要满足交互、效率等等各种需求,那么,就大家还可以使用下面这个方式。

二次查询方式

这可以说是解决分库查询的究极武器了,能够保证数据的精准度、查询的效率、用户的交互页面,牺牲的只是小小的性能开销和一些代码难度的上升。

方式其实也不难,假设大家要查询第21页的数据,每页5条。这个时候,大家先假设数据是平均分布的,但是大家在每个库都查询全量的5条数据。也就是:

select * from T order by time offset 100 limit 5;

这时,大家得到的数据可能是这样的。

而两个DB中,最小的时间是1487500001【minTime】,这个时间记录下来。两个DB中各自的最大时间也记录下来,分别是DB1:1487500041【maxTime1】 和 DB2:1487500061【maxTime2】。

这时,大家在使用时间去两个数据库中再次进行查询。

select * from T where time between minTime and maxTime1 order by time; select * from T where time between minTime and maxTime2 order by time;

由于之前minTime来自于DB1,因此,DB1的数据不会发生变化,但是DB2中的条件被放宽了,因此可能会查询出更多的数据。结果可能如下:

而两个结果集合并以后,相当于就获得了全局视野,也就可以很容易的找出这一页需要的5条数据了。

当然,大家还可以借助elasticsearch来完成分库的排序查找,由于elasticsearch引入了缓存机制,能够让查询更快。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。