diff --git a/README.md b/README.md index 542ffc9a0be004eb16bcc11558a5aa298da27a74..399a4ae4765edfa76980521f7a43ed9cf92bb712 100644 --- a/README.md +++ b/README.md @@ -1 +1,62 @@ -# 还在持续开发中,后期补上文档 +# Redisson实现分布式锁 + +有关ShardingSphere实现分库分表前面写了7篇博客作为该项目做详细说明。 + + 1、[分库分表(1) --- 理论](https://www.cnblogs.com/qdhxhz/p/11608222.html) + + 2、[分库分表(2) --- ShardingSphere(理论)](https://www.cnblogs.com/qdhxhz/p/11629883.html) + + 3、[分库分表(3) ---SpringBoot + ShardingSphere实现读写分离](https://www.cnblogs.com/qdhxhz/p/11656205.html) + + 4、[分库分表(4) ---SpringBoot + ShardingSphere 实现分表](https://www.cnblogs.com/qdhxhz/p/11651163.html) + + 5、[分库分表(5) ---SpringBoot + ShardingSphere 实现分库分表](https://www.cnblogs.com/qdhxhz/p/11673493.html) + + 6、[分库分表(6)--- SpringBoot+ShardingSphere实现分表+ 读写分离](https://www.cnblogs.com/qdhxhz/p/11688651.html) + + 7、[分库分表(7)--- SpringBoot+ShardingSphere实现分库分表 + 读写分离](https://www.cnblogs.com/qdhxhz/p/11688371.html) + +该项目拉下后配置数据库地址,和创建相应的库和表后就可以运行成功。 + + +## 一、项目概述 + + +#### 1、技术架构 + +项目总体技术选型 + +``` +SpringBoot2.0.6 + shardingsphere4.0.0-RC1 + Maven3.5.4 + MySQL + lombok(插件) +``` + +#### 2、项目说明 + +`场景` 在实际开发中,如果数据库压力大我们可以通过 **分库分表** 的基础上进行 **读写分离**,来减缓数据库压力。 + +#### 3、项目整体结构 + +```makefile +spring-boot-sharding-ssphere # 父工程 + + | #实现读写分离功能 + ---db-read-write + + | #实现分表功能 + ---sub-table + + | #实现分库分表功能 + ---sub-db-table + + | #实现分表 + 读写分离 + ---sub-table-read-write + + | #实现分库分表 + 读写分离 + ---sub-db-table-read-write + +``` + +
+ + + diff --git a/db-read-write/README.md b/db-read-write/README.md new file mode 100644 index 0000000000000000000000000000000000000000..53bfef2b8d674e56927d7de60c566b0e32448f02 --- /dev/null +++ b/db-read-write/README.md @@ -0,0 +1,174 @@ + +## 一、项目概述 + +#### 1、技术架构 + +项目总体技术选型 + +``` +SpringBoot2.0.6 + shardingsphere4.0.0-RC1 + Maven3.5.4 + MySQL + lombok(插件) +``` + +#### 2、项目说明 + +`场景` 如果实际项目中Mysql是 **Master-Slave** (主从)部署的,那么数据保存到Master库,Master库数据同步数据到Slave库,数据读取到Slave库, + +这样可以减缓数据库的压力。 + +#### 3、数据库设计 + +我们这个项目中Mysql服务器并没有实现主从部署,而是同一个服务器建立两个库,一个当做Master库,一个当做Slave库。所以这里是不能实现的功能就是Master库 + +新增数据主动同步到Slave库。这样也更有利于我们测试看效果。 + +`Master库` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191009185338624-1852756872.jpg) + +`Slave库` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191009185349432-1461519408.jpg) + +从两幅图中可以看出,我这里在同一个服务器建两个数据库来模拟主从数据库。为了方便看测试效果,这里`主从数据库中的数据是不一样的`。 + +
+ +## 二、核心代码 + +`说明` 完整的代码会放到GitHub上,这里只放一些核心代码。 + +#### 1、pom.xml + +```xml + + 1.8 + 2.0.1 + 1.1.16 + UTF-8 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + ${mybatis-spring-boot} + + + + mysql + mysql-connector-java + + + + com.alibaba + druid-spring-boot-starter + ${druid} + + + + org.apache.shardingsphere + sharding-jdbc-spring-boot-starter + 4.0.0-RC1 + + + + org.projectlombok + lombok + + +``` + +#### 2、application.properties + +```properties +server.port=8088 +#指定mybatis信息 +mybatis.config-location=classpath:mybatis-config.xml + +spring.shardingsphere.datasource.names=master,slave0 +# 数据源 主库 +spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource +spring.shardingsphere.datasource.master.driver-class-name=com.mysql.jdbc.Driver +spring.shardingsphere.datasource.master.url=jdbc:mysql://localhost:3306/master?characterEncoding=utf-8 +spring.shardingsphere.datasource.master.username=root +spring.shardingsphere.datasource.master.password=123456 +# 数据源 从库 +spring.shardingsphere.datasource.slave0.type=com.alibaba.druid.pool.DruidDataSource +spring.shardingsphere.datasource.slave0.driver-class-name=com.mysql.jdbc.Driver +spring.shardingsphere.datasource.slave0.url=jdbc:mysql://localhost:3306/slave?characterEncoding=utf-8 +spring.shardingsphere.datasource.slave0.username=root +spring.shardingsphere.datasource.slave0.password=123456 + +# 读写分离 +spring.shardingsphere.masterslave.load-balance-algorithm-type=round_robin +spring.shardingsphere.masterslave.name=ms +spring.shardingsphere.masterslave.master-data-source-name=master +spring.shardingsphere.masterslave.slave-data-source-names=slave0 +#打印sql +spring.shardingsphere.props.sql.show=true + +``` + +Sharding-JDBC可以通过`Java`,`YAML`,`Spring命名空间`和`Spring Boot Starter`四种方式配置,开发者可根据场景选择适合的配置方式。具体可以看官网。 + +#### 3、UserController + +```java +@RestController +public class UserController { + + @Autowired + private UserService userService; + /** + * @Description: 保存用户 + */ + @PostMapping("save-user") + public Object saveUser() { + return userService.saveOne(new User("小小", "女", 3)); + } + /** + * @Description: 获取用户列表 + */ + @GetMapping("list-user") + public Object listUser() { + return userService.list(); + } +} +``` + +
+ +## 三、测试验证 + +#### 1、读数据 + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191009185402278-1091601392.png) + +我们可以发现读取的数据是Slave库的数据。我们再来看控制台打印的SQL。可以看到读操作是Slave库。 + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191009185411133-1376483500.png) + +#### 2、写数据 + +`请求` + +``` +localhost:8088/save-user?name=小小&sex=女&age=3 +``` + +**查看Mater数据库** + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191009185420244-1105231293.png) + +发现Master数据库已经多了一条数据了,再看控制台打印的SQL。 + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191009185429389-1675126607.png) + +这个时候如果去看Slave库的话这条新增的数据是没有的,因为没有同步过去。 + + +
\ No newline at end of file diff --git a/sub-db-table-read-write/README.md b/sub-db-table-read-write/README.md new file mode 100644 index 0000000000000000000000000000000000000000..fcba2b85de51ee923b82c42c07ba029630345d7b --- /dev/null +++ b/sub-db-table-read-write/README.md @@ -0,0 +1,209 @@ +## 一、项目概述 + +#### 1、技术架构 + +项目总体技术选型 + +``` +SpringBoot2.0.6 + shardingsphere4.0.0-RC1 + Maven3.5.4 + MySQL + lombok(插件) +``` + +#### 2、项目说明 + +`场景` 在实际开发中,如果数据库压力大我们可以通过 **分库分表** 的基础上进行 **读写分离**,来减缓数据库压力。 + +#### 3、数据库设计 + +`分库` ms单库分库分为 ms0库 和 ms1库。 + +`分表` tab_user单表分为tab_user0表 和 tab_user1表。 + +`读写分离` 数据写入ms0库 和 ms1库,数据读取 sl0库 和 sl1库。 + +**如图** + +`ms0 ---主库` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191016204615168-856573739.png) + +`ms1 ---主库` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191016204625922-1762015926.png) + +`sl0 ---从库` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191016204638625-407970469.png) + +`sl1 ---从库` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191016204648399-387199295.png) + + +`说明` 初始数据的时候,这边只有 **sl0从库** 我插入了一条数据。那是因为我们这个项目中Mysql服务器并没有实现主从部署,这四个库都在同一服务器上,所以 + +做不到主数据库数据自动同步到从数据库。所以这里在从数据库建一条数据。等下验证的时候,我们只需验证数据是否存入`ms0`和`ms1`,数据读取是否在`sl0`和`sl1`。 + +具体的创建表SQL也会放到GitHub项目里 + +
+ +## 二、核心代码 + +`说明` 完整的代码会放到GitHub上,这里只放一些核心代码。 + +#### 1、application.properties + +```properties +server.port=8082 + +#指定mybatis信息 +mybatis.config-location=classpath:mybatis-config.xml +#打印sql +spring.shardingsphere.props.sql.show=true +#数据源 +spring.shardingsphere.datasource.names=master0,slave0,master1,slave1 + +spring.shardingsphere.datasource.master0.type=com.alibaba.druid.pool.DruidDataSource +spring.shardingsphere.datasource.master0.driver-class-name=com.mysql.jdbc.Driver +spring.shardingsphere.datasource.master0.url=jdbc:mysql://localhost:3306/ms0?characterEncoding=utf-8 +spring.shardingsphere.datasource.master0.username=root +spring.shardingsphere.datasource.master0.password=root + +spring.shardingsphere.datasource.slave0.type=com.alibaba.druid.pool.DruidDataSource +spring.shardingsphere.datasource.slave0.driver-class-name=com.mysql.jdbc.Driver +spring.shardingsphere.datasource.slave0.url=jdbc:mysql://localhost:3306/sl0?characterEncoding=utf-8 +spring.shardingsphere.datasource.slave0.username=root +spring.shardingsphere.datasource.slave0.password=root + +spring.shardingsphere.datasource.master1.type=com.alibaba.druid.pool.DruidDataSource +spring.shardingsphere.datasource.master1.driver-class-name=com.mysql.jdbc.Driver +spring.shardingsphere.datasource.master1.url=jdbc:mysql://localhost:3306/ms1?characterEncoding=utf-8 +spring.shardingsphere.datasource.master1.username=root +spring.shardingsphere.datasource.master1.password=root + +spring.shardingsphere.datasource.slave1.type=com.alibaba.druid.pool.DruidDataSource +spring.shardingsphere.datasource.slave1.driver-class-name=com.mysql.jdbc.Driver +spring.shardingsphere.datasource.slave1.url=jdbc:mysql://localhost:3306/slave1?characterEncoding=utf-8 +spring.shardingsphere.datasource.slave1.username=root +spring.shardingsphere.datasource.slave1.password=root + +#根据年龄分库 +spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=age +spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=master$->{age % 2} +#根据id分表 +spring.shardingsphere.sharding.tables.tab_user.actual-data-nodes=master$->{0..1}.tab_user$->{0..1} +spring.shardingsphere.sharding.tables.tab_user.table-strategy.inline.sharding-column=id +spring.shardingsphere.sharding.tables.tab_user.table-strategy.inline.algorithm-expression=tab_user$->{id % 2} + +#指定master0为主库,slave0为它的从库 +spring.shardingsphere.sharding.master-slave-rules.master0.master-data-source-name=master0 +spring.shardingsphere.sharding.master-slave-rules.master0.slave-data-source-names=slave0 +#指定master1为主库,slave1为它的从库 +spring.shardingsphere.sharding.master-slave-rules.master1.master-data-source-name=master1 +spring.shardingsphere.sharding.master-slave-rules.master1.slave-data-source-names=slave1 +``` + +Sharding-JDBC可以通过`Java`,`YAML`,`Spring命名空间`和`Spring Boot Starter`四种方式配置,开发者可根据场景选择适合的配置方式。具体可以看官网。 + +#### 2、UserController + +```java +@RestController +public class UserController { + + @Autowired + private UserService userService; + + /** + * 模拟插入数据 + */ + List userList = Lists.newArrayList(); + /** + * 初始化插入数据 + */ + @PostConstruct + private void getData() { + userList.add(new User(1L,"小小", "女", 3)); + userList.add(new User(2L,"爸爸", "男", 30)); + userList.add(new User(3L,"妈妈", "女", 28)); + userList.add(new User(4L,"爷爷", "男", 64)); + userList.add(new User(5L,"奶奶", "女", 62)); + } + /** + * @Description: 批量保存用户 + */ + @PostMapping("save-user") + public Object saveUser() { + return userService.insertForeach(userList); + } + /** + * @Description: 获取用户列表 + */ + @GetMapping("list-user") + public Object listUser() { + return userService.list(); + } +``` + +
+ +## 三、测试验证 + +#### 1、批量插入数据 + +请求接口 + +``` +localhost:8082/save-user +``` + +我们可以从商品接口代码中可以看出,它会批量插入5条数据。我们先看控制台输出SQL语句 + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191016204701100-420602843.png) + + + +我们可以从SQL语句可以看出 **master0** 和 **master1** 库中都插入了数据。 + +我们再来看数据库 + +`ms0.tab_user0` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191016204709927-109585642.png) + + +`ms0.tab_user1` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191016204720312-155045671.png) + + +`ms1.tab_user0` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191016204731838-247434033.png) + +`ms1.tab_user1` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191016204740482-27142599.png) + +完成分库分表插入数据。 + +#### 2、获取数据 + +这里获取列表接口的SQL。 + +```mysql + select * from tab_user +``` + +请求接口结果 + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191016204752338-1011637895.png) + + + +`结论` 从接口返回的结果可以很明显的看出,数据存储在主库,而数据库的读取在从库。 + +`注意` ShardingSphere并不支持`CASE WHEN`、`HAVING`、`UNION (ALL)`,`有限支持子查询`。这个官网有详细说明。 + + +
\ No newline at end of file diff --git a/sub-db-table-read-write/src/main/resources/application.properties b/sub-db-table-read-write/src/main/resources/application.properties index 737fd6278b61a7f30f1c7be81f1d854c22c93d1d..228b2d755380dbf6ceeebf6aa1fce4517898890d 100644 --- a/sub-db-table-read-write/src/main/resources/application.properties +++ b/sub-db-table-read-write/src/main/resources/application.properties @@ -1,5 +1,4 @@ -server.port=8082 - +server.port=8088 #指定mybatis信息 mybatis.config-location=classpath:mybatis-config.xml #打印sql diff --git a/sub-db-table/README.md b/sub-db-table/README.md new file mode 100644 index 0000000000000000000000000000000000000000..4e91f92a53fa177514bd282303f1ab1d98ea0327 --- /dev/null +++ b/sub-db-table/README.md @@ -0,0 +1,170 @@ +## 一、项目概述 + +#### 1、技术架构 + +项目总体技术选型 + +``` +SpringBoot2.0.6 + shardingsphere4.0.0-RC1 + Maven3.5.4 + MySQL + lombok(插件) +``` + +#### 2、项目说明 + +`场景` 在实际开发中,如果表的数据过大我们需要把一张表拆分成多张表,也可以垂直切分把一个库拆分成多个库,这里就是通过ShardingSphere实现`分库分表`功能。 + +#### 3、数据库设计 + +`分库` ds一个库分为 **ds0库** 和 **ds1库**。 + +`分表` tab_user一张表分为**tab_user0表** 和 **tab_user1表**。 + +**如图** + +`ds0库` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191014193639269-230175212.jpg) + +`ds1库` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191014193649751-736195635.jpg) + +具体的创建表SQL也会放到GitHub项目里 + +
+ +## 二、核心代码 + +`说明` 完整的代码会放到GitHub上,这里只放一些核心代码。 + +#### 1、application.properties + +```properties +server.port=8084 + +#指定mybatis信息 +mybatis.config-location=classpath:mybatis-config.xml +#打印sql +spring.shardingsphere.props.sql.show=true + +spring.shardingsphere.datasource.names=ds0,ds1 + +spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource +spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver +spring.shardingsphere.datasource.ds0.url=jdbc:mysql://localhost:3306/ds0?characterEncoding=utf-8 +spring.shardingsphere.datasource.ds0.username=root +spring.shardingsphere.datasource.ds0.password=root + +spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource +spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver +spring.shardingsphere.datasource.ds1.url=jdbc:mysql://localhost:3306/ds1?characterEncoding=utf-8 +spring.shardingsphere.datasource.ds1.username=root +spring.shardingsphere.datasource.ds1.password=root + +#根据年龄分库 +spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=age +spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=ds$->{age % 2} +#根据id分表 +spring.shardingsphere.sharding.tables.tab_user.actual-data-nodes=ds$->{0..1}.tab_user$->{0..1} +spring.shardingsphere.sharding.tables.tab_user.table-strategy.inline.sharding-column=id +spring.shardingsphere.sharding.tables.tab_user.table-strategy.inline.algorithm-expression=tab_user$->{id % 2} +``` + +Sharding-JDBC可以通过`Java`,`YAML`,`Spring命名空间`和`Spring Boot Starter`四种方式配置,开发者可根据场景选择适合的配置方式。具体可以看官网。 + +#### 2、UserController + +```java +@RestController +public class UserController { + + @Autowired + private UserService userService; + + /** + * 模拟插入数据 + */ + List userList = Lists.newArrayList(); + /** + * 初始化插入数据 + */ + @PostConstruct + private void getData() { + userList.add(new User(1L,"小小", "女", 3)); + userList.add(new User(2L,"爸爸", "男", 30)); + userList.add(new User(3L,"妈妈", "女", 28)); + userList.add(new User(4L,"爷爷", "男", 64)); + userList.add(new User(5L,"奶奶", "女", 62)); + } + /** + * @Description: 批量保存用户 + */ + @PostMapping("save-user") + public Object saveUser() { + return userService.insertForeach(userList); + } + /** + * @Description: 获取用户列表 + */ + @GetMapping("list-user") + public Object listUser() { + return userService.list(); + } +``` + +
+ +## 三、测试验证 + +#### 1、批量插入数据 + +请求接口 + +``` +localhost:8084/save-user +``` + +我们可以从商品接口代码中可以看出,它会批量插入5条数据。我们先看控制台输出SQL语句 + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191014193958255-984204288.jpg) + + +我们可以从SQL语句可以看出 **ds0** 和 **ds1** 库中都插入了数据。 + +我们再来看数据库 + +`ds0.tab_user0` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191014194112856-1815322205.jpg) + +`ds0.tab_user1` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191014194536294-534144947.jpg) + +`ds1.tab_user0` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191014194544830-1729440572.jpg) + +`ds1.tab_user1` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191014194553598-572433744.jpg) + +完成分库分表插入数据。 + +#### 2、获取数据 + +这里获取列表接口的SQL,这里对SQL做了order排序操作,具体ShardingSphere分表实现order操作的原理可以看上面一篇博客。 + +```mysql + select * from tab_user order by age +``` + +请求接口结果 + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191014194611502-1843756299.png) + +我们可以看出虽然已经分库分表,但依然可以将多表数据聚合在一起并可以支持按**age排序**。 + +`注意` ShardingSphere并不支持`CASE WHEN`、`HAVING`、`UNION (ALL)`,`有限支持子查询`。这个官网有详细说明。 + + +
\ No newline at end of file diff --git a/sub-table-read-write/README.md b/sub-table-read-write/README.md new file mode 100644 index 0000000000000000000000000000000000000000..7991621f8c474663ddd788a437c4eecf0e7ff06e --- /dev/null +++ b/sub-table-read-write/README.md @@ -0,0 +1,182 @@ +## 一、项目概述 + +#### 1、技术架构 + +项目总体技术选型 + +``` +SpringBoot2.0.6 + shardingsphere4.0.0-RC1 + Maven3.5.4 + MySQL + lombok(插件) +``` + +#### 2、项目说明 + +`场景` 在实际开发中,如果表的数据过大,我们可能需要把一张表拆分成多张表,这里就是通过ShardingSphere实现分表+读写分离功能,但不分库。 + +#### 3、数据库设计 + +`分表` tab_user单表拆分为tab_user0表 和 tab_user1表。 + +`读写分离` 数据写入master库 ,数据读取 slave库 。 + +**如图** + +`master库` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191016213947793-556434384.png) + +`slave库` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191016213957809-1645338573.png) + + +`说明` 初始数据的时候,这边只有 **slave从库的tab_user0** 我插入了一条数据。那是因为我们这个项目中Mysql服务器并没有实现主从部署,这两个库都在同一服务器上,所以 + +做不到主数据库数据自动同步到从数据库。所以这里在从数据库建一条数据。等下验证的时候,我们只需验证数据是否存入`master库`,数据读取是否在`slave库`。 + +具体的创建表SQL也会放到GitHub项目里 + +
+ +## 二、核心代码 + +`说明` 完整的代码会放到GitHub上,这里只放一些核心代码。 + +#### 1、application.properties + +```properties +server.port=8084 + +#指定mybatis信息 +mybatis.config-location=classpath:mybatis-config.xml + +#数据库 +spring.shardingsphere.datasource.names=master0,slave0 + +spring.shardingsphere.datasource.master0.type=com.alibaba.druid.pool.DruidDataSource +spring.shardingsphere.datasource.master0.driver-class-name=com.mysql.jdbc.Driver +spring.shardingsphere.datasource.master0.url=jdbc:mysql://localhost:3306/master?characterEncoding=utf-8 +spring.shardingsphere.datasource.master0.username=root +spring.shardingsphere.datasource.master0.password=123456 + +spring.shardingsphere.datasource.slave0.type=com.alibaba.druid.pool.DruidDataSource +spring.shardingsphere.datasource.slave0.driver-class-name=com.mysql.jdbc.Driver +spring.shardingsphere.datasource.slave0.url=jdbc:mysql://localhost:3306/slave?characterEncoding=utf-8 +spring.shardingsphere.datasource.slave0.username=root +spring.shardingsphere.datasource.slave0.password=root + +#数据分表规则 +#指定所需分的表 +spring.shardingsphere.sharding.tables.tab_user.actual-data-nodes=master0.tab_user$->{0..1} +#指定主键 +spring.shardingsphere.sharding.tables.tab_user.table-strategy.inline.sharding-column=id +#分表规则为主键除以2取模 +spring.shardingsphere.sharding.tables.tab_user.table-strategy.inline.algorithm-expression=tab_user$->{id % 2} + +# 读写分离 +spring.shardingsphere.masterslave.load-balance-algorithm-type=round_robin +spring.shardingsphere.masterslave.name=ms +#这里配置读写分离的时候一定要记得添加主库的数据源名称 这里为master0 +spring.shardingsphere.sharding.master-slave-rules.master0.master-data-source-name=master0 +spring.shardingsphere.sharding.master-slave-rules.master0.slave-data-source-names=slave0 + +#打印sql +spring.shardingsphere.props.sql.show=true +``` + +Sharding-JDBC可以通过`Java`,`YAML`,`Spring命名空间`和`Spring Boot Starter`四种方式配置,开发者可根据场景选择适合的配置方式。具体可以看官网。 + +#### 2、UserController + +```java +@RestController +public class UserController { + + @Autowired + private UserService userService; + + /** + * 模拟插入数据 + */ + List userList = Lists.newArrayList(); + /** + * 初始化插入数据 + */ + @PostConstruct + private void getData() { + userList.add(new User(1L,"小小", "女", 3)); + userList.add(new User(2L,"爸爸", "男", 30)); + userList.add(new User(3L,"妈妈", "女", 28)); + userList.add(new User(4L,"爷爷", "男", 64)); + userList.add(new User(5L,"奶奶", "女", 62)); + } + /** + * @Description: 批量保存用户 + */ + @PostMapping("save-user") + public Object saveUser() { + return userService.insertForeach(userList); + } + /** + * @Description: 获取用户列表 + */ + @GetMapping("list-user") + public Object listUser() { + return userService.list(); + } +``` + +
+ +## 三、测试验证 + +#### 1、批量插入数据 + +请求接口 + +``` +localhost:8084/save-user +``` + +我们可以从商品接口代码中可以看出,它会批量插入5条数据。我们先看控制台输出SQL语句 + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191016214013613-520082614.png) + + + +我们可以从SQL语句可以看出 **master0数据源** 中 **tab_user0** 表插入了`三条数据`,而 **tab_user1** 表中插入`两条数据`。 + +我们再来看数据库 + +`master.tab_user0` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191016214021616-2037678416.png) + + + +`master.tab_user1` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191016214028932-1050325570.png) + + + + + +完成分表插入数据。 + +#### 2、获取数据 + +我们来获取列表接口的SQL。 + +```mysql + select * from tab_user +``` + +请求接口结果 + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191016214037389-922151476.png) + +`结论` 从接口返回的结果可以很明显的看出,数据存储在master主库,而数据库的读取在slave从库。 + +`注意` ShardingSphere并不支持`CASE WHEN`、`HAVING`、`UNION (ALL)`,`有限支持子查询`。这个官网有详细说明。 + +
\ No newline at end of file diff --git a/sub-table/README.md b/sub-table/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c189c0edd98412b3c07298f12b6a75454c4f9c97 --- /dev/null +++ b/sub-table/README.md @@ -0,0 +1,158 @@ + +## 一、项目概述 + +#### 1、技术架构 + +项目总体技术选型 + +``` +SpringBoot2.0.6 + shardingsphere4.0.0-RC1 + Maven3.5.4 + MySQL + lombok(插件) +``` + +#### 2、项目说明 + +`场景` 在实际开发中,如果表的数据过大,我们可能需要把一张表拆分成多张表,这里就是通过ShardingSphere实现分表功能,但不分库。 + +#### 3、数据库设计 + +这里有个member库,里面的`tab_user`表由一张拆分成3张,分别是`tab_user0`、`tab_user1`、`tab_user2`。 + +**如图** + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191011190937605-1357123570.png) + +具体的创建表SQL也会放到GitHub项目里 + +
+ +## 二、核心代码 + +`说明` 完整的代码会放到GitHub上,这里只放一些核心代码。 + +#### 1、application.properties + +```properties +server.port=8086 + +#指定mybatis信息 +mybatis.config-location=classpath:mybatis-config.xml + +spring.shardingsphere.datasource.names=master + +# 数据源 主库 +spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource +spring.shardingsphere.datasource.master.driver-class-name=com.mysql.jdbc.Driver +spring.shardingsphere.datasource.master.url=jdbc:mysql://localhost:3306/member?characterEncoding=utf-8 +spring.shardingsphere.datasource.master.username=root +spring.shardingsphere.datasource.master.password=123456 + +#数据分表规则 +#指定所需分的表 +spring.shardingsphere.sharding.tables.tab_user.actual-data-nodes=master.tab_user$->{0..2} +#指定主键 +spring.shardingsphere.sharding.tables.tab_user.table-strategy.inline.sharding-column=id +#分表规则为主键除以3取模 +spring.shardingsphere.sharding.tables.tab_user.table-strategy.inline.algorithm-expression=tab_user$->{id % 3} + +#打印sql +spring.shardingsphere.props.sql.show=true + + +``` + +Sharding-JDBC可以通过`Java`,`YAML`,`Spring命名空间`和`Spring Boot Starter`四种方式配置,开发者可根据场景选择适合的配置方式。具体可以看官网。 + +#### 2、UserController + +```java +@RestController +public class UserController { + + @Autowired + private UserService userService; + + /** + * 模拟插入数据 + */ + List userList = Lists.newArrayList(); + /** + * 初始化插入数据 + */ + @PostConstruct + private void getData() { + userList.add(new User(1L,"小小", "女", 3)); + userList.add(new User(2L,"爸爸", "男", 30)); + userList.add(new User(3L,"妈妈", "女", 28)); + userList.add(new User(4L,"爷爷", "男", 64)); + userList.add(new User(5L,"奶奶", "女", 62)); + } + /** + * @Description: 批量保存用户 + */ + @PostMapping("save-user") + public Object saveUser() { + return userService.insertForeach(userList); + } + /** + * @Description: 获取用户列表 + */ + @GetMapping("list-user") + public Object listUser() { + return userService.list(); + } +``` + +
+ +## 三、测试验证 + +#### 1、批量插入数据 + +请求接口 + +``` +localhost:8086/save-user +``` + +我们可以从商品接口代码中可以看出,它会批量插入5条数据。我们先看控制台输出SQL语句 + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191011190953489-147927942.jpg) + + + +我们可以从SQL语句可以看出 **tab_user1** 和 **tab_user2** 表插入了`两条数据`,而 **tab_user0** 表中插入`一条数据`。 + +我们再来看数据库 + +`tab_user0` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191011191003991-863659850.jpg) + +`tab_user1` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191011191015624-277025558.jpg) + +`tab_user2` + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191011191024993-963489468.jpg) + +完成分表插入数据。 + +#### 2、获取数据 + +我们来获取列表的SQL,这里对SQL做了order排序操作,具体ShardingSphere分表实现order操作的原理可以看上面一篇博客。 + +```mysql + select * from tab_user order by id +``` + +请求接口结果 + +![](https://img2018.cnblogs.com/blog/1090617/201910/1090617-20191011191043297-1315264145.jpg) + +我们可以看出虽然已经分表,但依然可以将多表数据聚合在一起并可以排序。 + +`注意` ShardingSphere并不支持`CASE WHEN`、`HAVING`、`UNION (ALL)`,`有限支持子查询`。这个官网有详细说明。 + + +
\ No newline at end of file