前言

shardingjdbc进行分库 一节中,我们对数据分库做了介绍。现在想象一个场景,如果我们对数据进行分库之后,每个库中该表中的数据量依然很大,这个时候应该怎么办?

一种解决方案是我们可以多加服务器,分到更多个库中,但是如果我们服务器的资源有限,我们应该如何解决呢?

我们可以对同一个库中的数据进行分表,从而减小每个表的负载。

下面我们来对数据进行分库的基础上,进一步分表。

准备数据

在lagou1和lagou2两个数据库中分别创建2张表b_lagou0、b_lagou1,两表的结构完全一致,sql如下(省略了部分语句):

1
2
3
4
5
6
7
CREATE TABLE `b_order0`(
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`is_del` bit(1) NOT NULL DEFAULT 0 COMMENT '是否被删除',
`company_id` int(11) NOT NULL COMMENT '公司ID',
`position_id` bigint(11) NOT NULL COMMENT '职位ID',
`user_id` int(11) NOT NULL COMMENT '用户id'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;

代码及配置

创建对应的实体类及JpaRepository(代码省略,详见文末源码),

需要注意的几点,在实体类中@Table注解的表名需要配置成b_order:

配置文件中配置sharding-jdbc的数据分库分表策略及主键生成策略:

1
2
3
4
5
6
7
8
9
10
#sharding-database-table
#设置b_order表的分库策略,按company_id对2求模来分库
spring.shardingsphere.sharding.tables.b_order.database-strategy.inline.sharding-column=company_id
spring.shardingsphere.sharding.tables.b_order.database-strategy.inline.algorithm-expression=ds$->{company_id % 2}
#设置同一个库中的b_order表的分表策略,按id对2求模来分表
spring.shardingsphere.sharding.tables.b_order.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.b_order.table-strategy.inline.algorithm-expression=b_order${id % 2}
spring.shardingsphere.sharding.tables.b_order.actual-data-nodes=ds${0..1}.b_order${0..1}
spring.shardingsphere.sharding.tables.b_order.key-generator.column=id
spring.shardingsphere.sharding.tables.b_order.key-generator.type=SNOWFLAKE

我们按照b_order中的company_id字段来进行分库,然后在同一个数据库中使用id来进行分表。

测试

我们编写测试用例循环100次来生成记录存储到mysql:

1
2
3
4
5
6
7
8
9
10
11
12
@Test
@Repeat(100)
public void testShardingBOrder(){
Random random = new Random();
int companyId = random.nextInt(10);
BOrder order = new BOrder();
order.setDel(false);
order.setCompanyId(companyId);
order.setPositionId(3242342);
//...此处省略
orderRepository.save(order);
}

先对company_id对2求模进行分库,然后对id对2求模进行分表,结果如下:

lagou1库中的数据:

lagou2库中的数据:

源码

sharding-jdbc分表demo