分表需要解决的问题 & 基于MyBatis 的轻量分表落地方案

分表:垂直拆分、水平拆分
垂直拆分:根据业务将一个表拆分为多个表。
如:将经常和不常访问的字段拆分至不同的表中。由于与业务关系密切,目前的分库分表产品均使用水平拆分方式。
水平拆分:根据分片算法将一个表拆分为多个表。
如:按照ID的最后一位以3取余,尾数是1的放入第1个库(表),尾数是2的放入第2个库(表)等。

解决的问题:单纯的分表可以解决数据量过大导致检索变慢的问题。

分表无法解决过多并发请求访问同一个库,导致数据库响应变慢的问题。所以通常水平拆分都至少要采用分库的方式,用于一并解决大数据量和高并发的问题。这也是部分开源的分片数据库中间件只支持分库的原因。

分表不可替代的场景:最常见的分表需求是事务问题。
同在一个库则不需考虑分布式事务,善于使用同库不同表可有效避免分布式事务带来的麻烦。目前强一致性的分布式事务由于性能问题,导致使用起来并不一定比不分库分表快。目前采用最终一致性的柔性事务居多。分表的另一个存在的理由是,过多的数据库实例不利于运维管理。

综上所述,最佳实践是合理地配合使用分库+分表。

https://blog.csdn.net/u4110122855/article/details/50670503

MyBatis轻量分表落地方案:

分表需要解决的问题:(基于MyBatis来说明)
1. SQL解析
2. SQL改写
3. SQL执行
4. 结果合并

1. SQL解析
SQL语法树解析,为SQL改写做准备

2. SQL改写
按分片规则将 SQL 进行改写。
做为一个中间件产品,需要屏蔽分表的细节,到底分了多少个表,对使用者来说应该是透明的。所以使用者写出的 SQL 中的表是一个虚拟的表。
例如:有表 user_0, user_1,分片规则是 id%2
使用者写出的insert 语句:insert into user(id, name) values(1, ‘张三‘)
那么中间件需要将 SQL 改写为:insert into user_1(id, name) values(1, ‘张三‘)

改写出的 SQL 可能不止一条,例如:select * from user where id in (1, 2)
改写后的 SQL 应该是:select * from user_0 where id in (1, 2)
select * from user_1 where id in (1, 2)

3. SQL执行
MyBatis执行 SQL 时,最后是通过 PreparedStatementHandler#instantiateStatement(Connection) 来获取 Statement 的。它会从 BoundSql里面取需要执行的 sql 语句。
通过跟代码发现, BoundSql 是从 MappedStatement 中取出来的。
所以,我们 SQL 执行时,可以通过 MyBatis 的拦截器拦截 MappedStatement (即:Executor的query、update方法),然后改写 MappedStatement#getBoundSql()就可以了。

4. 结果合并
由于 SQL 改写后,我们需要执行的 SQL 不只一条,所以,当 SQL 有多条时,我们就需要将 SQL 执行的结果集合并出最终的结果。

基于MyBatis 的轻量分表实现:https://gitee.com/kkk001/mybatis-shard

原文地址:https://www.cnblogs.com/kevin-yuan/p/9217537.html

时间: 2024-11-08 16:50:06

分表需要解决的问题 & 基于MyBatis 的轻量分表落地方案的相关文章

基于.Net + SqlServer的分库分表设计方案

在说分库分表之前,先简单介绍下网站架构,这样有助于理解为何需要分库分表这种技术.因为所有的技术,大多都是因为业务的需要而产生的. 1.网站发展的第一阶段 大致架构如下,因为没有多少用户访问,所以单台服务器都搞定所有的事情,上面跑着数据库.资源站点.以及所有的业务站点. 2.网站发展的第二阶段 这个时候访问量开始增加,发现服务器的资源不够用了,用户体验越来越差,所以,第一想法,升级服务器配置.ok,暂时解决了问题,站点又能提供稳定且高效的服务. 3.网站发展的第三阶段 访问量持续增加,这个时候升级

Sharding-Sphere 3.X 与spring与mybatis集成(分库分表)demo

