文章目录
- 什么情况下需要拆分?
- 拆分的方案
- ShardingSphere-JDBC
- 步骤
- 分片中如何实现字典表联查呢?
- 其他
- 文档
一道经常考的题,必须掌握。
注:不是高级开发才需要掌握,中级开发就应该掌握了,因为确实不难。
什么情况下需要拆分?
主要需要考虑两个维度:
1、条数
如果是mysql库,单表超过1000万就需要拆分了,因为无论如何加索引、优化查询可能还是解决不了问题。
如果是oracle库,单表10亿以内都可以通过优化来解决,这里不这么高了,1亿吧,超过1亿就需要拆分了。
2、字段数
字段数过多也会影响性能。一般来说,单表超过50个字段就需要拆分了。
拆分的方案
主要有两种:
1、水平拆分
单表数据量过大用水平拆分。
表结构基本不变,加分片字段(一个或几个),按条数分到不同片中。
2、垂直拆分
字段过多用垂直拆分。
将原表字段拆到几个表里。
ShardingSphere-JDBC
如果是springboot项目,用ShardingSphere-JDBC实现分片比较成熟。
ShardingSphere-JDBC是一个开源项目。
步骤
1、引入依赖
<dependencies><!-- ShardingSphere JDBC Core --><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jdbc-core</artifactId><version>5.3.2</version><!-- 请使用最新稳定版 --></dependency><!-- 连接池 (推荐 HikariCP) --><dependency><groupId>com.zaxxer</groupId><artifactId>HikariCP</artifactId><version>5.0.1</version></dependency><!-- 数据库驱动 --><!-- ... --></dependencies>2、创建config-sharding.yaml并进行配置,如下:
# config-sharding.yamldataSources:ds0:dataSourceClassName:com.zaxxer.hikari.HikariDataSourcejdbcUrl:jdbc:mysql://localhost:3306/ds0username:rootpassword:rootds1:dataSourceClassName:com.zaxxer.hikari.HikariDataSourcejdbcUrl:jdbc:mysql://localhost:3306/ds1username:rootpassword:rootrules:-!SHARDINGtables:t_order:actualDataNodes:ds${0..1}.t_order_${0..1}databaseStrategy:standard:shardingColumn:user_idshardingAlgorithmName:db_hash_modtableStrategy:standard:shardingColumn:order_idshardingAlgorithmName:table_modshardingAlgorithms:db_hash_mod:type:HASH_MODprops:sharding-count:2table_mod:type:MODprops:sharding-count:23、java代码示例
importorg.apache.shardingsphere.driver.api.yaml.YamlShardingSphereDataSourceFactory;importjavax.sql.DataSource;importjava.io.File;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.ResultSet;publicclassShardingJdbcExample{public static void main(String[]args)throws Exception{//1.加载YAML配置,创建ShardingSphere数据源 DataSource dataSource=YamlShardingSphereDataSourceFactory.createDataSource(new File("path/to/your/config-sharding.yaml"));//2.获取连接并执行SQL,ShardingSphere会自动处理路由和结果归并try(Connection conn=dataSource.getConnection()){//插入数据 String insertSQL="INSERT INTO t_order (user_id, order_id, status) VALUES (?, ?, ?)";try(PreparedStatement ps=conn.prepareStatement(insertSQL)){ps.setLong(1,123L);//user_id ps.setLong(2,888L);//order_id ps.setString(3,"PAID");ps.executeUpdate();}//查询数据 String selectSQL="SELECT * FROM t_order WHERE user_id = ?";try(PreparedStatement ps=conn.prepareStatement(selectSQL)){ps.setLong(1,123L);ResultSet rs=ps.executeQuery();while(rs.next()){System.out.println("Order ID: "+rs.getLong("order_id"));}}}}}分片中如何实现字典表联查呢?
有现成的策略:广播表。
即:在每个分片中都建立相同的表结构,在配置中标记这些表为广播表,查询的时候就直接可以用了。
1、每个分片中都创建广播表。
2、通过配置声明哪些表为广播表。
数据会自动同步、查询时会自动路由。
其他
文档
ShardingSphere-JDBC git地址:
https://github.com/apache/shardingsphere/tree/master/examples/shardingsphere-jdbc-example