然后进行第二次方案优化,既然hash分区和key分区要求其中的一列必须是int类型的,那么创造出一个int类型的列出来分区是否可以。分析发现,银行卡的那串数字有秘密。银行卡一般是16位到19位不等的数字串,我们取其中的某一位拿出来作为表分区是否可行呢,通过分析发现,在这串数字中,其中确实有一位是0到9随机生成的,不同的卡串长度,这一位不同,绝不是最后一位,最后位数字一般都是校验位,不具有随机性。我们新设计的方案,基于银行卡号+随机位进行KEY分区,每次查询的时候,通过计算截取出这位随机位数字,再加上卡号,联合查询,达到了分区查询的目的,需要说明的是,分区后,建立的索引,也必须是分区列,否则的话,Mysql还是会在所有的分区表中查询数据。那么通过银行卡号查询绑定关系的问题解决了,那么证件号呢,如何通过证件号来查询绑定关系。前面已经讲过,做索引一定是要在分区健上进行,否则会引起全表扫描。我们再创建了一张新表,保存客户的证件号绑定关系,每位客户的证件号都是唯一的,新的证件号绑定关系表里,证件号作为了主键,那么如何来计算这个分区健呢,客户的证件信息比较庞杂,有身份证号,港澳台通行证,机动车驾驶证等等,如何在无序的证件号里找到分区健。为了解决这个问题,我们将证件号绑定关系表一分为二,其中的一张表专用于保存身份证类型的证件号,另一张表则保存其他证件类型的证件号,在身份证类型的证件绑定关系表中,我们将身份证号中的月数拆分出来作为了分区健,将同一个月出生的客户证件号保存在同一个区,这样分成了12个区,其他证件类型的证件号,数据量不超过10万,就没有必要进行分区了。这样每次查询时,首先通过证件类型确定要去查询哪张表,再计算分区健进行查询。
作了分区设计之后,保存2000万用户数据的时候,银行卡表的数据保存文件就分成了10个小文件,证件表的数据保存文件分成了12个小文件,解决了这两个查询的问题,还剩下一个问题就是,业务编号呢,怎么办,一个客户有多个签约业务,如何进行保存,这时候,采用分区的方案就不太合适了,它需要用到分表的方案。
分库分表
如何进行分库分表,目前互联网上有许多的版本,比较知名的一些方案:
•阿里的TDDL,DRDS和cobar,
•京东金融的sharding-jdbc;
•民间组织的MyCAT;
•360的Atlas;
•美团的zebra
其他比如网易,58,京东等公司都有自研的中间件。
百花齐放的景象。但是这么多的分库分表中间件方案,归总起来,就两类: client模式和proxy模式 。
client模式
proxy模式
无论是client模式,还是proxy模式,几个核心的步骤是一样的:SQL解析,重写,路由,执行,结果归并。个人比较倾向于采用client模式,它架构简单,性能损耗也比较小,运维成本低。如果在项目中引入mycat或者cobar,他们的单机模式无法保证可靠性,一旦宕机则服务就变得不可用,你又不得不引入HAProxy来实现它的高可用集群部署方案, 为了解决HAProxy的高可用问题,又需要采用Keepalived来实现。
我们在项目中放弃了这个方案,采用了shardingjdbc的方式。回到刚才的业务问题,如何对业务类型进行分库分表。分库分表第一步也是最重要的一步,即sharding column的选取,sharding column选择的好坏将直接决定整个分库分表方案最终是否成功。而sharding column的选取跟业务强相关。在我们的项目场景中,sharding column无疑最好的选择是业务编号。通过业务编号,将客户不同的绑定签约业务保存到不同的表里面去,查询时,根据业务编号路由到相应的表中进行查询,达到进一步优化sql的目的。
前面我们讲到了基于客户签约绑定业务场景的数据库优化,下面我们再聊一聊,对于海量数据的保存方案。
垂直分库