探秘Sharding JDBC----分库分表操作

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了探秘Sharding JDBC----分库分表操作相关的知识,希望对你有一定的参考价值。

熟悉sharding JDBC的同学都知道,分库分表的操作是使用sharding JDBC中非常重要的,可能还有很多初学者对此阶段的学习存在疑虑,因此,接下来我会帮助你逐渐深入分库分表的操作。
环境准备
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version></parent>
<properties>
<java.version>1.8</java.version>
<sharding.version>3.1.0</sharding.version></properties>
<dependencies>
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>${sharding.version}</version>
</dependency>

<dependency>
    <groupId>io.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>${sharding.version}</version>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.10</version>
</dependency>

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.5</version>
</dependency>

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.1</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.46</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency></dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins></build>
domain
// 建立domain@Setter@Getter@ToString@NoArgsConstructor@AllArgsConstructorpublic class Employee {
private Long id;
private String name;}
配置类
@SpringBootApplication@MapperScan("cn.wolfcode.sharding.mapper")public class ShardingApplication { }
分库分表
案例模型
把数据分别存放在两台服务器的两个数据库中表,通过分片算法来决定当前的数据存放在哪个数据库的哪个表中,由于一个连接池只能连接一个特定的数据库,所以这里需要创建多个连接池对象
建表
-- 分别在2台服务器中建立数据库sharding,并且建表employee_0和employee_1CREATE TABLE employee_0 (
id bigint(20) PRIMARY KEY AUTO_INCREMENT,
name varchar(255) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ###################################CREATE TABLE employee_1 (
id bigint(20) PRIMARY KEY AUTO_INCREMENT,
name varchar(255) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8;
application.properties

定义连接池

sharding.jdbc.datasource.names=db0,db1

格式sharding.jdbc.datasource.连接池名.xxx:设置4要素信息

sharding.jdbc.datasource.db0.type=com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.db0.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.db0.url=jdbc:mysql://db0Ip:port/sharing
sharding.jdbc.datasource.db0.username=xxx
sharding.jdbc.datasource.db0.password=xxx

sharding.jdbc.datasource.db1.type=com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.db1.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.db1.url=jdbc:mysql://db1Ip:port/sharing
sharding.jdbc.datasource.db1.username=xxx
sharding.jdbc.datasource.db1.password=xxx

设置分库规则

sharding.jdbc.config.sharding.default-database-strategy.inline.sharding-column:分库列

sharding.jdbc.config.sharding.default-database-strategy.inline.algorithm-expression:分库算法

sharding.jdbc.config.sharding.default-database-strategy.inline.sharding-column=id
sharding.jdbc.config.sharding.default-database-strategy.inline.algorithm-expression=db$->{id % 2}

绑定逻辑表

sharding.jdbc.config.sharding.binding-tables=employee

设置分表规则

sharding.jdbc.config.sharding.tables.逻辑表.actual-data-nodes:逻辑表对应的真实表

sharding.jdbc.config.sharding.tables.逻辑表.table-strategy.inline.sharding-column:分表列

sharding.jdbc.config.sharding.tables.逻辑表.table-strategy.inline.algorithm-expression:分表算法

sharding.jdbc.config.sharding.tables.逻辑表.key-generator-column-name:主键列

sharding.jdbc.config.sharding.tables.employee.actual-data-nodes=db$->{0..1}.employee$->{0..1}
sharding.jdbc.config.sharding.tables.employee.table-strategy.inline.sharding-column=id
sharding.jdbc.config.sharding.tables.employee.table-strategy.inline.algorithm-expression=employee
$->{id % 2}
sharding.jdbc.config.sharding.tables.employee.key-generator-column-name=id

打印日志

sharding.jdbc.config.props.sql.show=true
mapper
/**

  • 这里写的employee表是上面所配置的逻辑表
  • 底层会根据分片规则,把我们写的逻辑表改写为数据库中的真实表
    /@Mapperpublic interface EmployeeMapper {
    @Select("select
    from employee")
    List<Employee> selectAll();

    @Insert("insert into employee (name) values (#{name})")
    void inser(Employee entity);}
    测试
    @RunWith(SpringRunner.class)@SpringBootTest(classes=ShardingApplication.class)public class ShardingApplicationTests {

    @Autowired
    private EmployeeMapper employeeMapper;

    @Test
    public void save() {
    for (int i = 0; i < 10; i++) {
    Employee employee = new Employee();
    employee.setName("xx"+i);
    employeeMapper.inser(employee);
    }
    }

    @Test
    public void list() {
    employeeMapper.selectAll().forEach(System.out::println);
    }}
    优缺点
    ?拆分后单表数据量比较小,单表大数据被拆分,解决了单表大数据访问问题
    ?分表以什么切分如果弄的不好,导致多次查询,而且有时候要跨库操作,甚至导致join无法使用,对排序分组等有性能影响
    ?之前的原子操作被拆分成多个操作,事务处理变得复杂
    ?多个DB维护成本增加

分库分表的操作并不难学,只是整个shardingJDBC的学习范围还是比较广,要学好也并不是那么容易的。平时一定要多学多练,遇到不会的问题及时请教,如果有需要我帮助的地方,我也会尽我所力帮助你学习。

以上是关于探秘Sharding JDBC----分库分表操作的主要内容,如果未能解决你的问题,请参考以下文章

Sharding-JDBC读写分离探秘

Sharding JDBC如何分库分表?看完你就会了

一小时读懂Sharding JDBC之分库分表

分库分表之Sharding-JDBC

学习sharding-jdbc 分库分表扩展框架

shardingsphere