标签:
这篇文章我思考了很久,也去查了很多资料,很想拿出点干货来给大家,接着上一篇来说,因为我们进行到这里,数据库已经实现了垂直拆分和水平拆分,已经是进入最为复杂的地方了。
其实说起来,相对于垂直拆分数据库来讲,读写分离式一种粗颗粒的拆分,而对于水平拆分来讲,垂直拆分又何尝不是粗颗粒呢,相对来讲读写分离相比垂直拆分要简单的多,而垂直拆分相较水平拆分同样简单的多。
从他们的实现方式就可以分析出来,从简单的拷贝库,到将大表单独拆分到一个库,再到讲大表拆分开放到不同的库,技术实现越来越复杂,就意味着我们要付出的成本要更多,我们设计系统都有一个原则:能通过简单的方式解决的绝对不用复杂的方案,当我们要用很复杂的方案的时候,那一定是迫不得已没办法了的事。
从事这个行业的时间虽然不是特别长,但也不短了,期间也遇到过很多这个行业的前辈,谈到数据库上,他们大多说的就是建模不要搞得太复杂,什么叫不复杂?表与表之间不要有约束,不要定义触发器,甚至就连读写分离做数据同步的时候都不能用触发器,不过存储过程可以写写,但绝不能写跟业务有关的逻辑,只能作为一些辅助工具来用。
从第一次听他们说的时候我的不理解,再到最后慢慢理解,最开始我只是觉得他们这样做,就是要将所有的业务逻辑都控制在系统中,避免后期维护困难。
但后来我渐渐的明白了,便于维护只是一方面,而另一方面则是因为,大量的触发器约束等需要数据库服务器进行大量计算的东西,都会严重的拖低数据库的性能,你可能会觉得这是他本身自己功能,如果我们不用,那他们就没有存在的意义了。
这么说吧,也许有些应用场景我们可以毫无顾忌的去用数据库的各种功能,但是在我们的大型网站中觉得不会这样,从另一个层面来讲,数据库系统本身跟我们要开发的系统没有区别,都是用来做存储和计算展示的。
然而现在在我们的整个系统中,数据库仅仅是做为我们系统存储数据而用的,对于大型网站来讲他单单是存储数据方面就已经压力很大了,我们还要让他处理一大堆我们系统本身可以处理的逻辑,这样完全是不顾她的死活啊。
所以说,从这个层面来讲,我们应该尽量简化数据库对运算等方面的性能浪费,让他能专心致志的做数据的存储。
OK,回到正题,那么我们的数据如果进行了垂直拆分和水平拆分之后,我们会遇到什么棘手的问题呢。
第一个问题:被拆出来的表要跟原有库进行关联查询的sql语句需要改变。
第二个问题:在做增删改的时候,某些被拆分出来的表要跟原有库的表来配合完成,这里就会出现事务的问题,如果一个搞不好,操作失败,事务无法回滚,这会对业务造成致命的危险。
那么解决第一个问题很简单:我们只需要以这些被拆分的表为原点,去逐个修改我们的sql,能拆的拆能合的合,而且,数据库也是可以实现跨库查询的,只是听说效率不怎么样。
第二个问题:这个问题有些复杂,因为涉及到多个库的事务,有些朋友可能想到分布式事务,没错,我们可以利用一些现在流行的分布式事务的解决方案,下面我列出了一些,但我都没有深入了解过,也不太清楚他们的原理。
一、X/OPEN组织推出的分布式事务规范XA,其中还包括该组织定义的分布式事务处理模型X/OPEN;
二、大型网站一致性理论CAP/BASE
三、 PAXOS协议。
那么除了使用这些通用的分布式事务解决方案,我们还能应用什么来解决这个问题呢,其实说分布式事务,这个名头太大,很多人都被他唬住了,这里我说下我的想法。
其实涉及到多个库的事务操作,无非就是状态没办法统一,在执行操作之前我们给他定义一个初始状态,如果在执行的过程中,任何一个步骤操作失败了,我们都把这个状态设置为失败,然后分别回滚其他几个已经执行过的操作。
这么说大家应该都能理解吧,但这么做无疑我们在代码中的改动就要复杂了,有可能这些改动会对我们原有的业务逻辑造成巨大的影响。
所以怎么办呢,我们服务端不能总是被数据库牵着鼻子走吧,数据变动,我们服务端代码就要跟着一票大改,这样有可能对业务产生无法预计的影响。
我是这样考虑的,我们可以在服务端和数据库中间加一层,叫做数据服务层,服务端不直接操作数据库,而是调用数据服务层的接口得到数据,而数据服务层返回服务端需要的数据就可以了。
这样,数据库变更我们只需要更改相应的数据服务层的逻辑代码就可以了,而返回的数据始终是不变的,因此就不会给服务层的业务产生影响,当服务端有什么新的数据需求,可以让数据服务层提供就可以了。
这样问题就解决了,当然了这里我介绍的是一个很简单的思路,在实施上肯定会有不少问题,毕竟我并没有实施过,只是总结了下见闻和自己的理解。
还是希望大家留下自己的见解,指正笔者的不足之处,共同学习共同进步。
标签:
原文地址:http://blog.csdn.net/sun5769675/article/details/50446377