MyBatis实现Mysql数据库分库分表操作和总结

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

MyBatis实现Mysql数据库分库分表操作和总结
前⾔
作为⼀个数据库,作为数据库中的⼀张表,随着⽤户的增多随着时间的推移,总有⼀天,数据量会⼤到⼀个难以处理的地步。

这时仅仅⼀张表的数据就已经超过了千万,⽆论是查询还是修改,对于它的操作都会很耗时,这时就需要进⾏数据库切分的操作了。

MyBatis实现分表最简单步骤
既然⽂章的标题都这么写了,不如直接上⼲货来的⽐较实际,我们就先来看看如何实现最简单的分表。

1、我们模拟⽤户表数据量超过千万(虽然实际不太可能)
2、⽤户表原来的名字叫做user_tab,我们切分为user_tab_0和user_tab_1(实际也可能不是这么随意的名字),这样就能把原来千万的数据分离成两个百万的数据量的两张表了。

3、如何操作这两张表呢?我们利⽤userId也就是⽤户的唯⼀标识进⾏区分。

4、userId%2 == 0的⽤户操作表user_tab_0,同理userId%2 == 1的⽤户操作表user_tab_1
5、那么在MyBatis中sql语句如何实现呢?下⾯是举例查询⼀个⽤户的sql语句
<select id="getUser" parameterType="java.util.Map" resultType="UserDO">
SELECT userId, name
FROM user_tab_#{tabIndex}
WHERE userId = #{userId}
</select>
其中我们传⼊了两个参数tabIndex和userId,tabIndex就是需要操作表的标⽰值(0或1),这样如果需要查询userId为5的⽤户,那么最终出现的sql语句就会是:
SELECT userId, name
FROM user_tab_1
WHERE userId = 5
其他多余的DAO服务和实现我这⾥就不多展⽰了,相信聪明的你肯定会的。

以上就是最简单的实现,不需要多余的框架,不需要任何的插件也就满⾜了分表的要求。

上⾯基本上就是所有实现的内容了,下⾯就要开始详细说说分离的细节了,看热闹的基本可以散了。

我将从下⾯⼏个⾓度分别来说说。

我尽可能⽤最简单的⽩话来说。

分离的⽅式
切分的⽅式主要有两种,⽔平切分和垂直切分。

1、⽔平切分
简单的说就是,把⼀张表分离成⼏张⼀模⼀样的表,然后表的名字不同。

就和上⾯最简单的例⼦⼀样。

这种切分适合于⼀张表的数据量过⼤⽽导致操作时间变慢的情况,如保存的⼀些记录表。

2、垂直切分
把不同的业务模块分成不同的数据库,这些业务模块直接最好是0耦合(简单的说就是毫⽆关系)。

这主要是适合数据量普遍较⼤,⽽且业务场景⽐较分散,互相之间没有逻辑关系的情况。

分离的策略
具体的策略有很多种,你也可以设计你⾃⼰的,普遍的策略有下⾯⼏种,只是列举就不具体展开了。

1、“%”取模,也就是上⾯例⼦中实现的,也是最简单的⼀种。

2、MD5哈希
3、移位
4、⽇期时间(根据不同的⽇期分表,如⼀个⽉⼀张表,这个⽉就操作这张表,下个⽉就下张表)
5、枚举范围(⽤户1-10000操作第⼀张表,⽤户10001-20000操作第⼆张表)
分离的问题
下⾯说说最终要的点,导致的问题。

数据库肯定不是你说分就分的。

(⼈家⽐较有感情的,怎么能说分就分呢?)
正经来说,我列举了下⾯⼏个分离只有会导致的问题。

1、添加时主键唯⼀性的问题;分离之后多张表,就会导致原有的⾃增长主键不唯⼀,所以没有办法⾃增长了,导致问题,解决⽅案的也是有的,⽐如单独维护⼀张主键表专门⽤来存放当前主键,或者说⽤别的中间件等。

2、新增时的效率问题,虽然不是个⼤问题,但是新增肯定会多了计算量嘛,这个问题可以忽略不计。

3、查询所带来的分页问题,分离成多张表之后,分页查询就很困难了,这也考虑到不同的分离⽤不同的解决⽅案,总之会产⽣问题。

4、同理,关联查询,原本⼀张表关联别的表或者别的表关联⼀张表,都很简单,但是现在分离之后就难了。

5、事务问题,多张表需要使⽤分布式事务才能完成原来带有事务的操作。

因为原来的事务只是锁⼀张表现在可能要锁多张了呢。

6、扩展性问题,有的切分策略下,对数据的扩展性其实不好,之后如果有更多的数据来了,是说还能再新建表来扩展吗?
分离的原则
下⾯总结了⼏点分离的原则,主要是参考了⽹络上的,没有任何实际的依据(我也不是个年薪百万的DBA也碰不到那么⼤的数据去实际检验嘛),所以如果有任何问题也请指出。

1、能不分就不分
2、能分少就不分多
3、多冗余,不关联
4、避免使⽤分布式事务,主要是太难我也不会啊
5、单表千万记录以内就不分
6、现在不分以后分也来得及
7、扩展,耦合,仔细考虑
实现分离的⽅式
最后说说分离的⽅式,现在流⾏使⽤的DAO框架是MyBatis,也有很多别的框架。

分离的实现主要有下⾯⼏种⽅式。

1、原⽣实现,就和最上⾯的例⼦⼀样,不需要其他任何的东西,利⽤原⽣的框架,⾃⼰去控制实现。

优点是:容易控制,掌握主动权。

缺点是:代码量多,需要⾃⼰很清楚,修改不⽅便,不⽀持复杂的切分,⽐如切分之后还需要做⼀些分页查询,还有上⾯说的主键问题等。

2、插件实现,利⽤框架本⾝开发的⼀些插件,去实现这些插件,然后利⽤插件去访问数据库,直接实现分离。

优点是:代码量少,实现简单,扩展性好。

缺点是:不易控制,分离⽅式有限,出现问题难以解决。

没有找到特别成熟的插件。

3、中间件实现。

利⽤⼀些数据库访问的中间件,在访问数据库之前做⼀些操作使得sql进⾏相应的变化从⽽实现分离。

优点是:耦合⼩,扩展性好,可以解决分布式事务的问题。

确定是:实现⽐较复杂,需要对中间件进⾏学习,成本较⼤。

维护也是⼀个⼤问题,万⼀挂掉了。

总之⽅式各有千秋,但是考虑到成本上⾯,第⼀种⼏乎是0成本,即可上⼿,⽽且⽐较容易控制,就如同最上⾯给出的例⼦⼀样,⽽且当前我处理的数据还没有到达那种处处要分离的地步,所以我选择第⼀种。

也推荐使⽤。

如果你找到⽐较好⽤的插件或者中间件也可以在评论中推荐。

总结
在实际项⽬中,我是因为⽤户的账户记录过多所以不得不进⾏分离,⽽且因为账户记录更多的只是新增没有修改和删除,查询也是少数,所以使⽤了最简单的⽅式进⾏分离,也选择了最简单的策略。

希望上⾯的原则策略⽅式和问题的总结能对你有所帮助,有所参考。

参考博客:
转载请注明出处:
作者:LinkinStar。

相关文档
最新文档