前言
随着系统数据量的日益增长,在说起数据库架构和数据库优化的时候,我们难免会常常听到分库分表这样的名词。
当然,分库分表有很多的方法论,比如垂直拆分、水平拆分;也有很多的中间件产品,比如MyCat、ShardingJDBC。
根据业务场景选择合适的拆分方法,再选择一个熟悉的开源框架,就能帮助我们完成项目中所涉及到的数据拆分工作。
本文并不打算就这些方法论和开源框架展开深入的探讨,笔者想讨论另外一个场景:
如果系统中需要拆分的表并不多,只是1个或者少量的几个,我们是否值得引入一些相对复杂的中间件产品;特别是,如果我们对它们的原理不甚了解,是否有信心驾驭它们 ?
基于此,如果你的系统中有少量的表需要拆分,也没有专门的资源去研究开源组件,那么我们可以自己来实现一个简单的分库分表插件;当然,如果你的系统比较复杂,业务量较大,还是采用开源组件或者团队自研组件来解决这事较为稳妥。
一、原理
分库分表这事说简单也简单,说复杂那也挺复杂...
简单是因为它的核心流程比较明确。就是解析SQL语句,然后根据预先配置的规则,重写或路由到真实的数据库表中去;
复杂在于,SQL语句复杂且灵活,比如分页、去重、排序、分组、聚合、关联查询等操作,如何正确的解析它们。
所以就算是ShardingJDBC
,在官网中也明确了支持项和不支持项。
二、注解式配置
相对于复杂的配置文件,我们采用较为轻便的注解式配置,它的定义如下:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Sharding {
String tableName(); //逻辑表名
String field(); //分片键
String mode(); //算法模式
int length() default 0; //分表数量
}
那么,在哪里使用它呢 ? 比如我们的用户表需要分表,那就在User这个实体对象上标注。
@Data
@Sharding(tableName = "user",field = "id",mode = "hash",length = 16)
public class User {
private Long id;
private String name;
pri