分库分表初见
曾经为了面试,熟读并背诵了那么多骚操作,对于数据库这方面,常会背到的就是 sql 优化,分库分表了。
当分表来临时
昨天一个戴眼镜的老哥告诉我
有一个表未来数据量会比较大,我准备给他切了,可能会影响你那边。
我去?飞来横祸?我这 CRUD 过的很开心,分什么表啊。为此赶紧调动我面试时背诵的各种知识点,跟老哥进行一场 battle,渴望不分表,继续单表开开心心。可惜败下阵来,还是太年轻了。没办法,开始 coding 吧!
最开始想是直接引入 sharding-jdbc,第一次操作,不得不说 sharding-jdbc 的文档真不怎么样,搞了半天总是报错,各种错,反正是没跑起来。于是乎,一个骚操作涌上心头。我这边对这个表的操作很简单,就是 select,实在不行,直接改 sql 吧。我要是直接把
代码语言:javascript复制select * from table
改成
代码语言:javascript复制 select * from table0
union
select * from table1
union....
那未来承接这个项目的同学可能会把我骂死,不过让他骂不到也很容易,三下五除二,把代码上的 created by 署名删除了,嗯!完美!hahahahahha.....冷静三秒之后,觉得还是不要这么搞了,毕竟我是一个专业的软件工程师,担负着拯救人类的重任。算了,再想想招儿吧。ORM 用的是 mybatis,于是乎一个想法涌上心头,mybatis 不是有插件嘛,我直接来个统一处理完事了呗,不得不佩服自己的机智,很快搞了起来。
demo(地址附在文末)
talk is cheap,show me the code -----大师如此说道
mybatis 插件其实就是拦截器,可以用申明签名的方式,指定我们要拦截的方法,从中获取我们需要的信息,加入自定义的逻辑操作。也就是说,它可以帮我们拦截 sql,在 sql 提交给 jdbc 执行前的那一刻,将他拦截下来,判断他的分表策略和操作类型(demo 中以注解的形式申明),然后进行 sql 处理(demo 中使用的是 druid 的 sql 解析模块),整合出我们最终需要的 sql。
当然了,这么典型的需求,肯定已经有人做好轮子等着我们去用了,就如上面对话中所提及的几个,比如其中的 sharding-jdbc,做的就是帮我们拦截 sql,解析 sql,路由执行,结果聚合。这一切对于我们用户是透明的,我们无需改任何代码,只要加入 sharding-jdbc 的配置参数就可以开心的分库分表了,但考虑到各种原因,有些复杂 sql 是不支持的,这个可以参考官方文档。
这个 demo 记录了从单表操作到自定义分表插件,再到使用 sharding-jdbc 进行分表操作的全历程。demo 只能演示 select * from table 这样简单语句的全套操作历程,但也足以体现整个思路。使用自定义插件实现分表对应的是 demo 中的 version2 分支。使用sharding-jdbc 完成分表对应的是 demo 中的 version3 分支。
详见demo
地址:https://github.com/naget/sharding
参考资料
- https://github.com/alibaba/druid/wiki/SQL-Parser
- https://mp.baomidou.com/guide/quick-start.html#添加依赖
- https://github.com/apache/incubator-shardingsphere/issues/1900
- https://mybatis.org/mybatis-3/zh/configuration.html#plugins