赞
踩
注意:分库分表要注意id不能再用数据库自增方式。可以采用雪花算法(新增的表),自定义分片算法(旧表)
分片策略配置
对于分片策略存有数据源分片策略和表分片策略两种维度
对应于DatabaseShardingStrategy。用于配置数据被分配的目标数据源
表:
- CREATE TABLE `t_user0` (
- `id` bigint(20) NOT NULL,
- `name` varchar(64) DEFAULT NULL COMMENT '名称',
- `city_id` int(12) DEFAULT NULL COMMENT '城市',
- `sex` tinyint(1) DEFAULT NULL COMMENT '性别',
- `phone` varchar(32) DEFAULT NULL COMMENT '电话',
- `email` varchar(32) DEFAULT NULL COMMENT '邮箱',
- `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
- `password` varchar(32) DEFAULT NULL COMMENT '密码',
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
- CREATE TABLE `t_user1` (
- `id` bigint(20) NOT NULL,
- `name` varchar(64) DEFAULT NULL COMMENT '名称',
- `city_id` int(12) DEFAULT NULL COMMENT '城市',
- `sex` tinyint(1) DEFAULT NULL COMMENT '性别',
- `phone` varchar(32) DEFAULT NULL COMMENT '电话',
- `email` varchar(32) DEFAULT NULL COMMENT '邮箱',
- `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
- `password` varchar(32) DEFAULT NULL COMMENT '密码',
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
库:
test0,test1
pom:
- <dependency>
- <groupId>org.apache.shardingsphere</groupId>
- <artifactId>sharding-jdbc-core</artifactId>
- <version>4.1.1</version>
- </dependency>
properties:
- spring.application.name=shardingjdbc
- server.port=8080
-
- datasource0.url=jdbc:mysql://localhost:3306/test0?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
- datasource0.driver-class-name=com.mysql.cj.jdbc.Driver
- datasource0.type=com.alibaba.druid.pool.DruidDataSource
- datasource0.username=root
- datasource0.password=123456
-
- datasource1.url=jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
- datasource1.driver-class-name=com.mysql.cj.jdbc.Driver
- datasource1.type=com.alibaba.druid.pool.DruidDataSource
- datasource1.username=root
- datasource1.password=123456
-
- mybatis.mapper-locations=classpath:com/example/shardingjdbc/mapper/*.xml
- mybatis.type-aliases-package=com.example.shardingjdbc.**.entity
- #打印sql
- spring.shardingsphere.props.sql.show=true
- #
- spring.datasource.druid.filters=stat,wall,log4j2
- spring.datasource.druid.web-stat-filter.enabled=true
- spring.datasource.druid.web-stat-filter.url-pattern=/*
- spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*
- spring.datasource.druid.web-stat-filter.session-stat-enable=true
- spring.datasource.druid.web-stat-filter.session-stat-max-count=1000
- #spring.datasource.druid.web-stat-filter.principal-session-name=
- #spring.datasource.druid.web-stat-filter.principal-cookie-name=
- #spring.datasource.druid.web-stat-filter.profile-enable=
- spring.datasource.druid.stat-view-servlet.enabled=true
- spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
- spring.datasource.druid.stat-view-servlet.reset-enable=false
- spring.datasource.druid.stat-view-servlet.login-username=admin
- spring.datasource.druid.stat-view-servlet.login-password=123
- spring.datasource.druid.stat-view-servlet.allow=127.0.0.1
- spring.datasource.druid.stat-view-servlet.deny=
主键策略:
- package com.example.shardingjdbc.config;
-
- import org.apache.shardingsphere.core.strategy.keygen.SnowflakeShardingKeyGenerator;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
-
- @Configuration
- public class KeyIdConfig {
-
- @Bean("userKeyGenerator")
- public SnowflakeShardingKeyGenerator userKeyGenerator() {
- return new SnowflakeShardingKeyGenerator();
- }
-
- @Bean("orderKeyGenerator")
- public SnowflakeShardingKeyGenerator orderKeyGenerator() {
- return new SnowflakeShardingKeyGenerator();
- }
- }
分表分库策略:
- package com.example.shardingjdbc.sharding;
-
- import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
- import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
-
- import java.util.Collection;
-
- public class UserShardingAlgorithm {
-
- public static final DatabaseShardingAlgorithm databaseShardingAlgorithm = new DatabaseShardingAlgorithm();
-
- public static final TableShardingAlgorithm tableShardingAlgorithm = new TableShardingAlgorithm();
-
- static class DatabaseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
- @Override
- public String doSharding(Collection<String> databaseNames, PreciseShardingValue<Long> shardingValue) {
- for (String database : databaseNames) {
- if (database.endsWith(String.valueOf(shardingValue.getValue() % 2))) {
- return database;
- }
- }
-
- return "";
- }
- }
-
- static class TableShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
- @Override
- public String doSharding(Collection<String> tableNames, PreciseShardingValue<Long> shardingValue) {
- for (String table : tableNames) {
- if (table.endsWith(String.valueOf(shardingValue.getValue() % 2))) {
- return table;
- }
- }
-
- return "";
- }
- }
- }
配置:
1.分表不分库
DataSourceConfig:
- package com.example.shardingjdbc.config;
-
- import com.alibaba.druid.pool.DruidDataSource;
- import com.example.shardingjdbc.sharding.UserShardingAlgorithm;
- import org.apache.shardingsphere.api.config.sharding.KeyGeneratorConfiguration;
- import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
- import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
- import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
- import org.apache.shardingsphere.api.config.sharding.strategy.StandardShardingStrategyConfiguration;
- import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
-
- import javax.sql.DataSource;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Properties;
-
- @Configuration
- public class DataSourceConfig {
-
- @Value("${datasource0.url}")
- private String url0;
- @Value("${datasource0.username}")
- private String username0;
- @Value("${datasource0.password}")
- private String password0;
- @Value("${datasource0.driver-class-name}")
- private String driverClassName0;
-
- @Value(("${spring.datasource.druid.filters}"))
- private String filters;
-
- @Bean("dataSource")
- public DataSource dataSource() {
- try {
- DruidDataSource dataSource0 = new DruidDataSource();
- dataSource0.setDriverClassName(this.driverClassName0);
- dataSource0.setUrl(this.url0);
- dataSource0.setUsername(this.username0);
- dataSource0.setPassword(this.password0);
- dataSource0.setFilters(this.filters);
- //分库设置
- Map<String, DataSource> dataSourceMap = new HashMap<>(2);
- //添加数据库database0
- dataSourceMap.put("ds0", dataSource0);
- // 配置 t_user 表规则
- TableRuleConfiguration userRuleConfiguration = new TableRuleConfiguration("t_user", "ds0.t_user${0..1}");
- //此处可以自定义
- //userRuleConfiguration.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("id", "t_user${id % 2}"));
- StandardShardingStrategyConfiguration standardShardingStrategyConfiguration =
- new StandardShardingStrategyConfiguration("id", UserShardingAlgorithm.tableShardingAlgorithm);
- userRuleConfiguration.setTableShardingStrategyConfig(standardShardingStrategyConfiguration);
- //主键
- userRuleConfiguration.setKeyGeneratorConfig(new KeyGeneratorConfiguration("SNOWFLAKE", "id", getProperties()));
- // Sharding全局配置
- ShardingRuleConfiguration shardingRuleConfiguration = new ShardingRuleConfiguration();
- shardingRuleConfiguration.getTableRuleConfigs().add(userRuleConfiguration);
- // 创建数据源
- DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfiguration, new Properties());
- return dataSource;
- } catch (Exception ex) {
- ex.printStackTrace();
- return null;
- }
- }
- private static Properties getProperties() {
- Properties result = new Properties();
- result.setProperty("worker.id", "123");
- return result;
- }
- }
2.分库不分表
- package com.example.shardingjdbc.config;
-
- import com.alibaba.druid.pool.DruidDataSource;
- import com.example.shardingjdbc.sharding.UserShardingAlgorithm;
- import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
- import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
- import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
- import org.apache.shardingsphere.api.config.sharding.strategy.StandardShardingStrategyConfiguration;
- import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
-
- import javax.sql.DataSource;
- import java.util.*;
-
- @Configuration
- public class DataSourceConfig {
-
- @Value("${datasource0.url}")
- private String url0;
- @Value("${datasource0.username}")
- private String username0;
- @Value("${datasource0.password}")
- private String password0;
- @Value("${datasource0.driver-class-name}")
- private String driverClassName0;
-
- @Value("${datasource1.url}")
- private String url1;
- @Value("${datasource1.username}")
- private String username1;
- @Value("${datasource1.password}")
- private String password1;
- @Value("${datasource1.driver-class-name}")
- private String driverClassName1;
-
- @Value(("${spring.datasource.druid.filters}"))
- private String filters;
-
- @Bean("dataSource")
- public DataSource dataSource() {
- try {
- DruidDataSource dataSource0 = new DruidDataSource();
- dataSource0.setDriverClassName(this.driverClassName0);
- dataSource0.setUrl(this.url0);
- dataSource0.setUsername(this.username0);
- dataSource0.setPassword(this.password0);
- dataSource0.setFilters(this.filters);
- DruidDataSource dataSource1 = new DruidDataSource();
- dataSource1.setDriverClassName(this.driverClassName1);
- dataSource1.setUrl(this.url1);
- dataSource1.setUsername(this.username1);
- dataSource1.setPassword(this.password1);
- dataSource1.setFilters(this.filters);
- //分库设置
- Map<String, DataSource> dataSourceMap = new HashMap<>(2);
- //添加两个数据库database0和database1
- dataSourceMap.put("ds0", dataSource0);
- dataSourceMap.put("ds1", dataSource1);
- // 配置 t_user 表规则
- TableRuleConfiguration userRuleConfiguration = new TableRuleConfiguration("t_user", "ds${0..1}.t_user0");
- //id 是 偶数的都插入到了 test0 库的 t_user0 表中, 奇数的都插入到了 test1 库中的 t_user1 表中
- /**
- * #表策略 行表达式分表规则
- * sharding.jdbc.config.sharding.tables.user.actual-data-nodes=ds_$->{0..1}.user_$->{0..4}
- * sharding.jdbc.config.sharding.tables.user.table-strategy.inline.sharding-column=id
- * sharding.jdbc.config.sharding.tables.user.table-strategy.inline.algorithm-expression=user_$->{id % 5}
- * sharding.jdbc.config.sharding.tables.user.key-generator-column-name=id
- */
- // 行表达式分库规则
- /**
- * #库策略
- * sharding.jdbc.config.sharding.default-database-strategy.inline.sharding-column=id
- * harding.jdbc.config.sharding.default-database-strategy.inline.algorithm-expression=ds_$->{id % 2}
- */
- StandardShardingStrategyConfiguration standardShardingStrategyConfiguration =
- new StandardShardingStrategyConfiguration("id", UserShardingAlgorithm.databaseShardingAlgorithm);
- userRuleConfiguration.setDatabaseShardingStrategyConfig(standardShardingStrategyConfiguration);
- // Sharding全局配置
- ShardingRuleConfiguration shardingRuleConfiguration = new ShardingRuleConfiguration();
- shardingRuleConfiguration.getTableRuleConfigs().add(userRuleConfiguration);
- // 创建数据源
- DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfiguration, new Properties());
- return dataSource;
- } catch (Exception ex) {
- ex.printStackTrace();
- return null;
- }
- }
- }
3.分库分表
- package com.example.shardingjdbc.config;
-
- import com.alibaba.druid.pool.DruidDataSource;
- import com.example.shardingjdbc.sharding.UserShardingAlgorithm;
- import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
- import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
- import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
- import org.apache.shardingsphere.api.config.sharding.strategy.StandardShardingStrategyConfiguration;
- import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
-
- import javax.sql.DataSource;
- import java.util.*;
-
- @Configuration
- public class DataSourceConfig {
-
- @Value("${datasource0.url}")
- private String url0;
- @Value("${datasource0.username}")
- private String username0;
- @Value("${datasource0.password}")
- private String password0;
- @Value("${datasource0.driver-class-name}")
- private String driverClassName0;
-
- @Value("${datasource1.url}")
- private String url1;
- @Value("${datasource1.username}")
- private String username1;
- @Value("${datasource1.password}")
- private String password1;
- @Value("${datasource1.driver-class-name}")
- private String driverClassName1;
-
- @Value(("${spring.datasource.druid.filters}"))
- private String filters;
-
- @Bean("dataSource")
- public DataSource dataSource() {
- try {
- DruidDataSource dataSource0 = new DruidDataSource();
- dataSource0.setDriverClassName(this.driverClassName0);
- dataSource0.setUrl(this.url0);
- dataSource0.setUsername(this.username0);
- dataSource0.setPassword(this.password0);
- dataSource0.setFilters(this.filters);
-
- DruidDataSource dataSource1 = new DruidDataSource();
- dataSource1.setDriverClassName(this.driverClassName1);
- dataSource1.setUrl(this.url1);
- dataSource1.setUsername(this.username1);
- dataSource1.setPassword(this.password1);
- dataSource1.setFilters(this.filters);
- //分库设置
- Map<String, DataSource> dataSourceMap = new HashMap<>(2);
- //添加两个数据库database0和database1
- dataSourceMap.put("ds0", dataSource0);
- dataSourceMap.put("ds1", dataSource1);
- /**
- * 除了基本的分库分表规则以外,还有一些其他的配置,比如绑定表。这里先不一一举例了,参照官方文档配即可。
- * 举个例子:现在有 order, order_detail两张表,1:1的关系。
- * 在配置的时候,应该将相同 order_id 的 order 记录 和 order_detail 记录 映射到相同尾号的表中。这样方便连接查询。比如都插入到 order0, order_detail0中。
- * 如果配置了绑定关系,那么只会产生一条查询 select * from order0 as o join order_detail0 as d on o.order_id = d.order_id。
- * 否则会产生笛卡儿积查询,
- * select * from order0 as o join order_detail0 as d on o.order_id = d.order_id。
- * select * from order0 as o join order_detail1 as d on o.order_id = d.order_id。
- * select * from order1 as o join order_detail0 as d on o.order_id = d.order_id。
- * select * from order1 as o join order_detail1 as d on o.order_id = d.order_id。
- */
- // 配置 t_user 表规则 库:test0 test1 表 t_user1 t_user0
- TableRuleConfiguration userRuleConfiguration = new TableRuleConfiguration("t_user", "ds${0..1}.t_user${0..1}");
- //id 是 偶数的都插入到了 test0 库的 t_user0 表中, 奇数的都插入到了 test1 库中的 t_user1 表中
- /**
- * #表策略 行表达式分表规则
- * sharding.jdbc.config.sharding.tables.user.actual-data-nodes=ds_$->{0..1}.user_$->{0..1}
- * sharding.jdbc.config.sharding.tables.user.table-strategy.inline.sharding-column=id
- * sharding.jdbc.config.sharding.tables.user.table-strategy.inline.algorithm-expression=user_$->{id % 5}
- * sharding.jdbc.config.sharding.tables.user.key-generator-column-name=id
- */
- //sharding.jdbc.config.sharding.tables.user.table-strategy.standard.precise-algorithm-class-name: com.forezp.sharedingjdbcmasterslavetables.MyPreciseShardingAlgorithm
- //此处可以自定义
- userRuleConfiguration.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("id", "t_user${id % 2}"));
- // 行表达式分库规则
- /**
- * #库策略
- * sharding.jdbc.config.sharding.default-database-strategy.inline.sharding-column=id
- * harding.jdbc.config.sharding.default-database-strategy.inline.algorithm-expression=ds_$->{id % 2}
- */
- //根据城市分库
- userRuleConfiguration.setDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("city_id", "ds${city_id % 2}"));
- // Sharding全局配置
- ShardingRuleConfiguration shardingRuleConfiguration = new ShardingRuleConfiguration();
- shardingRuleConfiguration.getTableRuleConfigs().add(userRuleConfiguration);
- // 创建数据源
- DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfiguration, new Properties());
- return dataSource;
- } catch (Exception ex) {
- ex.printStackTrace();
- return null;
- }
- }
- }
注意:
1.事务需要手动配置。
2.手动开启sql打印
3.跨节点连接查询问题(分页、排序)
4.多数据源管理问题
分库分表根据业务划分:要注意各表之间的依赖关系,其有个体表,和全局表,全局表可以在每一个库中存放一份,以便提高查询的性能。如:用户表和用户地址表这两张表是相互依赖的,订单明细表和订单表也是相互依赖的,可以存访到一个库中中,减少网路请求I/O。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。