实操
1、单库多表
单库多表是对数据的水平拆分,多张表的表结构完全相同,数据按照不同的规则进行拆分,存储到对于的数据表中。
这是我安装数据的年份进行拆分的数据表,数据存储的时候根据数据的年份存到对于的表中,我们的查询业务也都是按照年份进行,一般没有跨年份的数据查询,这样就避免了多表查询后数据的合并。
2、多库单表
完全相同的数据库,安装不同规则存储各自的数据,下面是我的spring boot多数据源配置:
#更多数据源
custom.datasource.names=jiangsu,anhui,shandong,hubei,hunan,fujian
custom.datasource.jiangsu.type=com.zaxxer.hikari.HikariDataSource
custom.datasource.jiangsu.driverClassName=com.mysql.jdbc.Driver
custom.datasource.jiangsu.url=jdbc:mysql://127.0.0.1:3306/nda_jiangsu?useUnicode=yes&characterEncoding=UTF-8
custom.datasource.jiangsu.username=root
custom.datasource.jiangsu.password=
custom.datasource.anhui.type=com.zaxxer.hikari.HikariDataSource
custom.datasource.anhui.driverClassName=com.mysql.jdbc.Driver
custom.datasource.anhui.url=jdbc:mysql://127.0.0.1:3306/nda_anhui?useUnicode=yes&characterEncoding=UTF-8
custom.datasource.anhui.username=root
custom.datasource.anhui.password=
custom.datasource.shandong.type=com.zaxxer.hikari.HikariDataSource
custom.datasource.shandong.driverClassName=com.mysql.jdbc.Driver
custom.datasource.shandong.url=jdbc:mysql://127.0.0.1:3306/nda_shandong?useUnicode=yes&characterEncoding=UTF-8
custom.datasource.shandong.username=root
custom.datasource.shandong.password=
custom.datasource.hubei.type=com.zaxxer.hikari.HikariDataSource
custom.datasource.hubei.driverClassName=com.mysql.jdbc.Driver
custom.datasource.hubei.url=jdbc:mysql://127.0.0.1:3306/nda_hubei?useUnicode=yes&characterEncoding=UTF-8
custom.datasource.hubei.username=root
custom.datasource.hubei.password=
custom.datasource.hunan.type=com.zaxxer.hikari.HikariDataSource
custom.datasource.hunan.driverClassName=com.mysql.jdbc.Driver
custom.datasource.hunan.url=jdbc:mysql://127.0.0.1:3306/nda_hunan?useUnicode=yes&characterEncoding=UTF-8
custom.datasource.hunan.username=root
custom.datasource.hunan.password=
custom.datasource.fujian.type=com.zaxxer.hikari.HikariDataSource
custom.datasource.fujian.driverClassName=com.mysql.jdbc.Driver
custom.datasource.fujian.url=jdbc:mysql://127.0.0.1:3306/nda_fujian?useUnicode=yes&characterEncoding=UTF-8
custom.datasource.fujian.username=root
custom.datasource.fujian.password=
这是按照省进行数据拆分,保证各个省的数据完整性
在相关业务操作的时候,根据用户所在的省份查询对应的数据库:
DynamicDataSourceContextHolder.setDataSourceType(provincename);
3、多库多表
在介绍多库多表的时候,给大家介绍一个轻量级分库分表工具,sharding-jdbc,这是当当网自己实现的基本JDBC的数据库多库多表解决方案。可以让你在写业务代码的时候完全按照单库单表进行,多库多表的问题有sharding-jdbc帮你解决,需要自己实现分库分表规则接口,配置分库分表规则。
pom.xml配置
实现分库规则接口
public class DemoDatabaseShardingAlgorithm implements PreciseShardingAlgorithm{ @Override
public String doSharding(Collectioncollection, PreciseShardingValue preciseShardingValue) {
for (String each : collection) {
System.out.println(each+"=="+preciseShardingValue.getValue());
if (each.endsWith(Long.parseLong(preciseShardingValue.getValue().toString()) % 2+"")) {
return each;
}
}
throw new IllegalArgumentException();
}
}
实现分表规则接口
public class DemoTableShardingAlgorithm implements PreciseShardingAlgorithm{
@Override
public String doSharding(Collectioncollection, PreciseShardingValue preciseShardingValue) {
for (String each : collection) {
System.out.println(each+"=2="+preciseShardingValue.getValue());
if (each.endsWith(Long.parseLong(preciseShardingValue.getValue().toString()) % 2+"")) {
return each;
}
}
throw new IllegalArgumentException();
}
}
调用规则
@Bean(name = "shardingDataSource")
DataSource getShardingDataSource() throws SQLException {
ShardingRuleConfiguration shardingRuleConfig;
shardingRuleConfig = new ShardingRuleConfiguration();
shardingRuleConfig.getTableRuleConfigs().add(getUserTableRuleConfiguration());
shardingRuleConfig.getBindingTableGroups().add("user_info");
shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new StandardShardingStrategyConfiguration("user_id", DemoDatabaseShardingAlgorithm.class.getName()));
shardingRuleConfig.setDefaultTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("user_id", DemoTableShardingAlgorithm.class.getName()));
return new ShardingDataSource(shardingRuleConfig.build(createDataSourceMap()));
}
这样完成以后,业务代码就可以完全按照单表就行书写,Sharding-JDBC会自动帮你实现分库分表的数据库插入,以及查询时候的多表数据合并。
Sharding-JDBC 采用在 JDBC 协议层扩展分库分表,是一个以 jar 形式提供服务的轻量级组件,其核心思路是小而美地完成最核心的事情。
Sharding-JDBC 还提供了读写分离的能力,用于减轻写库的压力。
此外,Sharding-JDBC 可以用在 JPA 场景中,如 JPA、Hibernate、Mybatis,Spring JDBC Template 等任何 Java 的 ORM 框架。
不过目前Sharding-JDBC仅支持mysql数据库
然后还有一个第三方插件mycat也可以实现分库分表的数据插入和查询,不过mycat是基于 Proxy,它复写了 MySQL 协议,将 Mycat Server 伪装成一个 MySQL 数据库,而 Sharding-JDBC 是基于 JDBC 接口的扩展,是以 jar 包的形式提供轻量级服务的。
在使用中将mycat查询启动,它自己就成为了一个虚拟数据库,而业务程序是连接的mycat的虚拟数据库的,然后mycat连接实际数据库实现数据的分库分表。