最近在弄这个sharding-sphere,公司内部分库分表是在此业务代码上进行逻辑分库分表,但是这种总是不好,也调研了几款分库分表中间件.mycat.网易cetus.阿里DRDS.这几种就是背景强大,大公司经过大量的实战,成熟度很高,而框架sharding-sphere比较轻量级,最近比较火,它是以jar包形式提供服务,可以无缝连接ORM框架,并不需要额外的部署,不需要依赖,运维可以不需要改动,很多人都把sharding-sphere当成增强版的jdbc驱动,迁移代码其实没那么复杂.对于巨头公

记录一次MySQL两千万数据的大表优化解决过程,提供三种解决方案

问题概述 使用阿里云rds for MySQL数据库(就是MySQL5.6版本),有个用户上网记录表6个月的数据量近2000万,保留最近一年的数据量达到4000万,查询速度极慢,日常卡死.严重影响业务. 问题前提:老系统,当时设计系统的人大概是大学没毕业,表设计和sql语句写的不仅仅是垃圾,简直无法直视.原开发人员都已离职,到我来维护,这就是传说中的维护不了就跑路,然后我就是掉坑的那个!!! 我尝试解决该问题,so,有个这个日志. 方案概述 方案一:优化现有mysql数据库.优点:不影响现有业务

[simple-orm-mybaits]基于Mybatis的ORM封装介绍

目录 前言 ORM框架现状 Mybatis优缺点 simple-orm-mybatis设计思路介绍 simple-orm-mybatis使用说明 simple-orm-mybatis实际使用 推荐最佳实践 更多说明 simple-orm-mybatis在github开源,直接跳转查看,欢迎大家fork和star.有什么建议也可以提出,我会尽快修复或实现. 前言 最早接触Java的web开发框架就是SSH,其中的H就是Hibernate.Hibernate作为最出名的Java的ORM框架,现在的版

sql server解决无法删除修改拥有外键约束的表或表的记录字段

sql server解决无法删除修改拥有外键约束的表或表的记录字段 问题如下: or 解决步骤: 1.找出该表的所有外键约束 select * from sys.foreign_keys where referenced_object_id=object_id('订单') order by 1 2.删除所有外键约束(注意外键的名字和表的名字分别是哪个!) alter table 订货项目 drop constraint FK__订货项目__订单编号__412EB0B6; 到这就可以把表删掉了~

基于Mybatis的Dao层的开发

基于Mybatis的Dao层开发 SqlSessionFactoryBuilder用于创建SqlSessionFacoty,SqlSessionFacoty一旦创建完成就不需要SqlSessionFactoryBuilder了,因为SqlSession是通过SqlSessionFactory生产,所以可以将SqlSessionFactoryBuilder当成一个工具类使用,最佳使用范围是方法范围即方法体内局部变量. SqlSessionFactory是一个接口,接口中定义了openSession

水晶报表 Crystal Report 调用存储过程时出错 找不到表 ,解决方法。

用 CrystalReportViewer1 控件在asp.net的网页上显示报表,如果做报表时调用数据表数据的方式调用是可以成功的,但报表是用存储过程获取数据方式会出现以下错误: 找不到表'RptOpenCheck;1' . 文件 G:\TEMP\FO-OpenCheck {6D191F06-DECF-4A25-88FC-8553E3D435AA}.rpt 内出错: 找不到表. Error: 未将对象引用设置到对象的实例. The table 'RptOpenCheck;1' could no

基于动态分配的数组的顺序表(兼具Boost单元测试)

我们利用静态分配的数组来实现的顺序表的局限还是挺大的,主要在于它的容量是预先定好的,用户不能根据自己的需要来改变.如果为了后续用户能够自己调整顺序表的大小,动态地分配数组空间还是很有必要的.基于动态分配的数组的顺序表绝大部分跟基于静态分配的数组的顺序表是一样的,只需在后者程序上改动一小部分即可. 第一,我们不需定义一个容量常量CAPACITY,而是定义一个私有变量myCapacity. 第二,类的构造函数需要改进一下.我们需要类在被实例化时自动申请内存,即需添加下边程序: ElementType

hibernate 无法自动创建表 的解决办法

执行session.save() 时出现异常: org.hibernate.exception.SQLGrammarException: could not execute statement 无法创建表. 解决方法: 1)确定配置: <property name="hibernate.hbm2ddl.auto">update</property> 2)如果是mysql5的话,确定配置: <property name="hibernate.dia