上一篇我们简单实现分库分表,:先参考文章。
1、上一篇只有在保存分库分表的 user_info表的时候,数据库不报错,其他的表操作都报错:如下
Caused by: org.apache.ibatis.exceptions.PersistenceException:
### Error updating database. Cause: java.lang.IllegalStateException: Missing the data source name: 'null'
### The error may involve com.huobi.earning.admin.db.mapper.TblUserMapper.insert-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO tbl_user ( `name`, city_id, sex, phone, email, create_time, `password` ) VALUES ( ?, ?, ?, ?, ?, ?, ? )
### Cause: java.lang.IllegalStateException: Missing the data source name: 'null'
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:200)
at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:185)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433)
... 122 common frames omitted
Caused by: java.lang.IllegalStateException: Missing the data source name: 'null'
tbl_user 表没有进行分库分表,执行操作时找不到默认的数据源,就报错了
2、某些表分库分表,要保证其他的表不报错,应该添加默认数据源:主要变更如下
config:
sharding:
tables:
user_info:
actual-data-nodes: pr_master_slave.user_info$->{0..1}
database-strategy: #分库策略
inline: #行表达式
sharding-column: gender #列名称,多个列以逗号分隔
algorithm-expression: user$->{gender % 2} #按模运算分配
table-strategy: #分表策略
inline: #行表达式
sharding-column: user_id
algorithm-expression: user_info$->{user_id % 2}
default-data-source-name: pr_master_slave #未配置分片规则的表将通过默认数据源定位
binding-tables: user_info #绑定表规则列表
master-slave-rules: #数据库主从的划分
pr_master_slave:
master-data-source-name: user0 #主数据库
slave-data-source-names: user1 #从数据库
主从数据库,主的挂掉,用从的库;主库复制增删改,从库负责查询。
3、以上介绍单张表分库分表,下面介绍多张表分库分表,主要是该配置:
config:
sharding:
tables:
user_info:
actual-data-nodes: pr_master_slave.user_info$->{0..1}
database-strategy: #分库策略
inline: #行表达式
sharding-column: gender #列名称,多个列以逗号分隔
algorithm-expression: user$->{gender % 2} #按模运算分配
table-strategy: #分表策略
inline: #行表达式
sharding-column: user_id
algorithm-expression: user_info$->{user_id % 2}
u_info:
actual-data-nodes: pr_master_slave.u_info$->{0..1}
database-strategy: #分库策略
inline: #行表达式
sharding-column: gender #列名称,多个列以逗号分隔
algorithm-expression: user$->{gender % 2} #按模运算分配
table-strategy: #分表策略
inline: #行表达式
sharding-column: user_id
algorithm-expression: u_info$->{user_id % 2}
设置了两张表进行分库分表,依次往下添加。
4、当然了,分库分表有很多的规则,根据自己的实际业务场景设置是最好的方案:
比如 % 3,% 5 ,% 6 %10等等,也可以定义一个类定义分片规则:
config:
sharding:
tables:
user_info:
actual-data-nodes: pr_master_slave.user_info$->{0..9}
table-strategy:
standard:
sharding-column: user_id
precise-algorithm-class-name: com.nandan.rule.CommonShardingAlgorithm #分片规则类
CommonShardingAlgorithm 类的大概内容:
import java.util.Collection;
import io.shardingsphere.api.algorithm.sharding.PreciseShardingValue;
import io.shardingsphere.api.algorithm.sharding.standard.PreciseShardingAlgorithm;
/**
* 常用分表方式 实现 PreciseShardingAlgorithm 的接口
*/
public class NanDaoShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
@Override
public String doSharding(Collection<String> tableNames, PreciseShardingValue<Long> shardingValue) {
String tableId = shardingValue.getValue()+"";
String key = tableId.substring(tableId.length()-1);
int index = Integer.valueOf(key) % 10;
for (String each : tableNames) {
if(each.endsWith(index+"")){
return each;
}
}
return tableNames.iterator().next();
}
}
特别注意:
A、分库分表的策略不能中途更改,取模算法的id会出错,
B、查询不支持特殊sql,包括去重,子sql,聚合等等,
C、查询会给所有表发查询sql, 带上分库, 分表的字段的查询只发一条,
D、查询数据时要注意,尽量带上分库或分表字段来查询,避免多表查sql过多,影响性能。
到此,分库分表的基本流程是可以了,下篇分享读写分离,敬请期待!