网站首页 > 技术教程 正文
Sharding-JDBC核心概念
1、SQL核心概念
1.1、逻辑表,水平拆分的数据库(表)的相同逻辑和数据结构表的总称。
1.2、真实表,在分片的数据库中真实存在的物理表。
1.3、数据节点,数据分片的最小单元,由数据源名称和数据表组成,例:ds_0.t_order_0。
1.4、绑定表,指分片规则一致的主表和子表。
1.5、广播表,指所有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中均完全一致。
2、分片核心概念
2.1、分片键,用于分片的数据库字段,是将数据库(表)水平拆分的关键字段。
2.2、分片算法,通过分片算法将数据分片,支持通过=、>=、<=、>、<、BETWEEN和IN分片。分片算法需要应用方开发者自行实现,可实现的灵活度非常高。
1)精确分片算法,对应PreciseShardingAlgorithm,用于处理使用单一键作为分片键的=与IN进行分片的场景。需要配合StandardShardingStrategy使用。
2)范围分片算法,对应RangeShardingAlgorithm,用于处理使用单一键作为分片键的BETWEEN AND、>、<、>=、<=进行分片的场景。需要配合StandardShardingStrategy使用。
3)复合分片算法,对应ComplexKeysShardingAlgorithm,用于处理使用多键作为分片键进行分片的场景,包含多个分片键的逻辑较复杂,需要应用开发者自行处理其中的复杂度。需要配合ComplexShardingStrategy使用。
4)Hint分片算法,对应HintShardingAlgorithm,用于处理使用Hint行分片的场景。需要配合HintShardingStrategy使用。
2.3、分片策略,包含分片键和分片算法,由于分片算法的独立性,将其独立抽离。真正可用于分片操作的是分片键 + 分片算法,也就是分片策略。
1)标准分片策略,对应StandardShardingStrategy,提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。StandardShardingStrategy只支持单分片键,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法。PreciseShardingAlgorithm是必选的,用于处理=和IN的分片。RangeShardingAlgorithm是可选的,用于处理BETWEEN AND, >, <, >=, <=分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND将按照全库路由处理。
2)复合分片策略,对应ComplexShardingStrategy,复合分片策略。提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。
3)行表达式分片策略,对应InlineShardingStrategy,使用Groovy的表达式,提供对SQL语句中的=和IN的分片操作支持,只支持单分片键。对于简单的分片算法,可以通过简单的配置使用,从而避免繁琐的Java代码开发,如: t_user_$->{u_id % 8} 表示t_user表根据u_id模8,而分成8张表,表名称为t_user_0到t_user_7。
4)Hint分片策略,对应HintShardingStrategy,通过Hint指定分片值而非从SQL中提取分片值的方式进行分片的策略。
5)不分片策略,对应NoneShardingStrategy,不分片的策略。
2.4、SQL Hint,对于分片字段非SQL决定,而由其他外置条件决定的场景,可使用SQL Hint灵活的注入分片字段。例如:内部系统,按照员工登录主键分库,而数据库中并无此字段。
3、配置核心概念
3.1、分片规则,分片规则配置的总入口。包含数据源配置、表配置、绑定表配置以及读写分离配置等。
3.2、数据源配置,真实数据源列表。
3.3、表配置,逻辑表名称、数据节点与分表规则的配置。
3.4、数据节点配置,用于配置逻辑表与真实表的映射关系。可分为均匀分布和自定义分布两种形式。
3.5、分片策略配置,对于分片策略存有数据源分片策略和表分片策略两种维度,两种策略的API完全相同。
1)数据源分片策略,对应于DatabaseShardingStrategy。用于配置数据被分配的目标数据源。
2)表分片策略,对应于TableShardingStrategy。用于配置数据被分配的目标表,该目标表存在与该数据的目标数据源内。故表分片策略是依赖与数据源分片策略的结果的。
3.6、自增主键生成策略,通过在客户端生成自增主键替换以数据库原生自增主键的方式,做到分布式主键无重复。
根据表的列值分配到不同的数据库案例
pom.xml(版本)
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-namespace</artifactId>
<version>4.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-orchestration-center-zookeeper-curator</artifactId>
<version>4.1.1</version>
</dependency>
数据库和表
数据库:ds1、ds2。
CREATE TABLE `t_user` (
`id` bigint NOT NULL PRIMARY KEY,
`domain` varchar(45) NOT NULL,
`name` varchar(45) NOT NULL,
`status` varchar(45) NOT NUL
) ENGINE=InnoDB;
自定义数据库标准分片策略
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import java.util.Collection;
public class MyDatabasePreciseShardingAlgorithm implements PreciseShardingAlgorithm<String> {
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
// collection==>所有的数据库名
// preciseShardingValue
return "ds" + preciseShardingValue.getValue();
}
}
功能代码实现:
import javax.sql.DataSource;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class ShardingJDBCDemo01 {
public static void main(String[] args) {
// =====================================================================//
// 配置真实数据源
Map<String, DataSource> dataSourceMap = new HashMap<>();
// 配置第一个数据源
DruidDataSource dataSource1 = new DruidDataSource();
dataSource1.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource1.setUrl("jdbc:mysql://192.168.1.11:3306/ds1?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false");
dataSource1.setUsername("root");
dataSource1.setPassword("root1234");
dataSourceMap.put("ds1", dataSource1);
// 配置第二个数据源
DruidDataSource dataSource2 = new DruidDataSource();
dataSource2.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource2.setUrl("jdbc:mysql://192.168.1.11:3306/ds2?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false");
dataSource2.setUsername("root");
dataSource2.setPassword("root1234");
dataSourceMap.put("ds2", dataSource2);
// =====================================================================//
// shardingJDBC规则配置
// =====================================================================//
TableRuleConfiguration userTableRuleConfig = new TableRuleConfiguration("t_user");
String shardingColumn = "domain";
PreciseShardingAlgorithm preciseShardingAlgorithm = new MyDatabasePreciseShardingAlgorithm();
StandardShardingStrategyConfiguration standardShardingStrategyConfiguration = new StandardShardingStrategyConfiguration(shardingColumn, preciseShardingAlgorithm);
userTableRuleConfig.setDatabaseShardingStrategyConfig(standardShardingStrategyConfiguration);
ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
shardingRuleConfig.getTableRuleConfigs().add(userTableRuleConfig);
// =====================================================================//
// 获取数据源对象
// =====================================================================//
DataSource dataSource = null;
try {
dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new Properties());
} catch (SQLException e) {
e.printStackTrace();
}
// =====================================================================//
// 插入数据
// =====================================================================//
for (int i = 1; i <= 10; i++) {
try {
String sql = "insert into t_user(`id`,`domain`,`name`,`status`) values(" + i + ",'2','1','1')";
Connection conn = dataSource.getConnection();
Statement stmt = conn.createStatement();
stmt.executeUpdate(sql);
System.out.println("插入:" + i);
} catch (SQLException e) {
e.printStackTrace();
}
}
System.out.println("操作完成...");
}
}
测试说明:
给表中插入数据时,根据表t_user中列domain的值不同,分片存储到不同的数据库。
猜你喜欢
- 2024-11-12 【Java面试】OOM你遇到过哪些情况,SOF你遇到过哪些情况?
- 2024-11-12 Java干货:InetAddress基本操作演示
- 2024-11-12 Redis 哈希表 VS Java HaspMap , 哪家强?
- 2024-11-12 Java历史上接口的演变(java接口通俗理解)
- 2024-11-12 鸿蒙系统中的 JS 开发框架(js开发鸿蒙app)
- 2024-11-12 Java和JavaScript有什么区别?(javascript和java区别大吗)
- 2024-11-12 初识sa-token,一行代码搞定登录授权
- 2024-11-12 Java读取XML文件缺少部分字符串(java读取xml文件中的内容)
- 2024-11-12 Java的虚拟线程如何帮助您的业务?
- 2024-11-12 Clojure vs Java:少数据结构、多函数胜过多个单独类的优点
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- 下划线是什么 (87)
- 精美网站 (58)
- qq登录界面 (90)
- nginx 命令 (82)
- nginx .http (73)
- nginx lua (70)
- nginx 重定向 (68)
- Nginx超时 (65)
- nginx 监控 (57)
- odbc (59)
- rar密码破解工具 (62)
- annotation (71)
- 红黑树 (57)
- 智力题 (62)
- php空间申请 (61)
- 按键精灵 注册码 (69)
- 软件测试报告 (59)
- ntcreatefile (64)
- 闪动文字 (56)
- guid (66)
- abap (63)
- mpeg 2 (65)
- column (63)
- dreamweaver教程 (57)
- excel行列转换 (56)
本文暂时没有评论,来添加一个吧(●'◡'●)