分库分表实战
实战代码示例: https://gitee.com/ixinglan/mysql-demo.git
sharding-jdbc-demo: 详见README.md 介绍
1. 分库实战(这里是水平分库)
我们演示position表的分库
CREATE TABLE `position` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`salary` varchar(10) DEFAULT NULL,
`city` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb4;
- 创建两个库 sharding-demo1, sharding-demo2模拟两台服务器
- 分别执行position表的创建sql
- 创建与数据库对应实体entity: Position 提示: @GeneratedValue(strategy = GenerationType.IDENTITY) 应先注释掉,便于手动造id,观察数据写库策略情况
- 创建数据库操作类: PositionRepository
- 配置application.yml
- 配置application-sharding-database.yml
# datasource, 配置两个数据源, 这里配置我们刚创建的两个库
spring:
shardingsphere:
datasource:
names: ds0,ds1
ds0:
type: com.zaxxer.hikari.HikariDataSource
driver-class: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/sharding-demo1
username: root
password: 123456
ds1:
type: com.zaxxer.hikari.HikariDataSource
driver-class: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/sharding-demo2
username: root
password: 123456
# sharding-database 先采用 inline 行表达式的形式配置分库策略: 模2
sharding:
tables:
position:
databaseStrategy:
inline:
shardingColumn: id
algorithmExpression: ds$->{id % 2}
- 创建测试类: TestShardingDatabase, 见test1方法
2. 主键生成器
我们在1.1中, 主键是手动指定生成的, 这节我们改造一下,使用主键生成器
- 配置文件添加id生成策略配置
# sharding-database
sharding:
tables:
position:
databaseStrategy:
inline:
shardingColumn: id
algorithmExpression: ds$->{id % 2}
# 主键生成器, 此处我们使用内置的雪花算法
keyGenerator:
column: id
type: SNOWFLAKE
- 将 @GeneratedValue(strategy = GenerationType.IDENTITY) 注释放开,不然会使用数据库自身的自增
- TestShardingDatabase: test1 方法测试, 注释掉设置主键值, 如果写不进去,我们需要将主键int类型修改为bigint
3. 自定义主键生成器
1.2 我们演示了内置主键生成器, 这里我们演示自定义主键生成器
- 创建id生成类 MyId,实现ShardingKeyGenerator接口
- spi配置: 创建META-INF/services/org.apache.shardingsphere.spi.keygen.ShardingKeyGenerator,里面指定MyId路径
- 配置文件修改为 MyId
keyGenerator:
column: id
type: MyId
- TestShardingDatabase: test1 方法测试
4. 垂直分表+水平分库
如果一个表里字段太多, 往往将不常用字段拆分出来到一或多张表 这里我们演示 position_detail表: pid与主表主键id关联
CREATE TABLE `position_detail` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`pid` bigint(20) DEFAULT NULL,
`description` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
- 分别执行position表的创建sql
- 创建与数据库对应实体entity: PositionDetail
- 创建数据库操作类: PositionDetailRepository
- 配置文件application-sharding-database.yml 添加 分片字段+主键策 略配置, 注意分片主键变为了 pid
# sharding-database
sharding:
tables:
# 主表
position:
databaseStrategy:
inline:
shardingColumn: id
algorithmExpression: ds$->{id % 2}
# 主键生成器
keyGenerator:
column: id
# type: SNOWFLAKE
type: MyId
# 副表
position_detail:
databaseStrategy:
inline:
shardingColumn: pid
algorithmExpression: ds$->{id % 2}
# 主键生成器
keyGenerator:
column: id
type: MyId
- 测试方法 TestShardingDatabase: test2
- 测试查询 TestShardingDatabase: test3
5. 广播表
演示city表
CREATE TABLE `city` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`province` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
- 创建对应entity: City
- 创建repository: CityRepository
- 配置文件添加以下
#广播表
city:
# 主键生成器
keyGenerator:
column: id
type: SNOWFLAKE
#广播表
broadcast-tables:
- city
- 测试方法 TestShardingDatabase: test4
6. 水平分表+水平分库
这里演示order表
- 按 company_id 水平分库, 保证同一company_id在同一个库
- 再按 id 同一个库中水平分表
由于order为关键字, 我们命名表名为 b_order
由于要水平分表,我们分别在两个库建表: b_order0, b_order1
CREATE TABLE `b_order` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`is_del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否被删除',
`company_id` int(11) NOT NULL COMMENT '公司id',
`position_id` int(11) NOT NULL COMMENT '职位id',
`user_id` int(11) NOT NULL COMMENT '用户id',
`publish_user_id` int(11) NOT NULL COMMENT '职位发布者id',
`create_time` datetime NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
- 创建对应entity: Order
- 创建repository: OrderRepository
- 配置文件配置: 分库策略, 分表策略, id策略
# order表
b_order:
# 分库策略
databaseStrategy:
inline:
shardingColumn: company_id
algorithmExpression: ds$->{company_id % 2}
#分表策略
tableStrategy:
inline:
shardingColumn: id
algorithmExpression: b_order${id % 2}
#映射数据节点: 库+表 笛卡尔积
actualDataNodes: ds${0..1}.b_order${0..1}
# 主键生成器
keyGenerator:
column: id
type: SNOWFLAKE
- 测试方法 TestShardingDatabase: test5