shardindjdbc-inline策略
shardingjdbc官网https://shardingsphere.apache.org/document/current/cn/overview/
Apache ShardingSphere 是一款开源的分布式数据库生态项目,由 JDBC 和 Proxy 两款产品组成。其核心采用微内核+可插拔架构,通过插件开放扩展功能。它提供多源异构数据库增强平台,进而围绕其上层构建生态。
Apache ShardingSphere 设计哲学为 Database Plus,旨在构建异构数据库上层的标准和生态。它关注如何充分合理地利用数据库的计算和存储能力,而并非实现一个全新的数据库。它站在数据库的上层视角,关注它们之间的协作多于数据库自身。
sql和源码
https://gitee.com/zhangjijige/shardingjdbc.git
分片策略
InlineShardingStrategy策略
最常用的分片策略
application-inline.yml 文件
spring:
main:
allow-bean-definition-overriding: true
shardingsphere:
# 参数配置,显示 sql
props:
sql:
show: true
datasource:
# 数据源别名
names: db0, db1, db2, db3
# db0数据源信息
db0:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/order_db_0?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
db1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/order_db_1?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
db2:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/order_db_2?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
db3:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/order_db_3?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
sharding:
default-database-strategy:
inline:
sharding-column: user_id
algorithm-expression: db$->{user_id % 4}
default-table-strategy:
inline:
sharding-column: order_id
algorithm-expression: tbl_order_$->{order_id % 4}
tables:
# 逻辑表名
tbl_order:
# 指定数据节点
actual-data-nodes: db$->{0..3}.tbl_order_$->{0..3}
# # 分库策略
# database-strategy:
# inline:
# sharding-column: user_id
# algorithm-expression: db$->{user_id % 4}
# # 分表策略
# table-strategy:
# inline:
# sharding-column: order_id
# algorithm-expression: tbl_order_$->{order_id % 4}
mybatis:
mapper-locations: classpath:mapper/*.xml
default-database-strategy和default-table-strategy的意思是默认的分库分表策略,这里要注意的是
要写清楚逻辑表和指定的节点
# 逻辑表名
tbl_order:
# 指定数据节点,可以配合默认的分库分表策略default-database-strategy和default-table-strategy
actual-data-nodes: db$->{0..3}.tbl_order_$->{0..3}
当然也可以用自己的策略,策略可以看到是针对4取模
# 分库策略
database-strategy:
inline:
sharding-column: user_id
algorithm-expression: db$->{user_id % 4}
# 分表策略
table-strategy:
inline:
sharding-column: order_id
algorithm-expression: tbl_order_$->{order_id % 4}
如果查询的表,不需要分库分表就需要
sharding:
#这个就是默认的数据源,比如要查询 user表,没有给user表配置策略,那就直接使用默认的db0数据库
#表就是使用user表,这样就找到了 db0库的user表
default-data-source-name: db0
tables:
# 逻辑表名
tbl_order:
# 指定数据节点
actual-data-nodes: db$->{0..3}.tbl_order_$->{0..3}
# 分库策略
database-strategy:
inline:
sharding-column: user_id
algorithm-expression: db$->{user_id % 4}
# 分表策略
table-strategy:
inline:
sharding-column: order_id
algorithm-expression: tbl_order_$->{order_id % 4}
这里介绍一下,tbl_order是表名称在配置文件中是如何生效的其实很简单
image.png
image.png
图中
private Map<String, YamlTableRuleConfiguration> tables = new LinkedHashMap<>();
map的key就是tbl_order,这样就能解释在配置文件中使用动态属性
从上述配置可以知道user_id作为分库键,order_id作为分表键
如何使用
@Test
public void insertOrder() {
for (int i = 0 ; i <100; ++i) {
OrderDto orderDto = new OrderDto();
//使用雪花算法作为orderid和userid,在入库的时候根据配置的策略入库
orderDto.setOrderId(SnowFlakeUtil.getId());
orderDto.setUserId(SnowFlakeUtil.getId());
orderDto.setCreateTime(new Date());
orderDto.setUpdateTime(new Date());
orderDto.setPrice(new BigDecimal("100"));
orderMapper.addOrder(orderDto);
}
}
inline策略比较常用,配上也比较简单,db$->{user_id % 4}策略,使用的是Groovy表达式.查询的时候支持 =和in的方式,如果是范围 比如between 大于小于是不支持的
绑定关联和广播
绑定关联
tables:
# 逻辑表名
tbl_order:
# 指定数据节点
actual-data-nodes: db$->{0..3}.tbl_order_$->{0..3}
# 分库策略
database-strategy:
inline:
sharding-column: user_id
algorithm-expression: db$->{user_id % 4}
# 分表策略
table-strategy:
inline:
sharding-column: order_id
algorithm-expression: tbl_order_$->{order_id % 4}
# 逻辑表名
tbl_user:
# 指定数据节点
actual-data-nodes: db$->{0..3}.tbl_user_$->{0..3}
# 分库策略
database-strategy:
inline:
sharding-column: user_id
algorithm-expression: db$->{user_id % 4}
# 分表策略
table-strategy:
inline:
sharding-column: order_id
algorithm-expression: tbl_user_$->{order_id % 4}
bindingTables:
- tbl_order,tbl_user
bindingTables标签代表绑定关系,两张表做join的情况下使用
首先两张表的分库分表策略要完全一致,分片建数值也要完全一致, on的条件必须得是分片建
这样tbl_order表和tbl_user表在关联的时候只需关联一次即可,而不是做笛卡尔积
不绑定在查询所有数据的时候会出现tbl_order_0关联tbl_user_1 的情况,因为分表的策略是一样的
导致tbl_user的数据为空
image.png
示例中分库和分表的列不同,所以on作为条件的时候要把分库建和分表建都作为条件,
如果on条件不是分片建,很可能会出现本应该匹配的数据匹配不上.
广播表
广播表就是每个数据库都有一张表,比如字典表,数据量不大,就可以让所有的数据同时放到每个数据库中,每个数据库的数据是一致的,这样在查询数据的时候直接从本地库查找字典表的数据就可以了
配置非常的简单
spring.shardingsphere.sharding.broadcast-tables=t_dict
image.png
当insert数据的时候,会向4个库同时插入
数据就会同步到每个数据库中,查询的时候只会从一个数据库中,每次查询的数据库是不一样的,应该是随机的,这块没有太细的研究.
image.png