分库分表浅谈 迷南。 2021-06-11 15:12 449阅读 0赞 [https://www.jianshu.com/p/3fed6db29a01][https_www.jianshu.com_p_3fed6db29a01] ## 什么是分库分表 ## 顾名思义,分库分表就是按照一定的规则,对原有的数据库和表进行拆分,把原本存储于一个库的数据分块存储到多个库上,把原本存储于一个表的数据分块存储到多个表上。 ## 为什么需要分库分表 ## 随着时间和业务的发展,数据库中的数据量增长是不可控的,库和表中的数据会越来越大,随之带来的是更高的磁盘、IO、系统开销,甚至性能上的瓶颈,而一台服务的资源终究是有限的,因此需要对数据库和表进行拆分,从而更好的提供数据服务。 ## 分库分表的方式 ## ### 垂直分库/分表 ### 垂直划分数据库是根据业务进行划分,例如将shop库中涉及商品、订单、用户的表分别划分出成一个库,通过降低单库(表)的大小来提高性能,但这种方式并没有解决高数据量带来的性能损耗。同样的,分表的情况就是将一个大表根据业务功能拆分成一个个子表,例如用户表可根据业务分成基本信息表和详细信息表等。 ### 垂直分库/分表的优缺点 ### *优点*: 1. 拆分后业务清晰,达到专库专用。 2. 可以实现热数据和冷数据的分离,将不经常变化的数据和变动较大的数据分散再不同的库/表中。 3. 便于维护 *缺点*: 1. 不解决数据量大带来的性能损耗,读写压力依旧很大 2. 不同的业务无法跨库关联(join),只能通过业务来关联 ### 水平分库/分表 ### 水平划分是根据一定规则,例如时间或id序列值等进行数据的拆分。比如根据年份来拆分不同的数据库。每个数据库结构一致,但是数据得以拆分,从而提升性能。又比如根据用户id的值,根据规则分成若干个表。每个表结构一致,(***这点与垂直分库分表相反***)。 ### 水平分库/分表的优缺点 ### 优点: 1. 单库(表)的数据量得以减少,提高性能 2. 提高了系统的稳定性和负载能力 3. 切分出的表结构相同,程序改动较少 缺点: 1. 拆分规则较难抽象 2. 数据分片在扩容时需要迁移 3. 维护量增大 4. 依然存在跨库无法join等问题,同时涉及分布式事务,数据一致性等问题。 ## 使用Sharding-JDBC进行分库分表 ## ***简介***: Sharding-JDBC是一个开源的分布式数据库中间件,它无需额外部署和依赖,完全兼容JDBC和各种ORM框架。Sharding-JDBC作为面向开发的微服务云原生基础类库,完整的实现了分库分表、读写分离和分布式主键功能,并初步实现了柔性事务。关于sj的详细配置和使用方法请参见[官方文档][Link 1] ### 配置 ### Sharing-JDBC的springboot starter对springboot 2.0还不支持。我也是配置完项目启动失败才发现这个issue,懒得切换版本就暂且不使用starter pom吧,直接使用编程式配置。 ### 准备 ### 本Demo中使用的两个数据源是db0和db1,每个数据源之中包含了两组表t\_order\_0和t\_order\_1,t\_order\_item\_0和t\_order\_item\_1 。和官方文档的demo一致,这两组表的建表语句为: CREATE TABLE IF NOT EXISTS t_order_x ( order_id INT NOT NULL, user_id INT NOT NULL, PRIMARY KEY (order_id) ); CREATE TABLE IF NOT EXISTS t_order_item_x ( item_id INT NOT NULL, order_id INT NOT NULL, user_id INT NOT NULL, PRIMARY KEY (item_id) ); 逻辑结构如下: db0 ├── t_order_0 └── t_order_1 db1 ├── t_order_0 └── t_order_1 1. 首先引入依赖 <dependency> <groupId>io.shardingjdbc</groupId> <artifactId>sharding-jdbc-core</artifactId> <version>2.0.3</version> </dependency> 1. 配置表分片策略 @Bean TableRuleConfiguration getOrderTableRuleConfiguration() { TableRuleConfiguration orderTableRuleConfig = new TableRuleConfiguration(); //配置逻辑表名,并非数据库中真实存在的表名,而是sql中使用的那个,不受分片策略而改变. //例如:select * frpm t_order where user_id = xxx orderTableRuleConfig.setLogicTable("t_order"); //配置真实的数据节点,即数据库中真实存在的节点,由数据源名 + 表名组成 //${} 是一个groovy表达式,[]表示枚举,{...}表示一个范围。 //整个inline表达式最终会是一个笛卡尔积,表示ds_0.t_order_0. ds_0.t_order_1 // ds_1.t_order_0. ds_1.t_order_0 orderTableRuleConfig.setActualDataNodes("ds_${0..1}.t_order_${0..1}"); //主键生成列,默认的主键生成算法是snowflake orderTableRuleConfig.setKeyGeneratorColumnName("order_id"); //设置分片策略,这里简单起见直接取模,也可以使用自定义算法来实现分片规则 orderTableRuleConfig.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("order_id","t_order_${order_id % 2}")); return orderTableRuleConfig; } @Bean TableRuleConfiguration getOrderItemTableRuleConfiguration() { TableRuleConfiguration orderItemTableRuleConfig = new TableRuleConfiguration(); orderItemTableRuleConfig.setLogicTable("t_order_item"); orderItemTableRuleConfig.setActualDataNodes("ds_${0..1}.t_order_item_${0..1}"); orderItemTableRuleConfig.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("order_item_id","t_order_item_${order_id % 2}")); return orderItemTableRuleConfig; } 1. 配置数据源 private Map<String, DataSource> createDataSourceMap() { Map<String, DataSource> result = new HashMap<>(2, 1); result.put("ds_0", createDataSource("ds_0")); result.put("ds_1", createDataSource("ds_1")); return result; } private DataSource createDataSource(final String dataSourceName) { DruidDataSource result = new DruidDataSource(); result.setInitialSize(10); result.setMinIdle(10); result.setMaxActive(50); result.setDriverClassName(com.mysql.jdbc.Driver.class.getName()); result.setUrl(String.format("jdbc:mysql://localhost:3306/%s?useSSL=false", dataSourceName)); result.setUsername("root"); result.setPassword(""); return result; } @Bean DataSource getShardingDataSource() throws SQLException { ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration(); shardingRuleConfig.getTableRuleConfigs().add(getOrderTableRuleConfiguration()); shardingRuleConfig.getTableRuleConfigs().add(getOrderItemTableRuleConfiguration()); shardingRuleConfig.getBindingTableGroups().add("t_order, t_order_item"); shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig( new InlineShardingStrategyConfiguration("user_id", "ds_${user_id % 2}")); shardingRuleConfig.setDefaultTableShardingStrategyConfig( new InlineShardingStrategyConfiguration("order_id", "t_order_${order_id % 2}")); return ShardingDataSourceFactory.createDataSource(createDataSourceMap(), shardingRuleConfig, new HashMap<>(), null); } 1. 结果 使用junittest插入一条记录,查看分片结果: @SpringBootTest @RunWith(SpringRunner.class) public class OrderDaoTest { @Autowired private OrderDao orderDao; @Test public void addOrder() { Order order = new Order(); order.setUserId(1); order.setOrderId(1); //insert into t_order (order_id, user_id) values(#{orderId}, #{userId}) orderDao.addOrder(order); } } t\_order这张表配置的分片策略是按照order\_id与2取模,分库策略则是按照user\_id与2取模, 所以最终的结果应该是插入在ds\_1中的t\_order\_1中。 ![Image 1][] image.png [https_www.jianshu.com_p_3fed6db29a01]: https://www.jianshu.com/p/3fed6db29a01 [Link 1]: https://link.jianshu.com?t=http%3A%2F%2Fshardingsphere.io%2Fdocs_cn%2F00-overview%2F [Image 1]:
相关 分库分表 文章目录 * * 一.什么叫分库分表? * * 1.1概念 * 二.为什么要分库分表? * 三.切分类型 *... 不念不忘少年蓝@/ 2024年04月19日 08:05/ 0 赞/ 86 阅读
相关 【分库分表】分库分表 Sharding-JDBC 文章目录 前言 一、基本概念 1.1、表 1.2、逻辑表 1.3、真实表 1.4、绑定表 本是古典 何须时尚/ 2023年10月12日 22:32/ 0 赞/ 15 阅读
相关 Sharding-JDBC分库不分表、分库分表,主从分库分表 分库不分表、分库分表,主从分库分表 分库不分表 server: port: 8800 mybatis: confi 柔光的暖阳◎/ 2022年12月30日 15:53/ 0 赞/ 272 阅读
相关 分库分表场景--单表转分库分表 原文网址:[分库分表场景--单表转分库分表\_IT利刃出鞘的博客-CSDN博客][--_IT_-CSDN] 方案1:sharding-proxy + sharding-sc 我会带着你远行/ 2022年10月31日 00:38/ 0 赞/ 236 阅读
相关 分库 分表 分库,降低了单点机器的负载;分表,提高了数据操作的效率,尤其是Write操作的效率。 (1)切分的方式主要有两种,水平切分和垂直切分。 1、水平切分 简单的说就是, 我不是女神ヾ/ 2022年06月02日 03:37/ 0 赞/ 306 阅读
相关 分库分表 常用的切分方案 数据的切分(Sharding)根据其切分规则的类型,可以分为两种切分模式。 一种是按照不同的表(或者Schema)来切分到不同的数据库(主机)之上,这种 你的名字/ 2022年05月09日 06:38/ 0 赞/ 257 阅读
相关 分库分表 分库分表 为什么分库分表 在高并发和海量数据的场景下,通过使用分库分表的手段,能够解决单机或者单库单表的性能瓶颈和压力,突破IO、连接数、硬件资源的瓶颈。当然,投入 - 日理万妓/ 2022年04月22日 06:12/ 0 赞/ 329 阅读
相关 分库分表 一. 数据切分 关系型数据库本身比较容易成为系统瓶颈,单机存储容量、连接数、处理能力都有限。当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加从库、优 小咪咪/ 2022年03月19日 02:44/ 0 赞/ 410 阅读
相关 分表分库 一、常见面试题 1、为什么分表分库? 2、分表分库中间件有哪些?分别有什么特点? 3、垂直拆分还是水平拆分?有什么区别? 二、问题分析 1、由于用户数量增长, 野性酷女/ 2022年01月20日 00:25/ 0 赞/ 424 阅读
相关 分库分表浅谈 [https://www.jianshu.com/p/3fed6db29a01][https_www.jianshu.com_p_3fed6db29a01] 什么是分 迷南。/ 2021年06月11日 15:12/ 0 赞/ 450 阅读
还没有评论,来说两句吧...