网站推广软件信息,网站搜索引擎优化技术,长安高端装备网站设计公司,建站seo怎么赚钱一、shardingSphere介绍
1、官网#xff1a;Apache ShardingSphere
2、开发文档#xff1a; 概览 :: ShardingSphere
3、shardingsphere-jdbc
ShardingSphere-JDBC 定位为轻量级 Java 框架#xff0c;在 Java 的 JDBC 层提供的额外服务。 它使用客户端直连数据库#x…一、shardingSphere介绍
1、官网Apache ShardingSphere
2、开发文档 概览 :: ShardingSphere
3、shardingsphere-jdbc
ShardingSphere-JDBC 定位为轻量级 Java 框架在 Java 的 JDBC 层提供的额外服务。 它使用客户端直连数据库以 jar 包形式提供服务无需额外部署和依赖可理解为增强版的 JDBC 驱动完全兼容 JDBC 和各种 ORM 框架。
官网示例图 4、shardingSphere-proxy 定位为透明化的数据库代理端提供封装了数据库二进制协议的服务端版本用于完成对异构语言的支持。 目前提供 MySQL 和 PostgreSQL版本它可以使用任何兼容 MySQL/PostgreSQL 协议的访问客户端如MySQL Command Client, MySQL Workbench, Navicat 等操作数据对 DBA 更加友好。
官网示例图 5、两者的区别 二、使用docker安装mysql服务器
1、docker未安装的请看
docker环境安装
注意如果此时防火墙是开启的则先关闭防火墙并重启docker否则后续安装的MySQL无法启动或者在服务器开放对应的端口号可以提前开启33013302330633073308331033113321 #关闭docker systemctl stop docker #关闭防火墙 systemctl stop firewalld #启动docker systemctl start docker 2、在docker中创建并启动MySQL主服务器
第一步创建并启动mysql docker run -d \ -p 3306:3306 \ -v /usr/local/docker/mysql/master/conf:/etc/mysql/conf.d \ -v /usr/local/docker/mysql/master/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD123456 \ --name lkx-mysql-master \ mysql:8.0.29 第二步创建MySQL主服务器配置文件 vim /usr/local/docker/mysql/master/conf/my.cnf 将以下配置复制进去并保存 [mysqld] # 服务器唯一id默认值1 server-id1 # 设置日志格式默认值ROW binlog_formatSTATEMENT # 二进制日志名默认binlog # log-binbinlog # 设置需要复制的数据库默认复制全部数据库 #binlog-do-dbmytestdb # 设置不需要复制的数据库 #binlog-ignore-dbmysql #binlog-ignore-dbinfomation_schema binlog格式说明 binlog_formatSTATEMENT日志记录的是主机数据库的写指令性能高但是now()之类的函数以及获取系统参数的操作会出现主从数据不同步的问题。 binlog_formatROW默认日志记录的是主机数据库的写后的数据批量操作时性能较差解决now()或者 user()或者 hostname 等操作在主从机器上不一致的问题。 binlog_formatMIXED是以上两种level的混合使用有函数用ROW没函数用STATEMENT但是无法识别系统变量
第三步 重启MySQL容器 docker restart lkx-mysql-master restart重启
start启动
stop停止
第四步使用命令行登录MySQL主服务器 并使root账号在数据库可视化工具可以连接 #进入容器env LANGC.UTF-8 避免容器中显示中文乱码 docker exec -it lkx-mysql-master env LANGC.UTF-8 /bin/bash #进入容器内的mysql命令行 mysql -uroot -p #修改默认密码校验方式 ALTER USER root% IDENTIFIED WITH mysql_native_password BY 123456; 第五步主机中创建slave用户 -- 创建slave用户 CREATE USER lkx_slave%; -- 设置密码 ALTER USER lkx_slave% IDENTIFIED WITH mysql_native_password BY 123456; -- 授予复制权限 GRANT REPLICATION SLAVE ON *.* TO lkx_slave%; -- 刷新权限 FLUSH PRIVILEGES; 第六步查看主服务器的binlog文件名以及位置号
注意此操作后不再操作此主mysql服务器防止主服务器状态值变化 SHOW MASTER STATUS; 此时记录binlog.0000003 1357两个值
3、在docker中创建并启动两个MySql从服务器
【1】重复执行创建MySql主服务器的第一步到第四步按顺序执行两遍。注意映射的端口号与容器名称别一样这里自定义就行。
我这里举个例子 docker run -d \ -p 3307:3306 \ -v /usr/local/docker/mysql/slave1/conf:/etc/mysql/conf.d \ -v /usr/local/docker/mysql/slave1/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD123456 \ --name lkx-mysql-slave1 \ mysql:8.0.29 docker run -d \ -p 3308:3306 \ -v /usr/local/docker/mysql/slave2/conf:/etc/mysql/conf.d \ -v /usr/local/docker/mysql/slave2/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD123456 \ --name lkx-mysql-slave2 \ mysql:8.0.29 【2】在从机上配置主从关系
注意一定要在从机上操作并且两台从机都要执行 CHANGE MASTER TO MASTER_HOST47.97.68.78, MASTER_USERlkx_slave,MASTER_PASSWORD123456, MASTER_PORT3306, MASTER_LOG_FILEbinlog.000003,MASTER_LOG_POS1357; 【3】启动主从同步 -- 在从服务器下查看状态不需要分号 SHOW SLAVE STATUS\G 我这边binlog文件名与位置不一样是因为我重启过服务所以这里你们显示的就是上一步配置的binlog文件名与位置号 两个关键进程下面两个参数都是Yes则说明主从配置成功 可能会出现一下情况这时候表示从机的IO还没启动好此时在等等然后再查看。 【4】测试主从同步的情况
在主机中执行以下SQL在从机中查看数据库、表和数据是否已经被同步。或者直接在可视化工具下操作主MySql服务器然后看从MySql服务器是否同步 CREATE DATABASE db_user; USE db_user; CREATE TABLE t_user ( id BIGINT AUTO_INCREMENT, uname VARCHAR(30), PRIMARY KEY (id) ); INSERT INTO t_user(uname) VALUES(zhang3); INSERT INTO t_user(uname) VALUES(hostname); 三、ShardingSphere-JDBC读写分离
1、创建SpringBoot项目
2、引入maven依赖
dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.apache.shardingsphere/groupIdartifactIdshardingsphere-jdbc-core-spring-boot-starter/artifactIdversion5.1.1/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdscoperuntime/scope/dependencydependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.3.1/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scopeexclusionsexclusiongroupIdorg.junit.vintage/groupIdartifactIdjunit-vintage-engine/artifactId/exclusion/exclusions/dependency
/dependencies
3、读写分离配置文件
server:port: 8888
spring:# 应用名称application:name: ShardingSphere-JDBC# 开发环境设置profiles:active: devshardingsphere:datasource:# 配置真实数据源names: master,slave1,slave2master:driver-class-name: com.mysql.jdbc.Driverjdbc-url: jdbc:mysql://47.97.68.78:3306/db_user?characterEncodingutf-8password: 123456type: com.zaxxer.hikari.HikariDataSourceusername: rootslave1:driver-class-name: com.mysql.jdbc.Driverjdbc-url: jdbc:mysql://47.97.68.78:3307/db_user?characterEncodingutf-8password: 123456type: com.zaxxer.hikari.HikariDataSourceusername: rootslave2:driver-class-name: com.mysql.jdbc.Driverjdbc-url: jdbc:mysql://47.97.68.78:3308/db_user?characterEncodingutf-8password: 123456type: com.zaxxer.hikari.HikariDataSourceusername: root# 内存模式mode:type: Memory# 打印SQl 在控制台查看日志输出可以知道此时是在哪个数据源进行操作。如Actual SQL: slave2props:sql-show: truerules:readwrite-splitting:data-sources:myds:# 负载均衡算法名称 自定义load-balancer-name: alg_roundprops:# 读数据源名称多个从数据源用逗号分隔read-data-source-names: slave1,slave2# 写数据源名称write-data-source-name: master# 读写分离类型如: StaticDynamictype: Staticload-balancers:alg_random:type: RANDOMalg_round:type: ROUND_ROBINalg_weight:props:slave1: 1slave2: 2type: WEIGHT4、创建实体类
TableName(t_user)
Data
public class User {TableId(type IdType.AUTO)private Long id;private String uname;
}
5、创建Mapper
Mapper
public interface UserMapper extends BaseMapperUser {
}
6、测试
6.1读写分离测试
Autowiredprivate UserMapper userMapper;/*** 不添加Transactionalinsert对主库操作select对从库操作*/Testpublic void insertTest() {User user new User();user.setUname(lkx1);user.setCreateTime(new Date());userMapper.insert(user);ListUser users userMapper.selectList(null);System.out.println(users);} 效果 Actual SQL: master ::: INSERT 可以看出insert语句实在master这个配置的数据源执行的 Actual SQL: slave1 ::: SELECT 可以看出查询实在slave1从库其中一个执行的 6.2事务测试
/*** 添加Transactional则insert和select均对主库操作*/TestTransactionalpublic void insertOfTransactionalTest() {User user new User();user.setUname(lkx_transactional);user.setCreateTime(new Date());userMapper.insert(user);ListUser users userMapper.selectList(null);System.out.println(users);}
效果 可以看出insert与select都是在master数据源库进行处理的然后因为添加了事务所以在测试环境就会数据回滚
6.3负载均衡读测试
/*** 读数据测试*/Testpublic void testSelectAll(){ListUser users1 userMapper.selectList(null);ListUser users2 userMapper.selectList(null);//执行第二次测试负载均衡}
效果 可以看出两个从库每个执行一边select语句,我这使用的是轮询的算法。这里可以修改规则有轮询、随机、权重三个规则。可以修改对应想要的查询算法 四、ShardingSphere-JDBC垂直分片
准备使用docker创建两个容器 服务器容器名server-user端口3301 服务器容器名server-order端口3302
4.1、创建server-user容器
第一步创建容器 docker run -d \ -p 3301:3306 \ -v /usr/local/docker/server/user/conf:/etc/mysql/conf.d \ -v /usr/local/docker/server/user/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD123456 \ --name server-user \ mysql:8.0.29 第二步登录MySQL服务器 #进入容器 docker exec -it server-user env LANGC.UTF-8 /bin/bash #进入容器内的mysql命令行 mysql -uroot -p #修改默认密码插件 ALTER USER root% IDENTIFIED WITH mysql_native_password BY 123456; 第三步创建数据库 CREATE DATABASE db_user; USE db_user; CREATE TABLE t_user ( id BIGINT AUTO_INCREMENT, uname VARCHAR(30), PRIMARY KEY (id) ); 4.2、创建server-order容器
第一步创建容器 docker run -d \ -p 3302:3306 \ -v /usr/local/docker/server/order/conf:/etc/mysql/conf.d \ -v /usr/local/docker/server/order/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD123456 \ --name server-order \ mysql:8.0.29 第二步登录MySQL服务器 #进入容器 docker exec -it server-order env LANGC.UTF-8 /bin/bash #进入容器内的mysql命令行 mysql -uroot -p #修改默认密码插件 ALTER USER root% IDENTIFIED WITH mysql_native_password BY 123456; 第三步创建数据库 CREATE DATABASE db_user; USE db_user; CREATE TABLE t_user ( id BIGINT AUTO_INCREMENT, uname VARCHAR(30), PRIMARY KEY (id) ); 4.3、创建SpringBoot项目实现
4.3.1、引入maven
dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.apache.shardingsphere/groupIdartifactIdshardingsphere-jdbc-core-spring-boot-starter/artifactIdversion5.1.1/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdscoperuntime/scope/dependencydependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.3.1/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scopeexclusionsexclusiongroupIdorg.junit.vintage/groupIdartifactIdjunit-vintage-engine/artifactId/exclusion/exclusions/dependency/dependencies
4.3.2、配置配置文件
server:port: 8887
spring:# 应用名称application:name: ShardingSphere-JDBC-Vertical-branch-library# 开发环境设置profiles:active: devshardingsphere:datasource:# 配置真实数据源names: server-user,server-orderserver-user:driver-class-name: com.mysql.jdbc.Driverjdbc-url: jdbc:mysql://47.97.68.78:3301/db_user?characterEncodingutf-8password: 123456type: com.zaxxer.hikari.HikariDataSourceusername: rootserver-order:driver-class-name: com.mysql.jdbc.Driverjdbc-url: jdbc:mysql://47.97.68.78:3302/db_order?characterEncodingutf-8password: 123456type: com.zaxxer.hikari.HikariDataSourceusername: root# 内存模式mode:type: Memory# 打印SQl 在控制台查看日志输出可以知道此时是在哪个数据源进行操作。如Actual SQL: slave2props:sql-show: truerules:sharding:tables:t_user:
# actual-data-nodes: server-user.t_user_${0..1}actual-data-nodes: server-user.t_usert_order:actual-data-nodes: server-order.t_order
4.3.3、创建实体与Mapper文件
TableName(t_order)
Data
public class Order {TableId(type IdType.AUTO)private Long id;private String orderNo;private Long userId;private BigDecimal amount;
}
Mapper
public interface OrderMapper extends BaseMapperOrder {
}
4.3.4、测试
【1】测试插入
Autowiredprivate OrderMapper orderMapper;Autowiredprivate UserMapper userMapper;Testvoid testInsertUserAndOrder(){User user new User();user.setUname(lkx777);user.setCreateTime(new Date());userMapper.insert(user);Order order new Order();order.setUserId(user.getId());order.setOrderNo(O123457);order.setAmount(new BigDecimal(100));orderMapper.insert(order);}
效果 由此可见插入的时候是插入到不同的库中。
【2】测试查询
/*** 垂直分片查询数据测试*/Testpublic void testSelectFromOrderAndUser(){User user userMapper.selectById(1L);Order order orderMapper.selectById(1L);}
效果 五、ShardingSphere-JDBC水平分片*重点*
准备使用docker创建两个容器
5.1、创建server-order0容器
第一步创建容器 服务器容器名server-order0端口3310 服务器容器名server-order1端口3311 docker run -d \ -p 3310:3306 \ -v /usr/local/docker/server/order0/conf:/etc/mysql/conf.d \ -v /usr/local/docker/server/order0/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD123456 \ --name server-order0 \ mysql:8.0.29 第二步登录MySQL服务器 #进入容器 docker exec -it server-order0 env LANGC.UTF-8 /bin/bash #进入容器内的mysql命令行 mysql -uroot -p #修改默认密码插件 ALTER USER root% IDENTIFIED WITH mysql_native_password BY 123456; 第三步创建数据库
注意水平分片的id需要在业务层实现不能依赖数据库的主键自增否则不同库会出现相同的主键 CREATE DATABASE db_order; USE db_order; CREATE TABLE t_order0 ( id BIGINT, order_no VARCHAR(30), user_id BIGINT, amount DECIMAL(10,2), PRIMARY KEY(id) ); CREATE TABLE t_order1 ( id BIGINT, order_no VARCHAR(30), user_id BIGINT, amount DECIMAL(10,2), PRIMARY KEY(id) ); 5.2、创建server-order1容器
第一步创建容器 docker run -d \ -p 3311:3306 \ -v /usr/local/docker/server/order1/conf:/etc/mysql/conf.d \ -v /usr/local/docker/server/order1/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD123456 \ --name server-order1 \ mysql:8.0.29 第二步登录MySQL服务器 #进入容器 docker exec -it server-order1 env LANGC.UTF-8 /bin/bash #进入容器内的mysql命令行 mysql -uroot -p #修改默认密码插件 ALTER USER root% IDENTIFIED WITH mysql_native_password BY 123456; 第三步创建数据库
注意水平分片的id需要在业务层实现不能依赖数据库的主键自增否则不同库会出现相同的主键 CREATE DATABASE db_order; USE db_order; CREATE TABLE t_order0 ( id BIGINT, order_no VARCHAR(30), user_id BIGINT, amount DECIMAL(10,2), PRIMARY KEY(id) ); CREATE TABLE t_order1 ( id BIGINT, order_no VARCHAR(30), user_id BIGINT, amount DECIMAL(10,2), PRIMARY KEY(id) ); 5.3、创建SpringBoot项目实现
5.3.1、引入maven
dependenciesdependencygroupIdcn.hutool/groupIdartifactIdhutool-all/artifactIdversion5.8.20/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.apache.shardingsphere/groupIdartifactIdshardingsphere-jdbc-core-spring-boot-starter/artifactIdversion5.1.1/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdscoperuntime/scope/dependencydependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.3.1/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scopeexclusionsexclusiongroupIdorg.junit.vintage/groupIdartifactIdjunit-vintage-engine/artifactId/exclusion/exclusions/dependency/dependencies
5.3.2、配置配置文件
总配置文件
server:port: 8886
spring:# 应用名称application:name: demoShardingSphere-JDBC-horizontal-fragmentation# 开发环境设置profiles:active: devshardingsphere:datasource:# 配置真实数据源names: server-user,server-order0,server-order1server-user:driver-class-name: com.mysql.jdbc.Driverjdbc-url: jdbc:mysql://47.97.68.78:3301/db_user?characterEncodingutf-8password: 123456type: com.zaxxer.hikari.HikariDataSourceusername: rootserver-order0:driver-class-name: com.mysql.jdbc.Driverjdbc-url: jdbc:mysql://47.97.68.78:3310/db_order?characterEncodingutf-8password: 123456type: com.zaxxer.hikari.HikariDataSourceusername: rootserver-order1:driver-class-name: com.mysql.jdbc.Driverjdbc-url: jdbc:mysql://47.97.68.78:3311/db_order?characterEncodingutf-8password: 123456type: com.zaxxer.hikari.HikariDataSourceusername: root# 内存模式mode:type: Memory# 打印SQl 在控制台查看日志输出可以知道此时是在哪个数据源进行操作。如Actual SQL: slave2props:sql-show: true# spring.shardingsphere.rules.sharding.tables.table-name.actual-data-nodes值# 值由数据源名 表名组成以小数点分隔。多个表以逗号分隔支持 inline 表达式。 server-order$-{0..1}.t_order$-{0..1}# table-name逻辑表名rules:sharding:tables:t_user:# actual-data-nodes: server-user.t_user_${0..1}actual-data-nodes: server-user.t_usert_order:
# actual-data-nodes: server-order0.t_order0,server-order0.t_order1,server-order1.t_order0,server-order1.t_order1actual-data-nodes: server-order$-{[0,1]}.t_order$-{[0,1]}
# actual-data-nodes: server-order$-{[0,1]}.t_order0# ---------------分库策略database-strategy:standard:# 分片列名称sharding-column: user_id# 分片算法名称sharding-algorithm-name: alg_inline_userid# ---------------分表策略table-strategy:standard:# 分片列名称sharding-column: order_no# 分片算法名称sharding-algorithm-name: alg_hash_mod#------------------------分布式序列策略配置key-generate-strategy:# 分布式序列列名称column: id# 分布式序列算法名称key-generator-name: alg_snowflaket_order_item:actual-data-nodes: server-order$-{[0,1]}.t_order_item$-{[0,1]}# ---------------分库策略database-strategy:standard:# 分片列名称sharding-column: user_id# 分片算法名称sharding-algorithm-name: alg_inline_userid# ---------------分表策略table-strategy:standard:# 分片列名称sharding-column: order_no# 分片算法名称sharding-algorithm-name: alg_hash_mod#------------------------分布式序列策略配置key-generate-strategy:# 分布式序列列名称column: id# 分布式序列算法名称key-generator-name: alg_snowflaket_dict:actual-data-nodes: server-user.t_dict,server-order$-{[0,1]}.t_dictsharding-algorithms:# 行表达式分片算法 alg_inline_userid 是取的对应的算法名称这里可自定义alg_inline_userid:# 分片算法类型type: INLINE# 分片算法属性配置props:algorithm-expression: server-order$-{user_id % 2}# 取模分片算法 alg_mod 是取的对应的算法名称这里可自定义alg_mod:# 分片算法类型type: MOD# 分片算法属性配置props:sharding-count: 2alg_hash_mod:type: HASH_MODprops:sharding-count: 2# 分布式序列算法配置key-generators:alg_snowflake:# 分布式序列算法类型type: SNOWFLAKE# 绑定表规则列表#使用绑定表进行多表关联查询时必须使用分片键(user_id,order_no)进行关联否则会出现笛卡尔积关联或跨库关联从而影响查询效率。binding-tables[0]: t_order,t_order_item# 广播表broadcast-tables[0]: t_dict分库配置
spring:shardingsphere:rules:sharding:#------------------------分片算法配置sharding-algorithms:alg_inline_userid:# 分片算法属性配置props:algorithm-expression: server-order$-{user_id % 2}# 分片算法类型type: INLINEalg_mod:# 分片算法属性配置props:sharding-count: 2# 分片算法类型type: MODtables:t_order:#------------------------分库策略database-strategy:standard:# 分片算法名称sharding-algorithm-name: alg_inline_userid# 分片列名称sharding-column: user_id分表配置
spring:shardingsphere:rules:sharding:#------------------------分片算法配置# 哈希取模分片算法sharding-algorithms:alg_hash_mod:# 分片算法属性配置props:sharding-count: 2# 分片算法类型type: HASH_MODtables:t_order:#------------------------分库策略table-strategy:standard:# 分片算法名称sharding-algorithm-name: alg_hash_mod# 分片列名称sharding-column: order_no
5.3.3、测试
【1】插入测试 /*** 水平分片分表插入数据测试*/Testpublic void testInsertOrderTableStrategy(){for (long i 100; i 104; i) {Order order new Order();order.setOrderNo(O i);order.setUserId(1L);order.setAmount(new BigDecimal(100));orderMapper.insert(order);}for (long i 105; i 109; i) {Order order new Order();order.setOrderNo(O i);order.setUserId(2L);order.setAmount(new BigDecimal(100));orderMapper.insert(order);}}
效果 【2】查询测试
/*** 水平分片查询所有记录* 查询了两个数据源每个数据源中使用UNION ALL连接两个表*/
Test
public void testShardingSelectAll(){ListOrder orders orderMapper.selectList(null);orders.forEach(System.out::println);
}/*** 水平分片根据user_id查询记录* 查询了一个数据源每个数据源中使用UNION ALL连接两个表*/
Test
public void testShardingSelectByUserId(){QueryWrapperOrder orderQueryWrapper new QueryWrapper();orderQueryWrapper.eq(user_id, 1L);ListOrder orders orderMapper.selectList(orderQueryWrapper);orders.forEach(System.out::println);
}
效果有一些我的老数据可忽略结果直接看sql
5.4、多表关联
5.4.1、创建关联表
在server-order0、server-order1服务器中分别创建两张订单详情表t_order_item0、t_order_item1
我们希望同一个用户的订单表和订单详情表中的数据都在同一个数据源中避免跨库关联因此这两张表我们使用相同的分片策略。
那么在t_order_item中我们也需要创建order_no和user_id这两个分片键 CREATE TABLE t_order_item0( id BIGINT, order_no VARCHAR(30), user_id BIGINT, price DECIMAL(10,2), count INT, PRIMARY KEY(id) ); CREATE TABLE t_order_item1( id BIGINT, order_no VARCHAR(30), user_id BIGINT, price DECIMAL(10,2), count INT, PRIMARY KEY(id) ); 5.4.2、创建实体类与Mapper
TableName(t_order_item)
Data
public class OrderItem {//当配置了shardingsphere-jdbc的分布式序列时自动使用shardingsphere-jdbc的分布式序列TableId(type IdType.AUTO)private Long id;private String orderNo;private Long userId;private BigDecimal price;private Integer count;
}
Mapper
public interface OrderItemMapper extends BaseMapperOrderItem {}
5.4.3、关联表相关配置
spring:shardingsphere:rules:sharding:tables:t_order_item:#------------------------标准分片表配置数据节点配置actual-data-nodes: server-order$-{0..1}.t_order_item$-{0..1}#------------------------分库策略database-strategy:standard:# 分片算法名称sharding-algorithm-name: alg_mod# 分片列名称sharding-column: user_id#------------------------分布式序列策略配置key-generate-strategy:# 分布式序列列名称column: id# 分布式序列算法名称key-generator-name: alg_snowflake#------------------------分表策略table-strategy:standard:# 分片算法名称sharding-algorithm-name: alg_hash_mod# 分片列名称sharding-column: order_no5.4.4、测试
【1】插入测试
/*** 测试关联表插入*/Testpublic void testInsertOrderAndOrderItem(){for (long i 1; i 3; i) {Order order new Order();String orderNo O i;order.setOrderNo(orderNo);order.setUserId(1L);orderMapper.insert(order);for (long j 1; j 3; j) {OrderItem orderItem new OrderItem();orderItem.setOrderNo(orderNo);orderItem.setUserId(1L);orderItem.setPrice(new BigDecimal(10));orderItem.setCount(2);orderItemMapper.insert(orderItem);}}for (long i 5; i 7; i) {Order order new Order();String orderNo O i;order.setOrderNo(orderNo);order.setUserId(2L);orderMapper.insert(order);for (long j 1; j 3; j) {OrderItem orderItem new OrderItem();orderItem.setOrderNo(orderNo);orderItem.setUserId(2L);orderItem.setPrice(new BigDecimal(1));orderItem.setCount(3);orderItemMapper.insert(orderItem);}}}
【2】查询测试
Data
public class OrderVo {private String orderNo;private BigDecimal amount;
}/*** 测试关联表查询*/Testpublic void testGetOrderAmount(){ListOrderVo orderAmountList orderMapper.getOrderAmount();orderAmountList.forEach(System.out::println);}
select idgetOrderAmount resultTypecom.lkx.horizontalfragmentation.entity.OrderVoSELECT o.order_no, SUM(i.price * i.count) AS amountFROM t_order o JOIN t_order_item i ON o.order_no i.order_noGROUP BY o.order_no/select
5.5、配置绑定表
配置
spring:shardingsphere:rules:sharding:binding-tables[0]: t_order,t_order_item
配置完绑定表后再次进行关联查询的测试 如果不配置绑定表测试的结果为8个SQL。多表关联查询会出现笛卡尔积关联。 如果配置绑定表测试的结果为4个SQL。 多表关联查询不会出现笛卡尔积关联关联查询效率将大大提升。
绑定表指分片规则一致的一组分片表。 使用绑定表进行多表关联查询时必须使用分片键进行关联否则会出现笛卡尔积关联或跨库关联从而影响查询效率。
六、ShardingSphere-Proxy