# sjdbc **Repository Path**: fengerous/sjdbc ## Basic Information - **Project Name**: sjdbc - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-02-17 - **Last Updated**: 2021-05-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ShardingSphere ## 什么是 ShardingSphere - 一套开源的分布式数据库中间件解决方案 - 有三个产品: ShardingSphere-JDBC、ShardingSphere-Proxy、ShardingSphere-Sidecar - 定位为关系型数据库中间件,合理在分布式环境下使用关系型数据库操作 ## 什么是分库分表 - 数据库数据量不可控,随着时间和业务的发展,造成表里的数据越来越多,如果再对 数据库表进行curd操作,造成性能问题 - 方案一: 从硬件上 - 方案二: 分库分表 ## 分库分表方式 ### 分库分表有两种方式:垂直切分和水平切分 ### 垂直切分:垂直分表和垂直分库 - 垂直分表: 是基于数据表的列(字段)为依据切分的,是一种大表拆小表的模式。 这样拆分以后核心表大多是访问频率较高的字段,而且字段长度也都较短, 因而可以加载更多数据到内存中,来增加查询的命中率,减少磁盘IO,以此来提升数据库性能。 ``` 切分前 A表 (id,name,age,email,idcard,nick_name,password,qq,wechat,address) 切分后 B表 (id,name,nick_name,password) C表 (id,age,email,idcard,qq,wechat,address) ``` **优点** 1. 业务间数据解耦,不同业务的数据进行独立的维护、监控、扩展 2. 在高并发场景下,一定程度上缓解了数据库的压力。 **缺点** 1. 提升了开发的复杂度,由于业务的隔离性,很多表无法直接访问,必须通过接口方式聚合数据 2. 分布式事务管理难度增加。 3. 数据库还是存在单表数据量过大的问题,并未根本上解决,需要配合水平切分。 - 垂直分库: 把单一数据库按业务进行划分,专库专表 ``` 切分前 A库 (A表,B表,C表,D表,E表,F表,G表) 切分后 A库 (A表,B表,C表,D表) B库 (E表,F表,G表) ``` ### 水平切分:水平分库和水平分表 - 水平分库: 水平分库是把同一个表按一定规则拆分到不同的数据库中, 每个库可以位于不同的服务器上,以此实现水平扩展, 是一种常见的提升数据库性能的方式。 这种方案往往能解决单库存储量及性能瓶颈问题, 但由于同一个表被分配在不同的数据库中, 数据的访问需要额外的路由工作,因此系统的复杂度也被提升了。 ``` 切分前 A库 (A表,B表,C表,D表) 切分后 A_0库 (A表,B表,C表,D表) A_1库 (A表,B表,C表,D表) 可以根据表id进行取模,绝对数据存放到哪张表 ``` - 水平分表: 在同一个数据库内,把一张大数据量的表按一定规则, 切分成多个结构完全相同表,而每个表只存原表的一部分数据。 ``` 切分前 A库 (A表,B表) 切分后 A库 (A_1表,A_2表,B_1表,B_2表) ``` **优点** 1. 解决高并发时单库数据量过大的问题,提升系统稳定性和负载能力。 2. 业务系统改造的工作量不是很大。 **缺点** 1. 跨分片的事务一致性难以保证。 2. 跨库的join关联查询性能较差。 3. 扩容的难度和维护量较大,(拆分成几千张子表想想都恐怖) ## 分片策略 - 取模算法: 按字段取模(对hash结果取余数 (hash() mod N),N为数据库实例数或子表数量)是最为常见的一种切分方式。 **优点** 1. 数据分片相对比较均匀,不易出现请求都打到一个库上的情况。 **缺点** 1. 当某一台机器宕机,本应该落在该数据库的请求就无法得到正确的处理, 这时宕掉的实例会被踢出集群,此时算法变成hash(userId) mod N-1, 用户信息可能就不再在同一个库中了。 - 范围限定算法: 按照 时间区间 或 ID区间 来切分, 比如:我们切分的是用户表,可以定义每个库的 User 表里只存10000条数据, 第一个库只存 userId 从1 ~ 9999的数据,第二个库存 userId 为10000 ~ 20000, 第三个库存 userId 为 20001~ 30000......以此类推,按时间范围也是同理。 **优点** 1. 单表数据量是可控的 2. 水平扩展简单只需增加节点即可,无需对其他分片的数据进行迁移 3. 能快速定位要查询的数据在哪个库 **缺点** 1. 由于连续分片可能存在数据热点,比如按时间字段分片, 可能某一段时间内订单骤增,可能会被频繁的读写, 而有些分片存储的历史数据,则很少被查询。 ## 分库分表应用和问题 ### 应用 - 在数据库设计的时候考虑垂直分库和垂直分表 - 随着数据库业务的增加,不要马上考虑水平切分,首先考虑缓存处理、读写分离,添加 索引等方式,如果这些方式不能根本解决问题,再考虑做水平分库和水平分表 ### 分库分表问题 - 跨节点连接查询问题(分页、排序) - 多数据源管理问题 - 分布式事务: 分布式事务框架Seata - 分布式主键 ## 分库分表工具 - sharding-jdbc(当当) - TSharding(蘑菇街) - Atlas(奇虎360) - Cobar(阿里巴巴) - MyCAT(基于Cobar) - Oceanus(58同城) - Vitess(谷歌) ## ShardingSphere-JDBC简介 - 是轻量级的java框架,是增强版的JDBC驱动 - 主要目的是简化对分库分表之后数据的相关操作 ### 核心概念 - 分片 - 数据节点 - 逻辑表 - 真实表 - 分片键 - 分片算法 1. 精确分片算法(PreciseShardingAlgorithm): 用于单个字段 作为分片键,SQL中有 = 与 IN 等条件的分片, 需要在标准分片策略(StandardShardingStrategy )下使用 2. 范围分片算法(RangeShardingAlgorithm): 用于单个字段作为分片键,SQL中有 BETWEEN AND、>、 <、>=、<= 等条件的分片,需要在标准分片策略(StandardShardingStrategy ) 下使用。 3. Hint分片算法(HintShardingAlgorithm): 稍有不同,上边的算法中我们 都是解析SQL 语句提取分片键,并设置分片策略进行分片。 但有些时候我们并没有使用任何的分片键和分片策略, 可还想将 SQL 路由到目标数据库和表,就需要通过手动干预指定SQL 的目标数据库和表信息,这也叫强制路由。 - 分片策略 1. 标准分片策略: 标准分片策略适用于单分片键,此策略支持 PreciseShardingAlgorithm 和 RangeShardingAlgorithm 两个分片算法 其中 PreciseShardingAlgorithm 是必选的,用于处理 = 和 IN 的分片。 RangeShardingAlgorithm 是可选的,用于处理BETWEEN AND, >, <,>=,<= 条件分片,如果不配置RangeShardingAlgorithm, SQL中的条件等将按照全库路由处理 2. 复合分片策略: 同样支持对 SQL语句中的 =,>, <, >=, <=,IN和 BETWEEN AND 的分片操作。不同的是它支持多分片键, 具体分配片细节完全由应用开发者实现 3. 行表达式分片策略: 行表达式分片策略,支持对 SQL语句中的 = 和 IN 的分片操作, 但只支持单分片键。这种策略通常用于简单的分片, 不需要自定义分片算法,可以直接在配置文件中接着写规则。 4. Hint分片策略: 对应上边的Hint分片算法,通过指定分片健而非从 SQL中提取分片健的方式进行分片的策略。 - 分布式主键 1. ApacheShardingSphere 内置了UUID、SNOWFLAKE 两种分布式主键⽣成器, 默认使⽤雪花算法(snowflake)⽣成64bit的⻓整型数据。 不仅如此它还抽离出分布式主键⽣成器的接口,⽅便我们实现⾃定义的⾃增主 键⽣成算法 - 广播表: 存在于所有的分片数据源中的表,表结构和表中的数据在每个 数据库中均完全一致。一般是为字典表或者配置表 t_config, 某个表一旦被配置为广播表,只要修改某个数据库的广播表, 所有数据源中广播表的数据都会跟着同步。 - 绑定表: 那些分片规则一致的主表和子表。比如:t_order 订单表和 t_order_item 订单服务项目表, 都是按 order_id 字段分片,因此两张表互为绑定表关系 通常在我们的业务中都会使用 t_order 和 t_order_item 等表进行多表联合查询, 但由于分库分表以后这些表被拆分成N多个子表。 如果不配置绑定表关系,会出现笛卡尔积关联查询,将产生多条SQL, 配置绑定表关系后再进行关联查询时,只要对应表分片规则一致产生的数据就会落到同一个库中, 那么只需 t_order_0 和 t_order_item_0 表关联 ## ShardingSphere-JDBC实现水平分库 ## ShardingSphere-JDBC实现水平分表 ## ShardingSphere-JDBC实现垂直分库 ## ShardingSphere-JDBC操作公共表 ## ShardingSphere-JDBC读写分离