事务降维的几种策略

这是学习笔记的第 1935 篇文章


  我们在工作中很容易陷入一个漩涡,那就是因为并发事务选择了关系型数据库,因为关系型选择了MySQL,因为MySQL的业务特点而选择了对事务降维。 

 在大多数场景下算是一件好事说明我们对于事务的理解算是理性的,除此之外,我认为我们传统理解上的业务类型就不是非常合理,很多需求如果是基于OLTP和OLAP其实业务场景是很受限的,比如一个论坛业务,你说对事务的要求高吗 对于一些日志型,监控型数据的写入,使用事务也不大有用,而同时它们也不属于OLAP的业务场景。 

 简而言之,不是所有的业务场景需要事务支持,需要根据场景进行方案选择。

我总结了下面的一些降维策略,供参考。

降维策略1:存储过程调用转换为透明的SQL调用

对于新业务而言,使用存储过程显然不是一个好主意,MySQL的存储过程和其他商业数据库相比,功能和性能都有待验证,而且在现在轻量化的业务处理中,存储过程的处理方式太“重”了。

有些应用架构看起来是按照分布式部署的,在数据库层的调用方式是基于存储过程,因为存储过程的调用中内部来保证事务,看起来设计很清晰,但是这样压力都在数据库层面了,以至于数据库层很容易成为瓶颈,而且难以实现真正的分布式。

所以有一个明确的改进方向就是对于存储过程的改造,把它改造为SQL调用的方式,可以极大的提高业务的处理效率,在数据库的接口调用上足够简单而且清晰可控。

降维策略2:Drop 操作转换为可逆的DDL操作

Drop操作是默认提交的,而且是不可逆的,在数据库操作中都是跑路的代名词,MySQL层面目前是没有相应的drop操作恢复功能,除非通过备份来恢复,但是我们可以考虑将Drop操作转换为一种可逆的DDL操作。

在MySQL中默认是每个表有一个对应的ibd文件,其实可以把drop操作转换为一个rename操作,即可把文件从testdb迁移到testdb_arch下面,从权限上来说,testdb_arch是业务不可见的,rename操作可以平滑的实现这个删除功能,如果在一定时间后确认可以清理,则数据清理对于已有的业务流程是不可见的。

640?wx_fmt=png

降维策略3:Truncate操作转换为安全的DDL操作

Truncate操作的危害比Drop还要大,我们在第2种策略的基础上可以把truncate操作转换为一种较为安全的操作,思路也是通过rename的方式来实现,唯一的差别是这种方式需要额外处理表结构信息。

降维策略4:DDL操作转换为DML操作

有些业务经常会有一种紧急需求,总是需要给一个表添加字段,搞得DBA和业务同学都挺累,可以想象一个表有上百个字段,而且基本都是name1,name2....name100,这种设计本身就是有问题的,更不用考虑性能了。 究其原因,是因为业务的需求动态变化,比如一个游戏装备有20个属性,可能过了一个月之后就增加到了40个属性,这样一来,所有的装备都有40个属性,不管用没用到,而且这种方式也存在诸多的冗余。

我们在设计规范里面也提到了一些设计的基本要素,在这些基础上需要补充的是,在保持有限的字段,如果要实现这些功能的扩展,其实完全可以通过配置化的方式来实现,比如把一些动态添加的字段转换为一些配置信息。配置信息可以通过DML的方式进行修改和补充,对于数据入口也可以更加动态易扩展。


降维策略5:Delete操作转换为高效操作

有些业务需要定期来清理一些周期性数据,比如表里的数据只保留一个月,那么超出时间范围的数据就要清理掉了,而如果表的量级比较大的情况下,这种delete操作的代价实在太高,我们可以有两类解决方案来把Delete操作转换为更为高效的方式。 

第一种是根据业务建立周期表,比如按照月表,周表,日表等维度来设计,这样数据的清理就是一个相对可控而且高效的方式了。 

第二种方案是使用策略2的思路,比如一张2千万的大表要清理99%的数据,那么保留的1%的数据我们可以很快根据条件过滤补录,我们完全可以实现“移形换位”的方式。

降维策略6:Update操作转换为Insert操作

有些业务中会有一种固定的数据模型,比如先根据id查看记录是否存在,如果不存在则进行insert操作,如果存在则进行update操作,如果不加事务,在高并发的情况下很可能会因为重复的insert操作导致主键冲突的错误,我们可以使用insert on duplicate的方式来平滑的过渡,如果记录存在则进行update操作,但是语句接口都是insert,这样就可以把insert,update的操作模型统一为insert模型。




640?


猜你喜欢

转载自blog.csdn.net/weixin_36250635/article/details/88968988