Sharding-JDBC实现Mysql分表项目演示

引言

上一篇:Sharding-JDBC实现Mysql读写分离实战演示 中,咱们使用读写分离,将数据库查询的压力分担到从库中,但是,如果单表的数据量非常的大,超过1000万行了,通过单表的优化,已经无法显著的优化性能,此时就要考虑分表了。
官方文档地址:shardingsphere官方文档

1、环境准备

本项目在上一篇项目的基础上进行修改,如下:

  1. 数据库脚本准备
USE `coolsummermoon`;
DROP TABLE IF EXISTS `user_0`;
CREATE TABLE `user_0` (
  `id` bigint(18) NOT NULL AUTO_INCREMENT,
  `username` varchar(30) NOT NULL,
  `password` varchar(30) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `user_1`;
CREATE TABLE `user_1` (
  `id` bigint(18) NOT NULL AUTO_INCREMENT,
  `username` varchar(30) NOT NULL,
  `password` varchar(30) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `user_2`;
CREATE TABLE `user_2` (
  `id` bigint(18) NOT NULL AUTO_INCREMENT,
  `username` varchar(30) NOT NULL,
  `password` varchar(30) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
  1. 修改application.yml
sharding:
  jdbc:
    datasource:
      names: db-master,db-slave
      db-master:
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.158.129:3306/coolsummermoon?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
        username: root
        password: 123456
        maxPoolSize: 20
      db-slave:
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.158.131:3306/coolsummermoon?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
        username: root
        password: 123456
        maxPoolSize: 20
    props:
      sql:
        show: true
    config:
      sharding:
        tables:
          user:
            actual-data-nodes: db_0.user_$->{
    
    0..2}
            table-strategy:
              inline:
                sharding-column: id
                algorithm-expression: user_${
    
    id.longValue() % 3}
        master-slave-rules:
          db_0:
           master-data-source-name: db-master
           slave-data-source-names: db-slave
server:
  port: 8010
mybatis:
  type-aliases-package: com.comcoolsummermoon.entity
  mapper-locations: classpath:mapper/*.xml
  1. Controller
@RestController
@RequestMapping("users")
public class UserController {
    
    

    @Autowired
    private UserService userService;

    @GetMapping("/list")
    public Object list() {
    
    
        return userService.list();
    }

    @GetMapping("/insert")
    public Object insert() {
    
    
        for(long i=1; i<100; i++) {
    
    
            User user = new User();
            //注意此处增加了主键id,因为分表的规则是对id除以3取余
            user.setId(i);
            user.setUsername("coolsummermoon" + i);
            user.setPassword("123456");
            userService.insert(user);
        }
        return true;
    }
}

4、UserMapper.xml
insert的语句中一定要加上id(特别强调,这里一定要加id,你可以不加试试),因为sharding的规则是对jdbc进行重写,并且是以id作为分表的策略

<insert id="insert" parameterType="com.comcoolsummermoon.entity.User">
	insert into user (id,username, password)
	values (#{id,jdbcType=BIGINT},#{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR})
</insert>
  1. 除上面标注的部分,其余和上一篇项目一致

2、测试

  1. 启动项目工程,调用插入接口
  2. 打开master数据库,三个表中的数据,都按照分表规则插入成功
  3. 打开slave数据库,三个表的数据都备份成功
  4. 调用查询接口,成功返回数据,数据的格式是先返回user_0、user_1、user_2中的数据进行排序,如果想要按照id从小到大排序,则需要修改查询sql,增加:order by id

结束语

想要了解更详细的配置,可以参考文章开头的官方文档。

留一个思考题:本篇是以id作为分表的策略,如果是其它字段,如何保证主键的唯一性呢?

猜你喜欢

转载自blog.csdn.net/cool_summer_moon/article/details/106356764