当数据量比较大的时候,比如单个表的数据量超过了1000W的数据,这时可以考虑将数据存储在不同的表中,比如将user表拆分为四个表user_0、user_1、 user_2、user_3装在四个表中。此时如图所示:
数据库类型 | 数据库 | ip |
---|---|---|
主 | readwrite | 192.168.39.129 |
从 | readwrite | 192.168.39.130 |
从 | readwrite | 192.168.39.131 |
在主库初始化Mysql数据的脚本,初始化完后,从库也会创建这些表
DROP TABLE IF EXISTS `user_0`;
CREATE TABLE `user_0` (
`id` int(12) NOT NULL AUTO_INCREMENT,
`username` varchar(12) NOT NULL,
`password` varchar(30) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx-username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Table structure for table `user_1` */
DROP TABLE IF EXISTS `user_1`;
CREATE TABLE `user_1` (
`id` int(12) NOT NULL AUTO_INCREMENT,
`username` varchar(12) NOT NULL,
`password` varchar(30) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx-username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=150 DEFAULT CHARSET=utf8;
/*Table structure for table `user_2` */
DROP TABLE IF EXISTS `user_2`;
CREATE TABLE `user_2` (
`id` int(12) NOT NULL AUTO_INCREMENT,
`username` varchar(12) NOT NULL,
`password` varchar(30) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx-username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Table structure for table `user_3` */
DROP TABLE IF EXISTS `user_3`;
CREATE TABLE `user_3` (
`id` int(12) NOT NULL AUTO_INCREMENT,
`username` varchar(12) NOT NULL,
`password` varchar(30) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx-username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
pom文件
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.3.2.RELEASE
com.hzau
sharding-demo
0.0.1-SNAPSHOT
sharding-demo
Demo project for Spring Boot
1.8
org.springframework.boot
spring-boot-starter-web
com.baomidou
mybatis-plus-boot-starter
3.3.2
com.baomidou
mybatis-plus-generator
3.3.2
org.springframework.boot
spring-boot-starter-freemarker
mysql
mysql-connector-java
runtime
com.github.pagehelper
pagehelper-spring-boot-starter
1.2.13
org.projectlombok
lombok
true
com.alibaba
druid-spring-boot-starter
1.1.23
io.shardingsphere
sharding-jdbc-spring-boot-starter
3.1.0
org.springframework.boot
spring-boot-starter-test
test
org.junit.vintage
junit-vintage-engine
org.springframework.boot
spring-boot-maven-plugin
配置文件
sharding:
jdbc:
dataSource:
names: db-test0,db-test1,db-test2
# 配置主库
db-test0: #org.apache.tomcat.jdbc.pool.DataSource
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.39.129:3306/readwrite?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
username: root
password: root
#最大连接数
maxPoolSize: 20
db-test1: # 配置第一个从库
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.39.130:3306/readwrite?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT
username: root
password: root
maxPoolSize: 20
db-test2: # 配置第二个从库
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.39.131:3306/readwrite?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT
username: root
password: root
maxPoolSize: 20
props:
sql: # 开启SQL显示,默认值: false,注意:仅配置读写分离时不会打印日志!!!
show: true
sharding.jdbc.config.sharding.tables.user.actual-data-nodes: ds_0.user_$->{0..3}
sharding.jdbc.config.sharding.tables.user.table-strategy.standard.sharding-column: id
sharding.jdbc.config.sharding.tables.user.table-strategy.standard.precise-algorithm-class-name: com.hzau.shardingdemo.config.MyPreciseShardingAlgorithm
sharding.jdbc.config.sharding.master-slave-rules.ds_0.master-data-source-name: db-test0
sharding.jdbc.config.sharding.master-slave-rules.ds_0.slave-data-source-names: db-test1,db-test2
mybatis-plus:
datasource: dataSource
mapper-locations: classpath:/mapper/*Mapper.xml
#别名扫描
typeAliasesPackage: com.hzau.*.entity
spring:
main:
allow-bean-definition-overriding: true
druid监控配置
package com.hzau.shardingdemo.config;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @ClassName DruidDBConfig
* @Description TODO
* @Author yueyiming
* @Date 2020/7/27 16:05
* @Version 1.0
* https://blog.csdn.net/hzau_itdog
**/
@Configuration
public class DruidDBConfig {
@Bean
public ServletRegistrationBean druidServlet() {
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
// IP白名单
// servletRegistrationBean.addInitParameter("allow", "192.168.2.25,127.0.0.1");
// IP黑名单(共同存在时,deny优先于allow)
//servletRegistrationBean.addInitParameter("deny", "192.168.1.100");
//控制台管理用户
servletRegistrationBean.addInitParameter("loginUsername", "admin");
servletRegistrationBean.addInitParameter("loginPassword", "9527");
//是否能够重置数据 禁用HTML页面上的“Reset All”功能
servletRegistrationBean.addInitParameter("resetEnable", "false");
return servletRegistrationBean;
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return filterRegistrationBean;
}
}
MyPreciseShardingAlgorithm
根据id获取表名
package com.hzau.shardingdemo.config;
import io.shardingsphere.api.algorithm.sharding.PreciseShardingValue;
import io.shardingsphere.api.algorithm.sharding.standard.PreciseShardingAlgorithm;
import java.util.Collection;
/**
* @ClassName MyPreciseShardingAlgorithm
* @Description TODO
* @Author yueyiming
* @Date 2020/7/28 14:00
* @Version 1.0
* https://blog.csdn.net/hzau_itdog
**/
public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm {
@Override
public String doSharding(Collection availableTargetNames, PreciseShardingValue shardingValue) {
for (String tableName : availableTargetNames) {
if (tableName.endsWith(shardingValue.getValue() % 4 + "")) {
return tableName;
}
}
return null;
}
}
启动类上配置mapper扫描包
@SpringBootApplication
@MapperScan({"com.hzau.*.dao","com.hzau.*.mapper"})
public class ShardingDemoApplication {
public static void main(String[] args) {
SpringApplication.run(ShardingDemoApplication.class, args);
}
}
user
package com.hzau.shardingdemo.entity;
import lombok.Data;
/**
* @ClassName User
* @Description TODO
* @Author yueyiming
* @Date 2020/7/28 14:04
* @Version 1.0
* https://blog.csdn.net/hzau_itdog
**/
@Data
public class User {
private Integer id;
private String username;
private String password;
}
userMapper
/**
* @ClassName UserMapper
* @Description TODO
* @Author yueyiming
* @Date 2020/7/28 14:05
* @Version 1.0
* https://blog.csdn.net/hzau_itdog
**/
public interface UserMapper extends BaseMapper {
}
controller
package com.hzau.shardingdemo.controller;
import com.hzau.shardingdemo.dao.UserMapper;
import com.hzau.shardingdemo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* @ClassName UserController
* @Description TODO
* @Author yueyiming
* @Date 2020/7/28 14:07
* @Version 1.0
* https://blog.csdn.net/hzau_itdog
**/
@RestController
public class UserController {
@Resource
private UserMapper userMapper;
@GetMapping("/users")
public List list() {
return userMapper.selectList(null);
}
@GetMapping("/add")
public Object add() {
for(int i=100;i<150;i++) {
User user = new User();
user.setId(i);
user.setUsername("hzau"+(i));
user.setPassword("1233edwd");
userMapper.insert(user);
}
return "ok";
}
}
访问 127.0.0.1:8080/add
查看数据库
user_0
user_1
user_2
user_3
分表成功。
访问 127.0.0.1:8080/users
可以看到能查出来所有数据。
查看资料
https://www.fangzhipeng.com/db/2019/06/30/sharding-jdbc-tables-ms.html