数据库 数据切分

1  何谓数据切分数据库

不管数据的 Sharding 仍是数据的切分,其实质都是同样的。简单来讲,就是指经过某种特定的条件,将存放在同一个数据库中的数据分散存放到多个数据库(主机)上面,以达到分散单台设备负载的效果。数据的切分同时还能够提升系统的整体可用性,由于单台设备 Crash 以后,只有整体数据的某部分不可用,而不是全部的数据。架构

数据的切分(Sharding)根据其切分规则的类型,能够分为两种切分模式。一种是按照不一样的表(或者 Schema)来切分到不一样的数据库(主机)之上,这种切分能够称之为数据的垂直(纵向)切分;另一种则是根据表中数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上,这种切分称之为数据的水平(横向)切分。ide

垂直切分的最大特色就是规则简单,实施也更为方便,尤为适合各业务之间的耦合度很是低、相互影响很小、业务逻辑很是清晰的系统。在这种系统中,能够很容易作到将不一样业务模块所使用的表分拆到不一样的数据库中。根据不一样的表来进行拆分,对应用程序的影响也更小,拆分规则也会比较简单清晰。模块化

水平切分与垂直切分相比,稍微复杂一些。由于要将同一个表中的不一样数据拆分到不一样的数据库中,对于应用程序来讲,拆分规则自己就较根据表名来拆分更为复杂,后期的数据维护也会更复杂。post

当某个(或者某些)表的数据量和访问量特别大,经过垂直切分将其放在独立的设备上后仍然没法知足性能要求时,就必须将垂直切分和水平切分相结合,先垂直切分,而后再水平切分,这样才能解决这种超大型表的性能问题。性能

下面就针对垂直、水平及组合切分这三种数据切分方式的架构实现及切分后数据的整合进行相应的分析。网站

2  数据的垂直切分spa

咱们先来看一下,数据的垂直切分究竟是如何切分的。数据的垂直切分,也能够称为纵向切分。将数据库想象成由不少个一大块一大块的"数据块"(表)组成,垂直地将这些"数据块"切开,而后把它们分散到多台数据库主机上面。这样的切分方法就是垂直(纵向)的数据切分。架构设计

一个架构设计较好的应用系统,其整体功能确定是由不少个功能模块所组成的,而每个功能模块所须要的数据对应到数据库中就是一个或多个表。而在架构设计中,各个功能模块相互之间的交互点越统1、越少,系统的耦合度就越低,系统各个模块的维护性及扩展性也就越好。这样的系统,实现数据的垂直切分也就越容易。设计

功能模块越清晰,耦合度越低,数据垂直切分的规则定义也就越容易。彻底能够根据功能模块来进行数据的切分,不一样功能模块的数据存放于不一样的数据库主机中,能够很容易就避免跨数据库的 Join 存在,同时系统架构也很是清晰。

固然,很难有系统可以作到全部功能模块使用的表彻底独立,根本不需要访问对方的表,或者需要将两个模块的表进行 Join 操做。这种状况下,就必须根据实际的应用场景进行评估权衡。决定是迁就应用程序将须要 Join 的表的相关模块都存放在同一个数据库中,仍是让应用程序作更多的事情--彻底经过模块接口取得不一样数据库中的数据,而后在程序中完成 Join 操做。

通常来讲,若是是一个负载相对不大,并且表关联又很是频繁的系统,那可能数据库让步,将几个相关模块合并在一块儿,减小应用程序工做的方案能够减小较多的工做量,是一个可行的方案。

固然,经过数据库的让步,让多个模块集中共用数据源,实际上也是间接默许了各模块架构耦合度增大的发展,可能会恶化之后的架构。尤为是当发展到必定阶段,发现数据库实在没法承担这些表所带来的压力,不得不面临再次切分时,所带来的架构改形成本可能远远大于最初就使用切分的架构设计。

因此,在数据库进行垂直切分的时候,如何切分、切分到什么样的程度,是一个比较考验人的难题。这只能在实际的应用场景中经过平衡各方面的成本和收益,才能分析出一个真正适合本身的拆分方案。

好比在本书所使用的示例系统的 example 数据库中,咱们简单分析一下,而后设计一个简单的切分规则,进行一次垂直拆分。

系统功能基本能够分为4个功能模块:用户、群组消息、相册以及事件,分别对应为以下这些表:

(1)用户模块表:user,user_profile,user_group,user_photo_album

(2)群组讨论表:groups,group_message,group_message_content,top_message

(3)相册相关表:photo,photo_album,photo_album_relation,photo_comment

(4)事件信息表:event

初略一看,没有哪一个模块能够脱离其余模块独立存在,模块与模块之间都存在着关系,莫非没法切分?

固然不是,再稍微深刻分析一下,能够发现,虽然各个模块所使用的表之间都有关联,可是关联关系还算清晰,也比较简单。

群组讨论模块和用户模块之间主要存在经过用户或群组关系来进行关联。通常都会经过用户的 id 或 nick_name 及 group 的 id 来进行关联,经过模块之间的接口实现不会带来太多麻烦。

相册模块仅仅与用户模块存在用户的关联。这两个模块之间的关联基本只有经过用户 id 关联的内容,简单清晰,接口明确。

事件模块与各个模块可能都有关联,可是都只关注其各个模块中对象的ID信息,一样比较容易分拆。
因此,第一步能够将数据库按照功能模块相关的表进行一次垂直拆分,每一个模块所涉及的表单独分到一个数据库中,模块与模块之间的表关联在应用系统端都经过接口来处理。如数据垂直切分示意图(图14-1)所示:

 
(点击查看大图)图14-1  垂直切分示意

经过这样的垂直切分以后,以前只能经过一个数据库来提供的服务,就被分拆成4个数据库来提供服务,服务能力天然是增长几倍了。

垂直切分的优势:

数据库的拆分简单明了,拆分规则明确;

应用程序模块清晰明确,整合容易;

数据维护方便易行,容易定位。

垂直切分的缺点:

部分表关联没法在数据库级别完成,要在程序中完成;

对于访问极其频繁且数据量超大的表仍然存在性能瓶颈,不必定能知足要求;

事务处理相对复杂;

切分达到必定程度以后,扩展性会受到限制;

过分切分可能会带来系统过于复杂而难以维护。

针对于垂直切分可能遇到数据切分及事务问题,在数据库层面实在是很难找到一个较好的处理方案。实际应用案例中,数据库的垂直切分大可能是与应用系统的模块相对应的,同一个模块的数据源存放于同一个数据库中,能够解决模块内部的数据关联问题。而模块与模块之间,则经过应用程序以服务接口的方式来相互提供所须要的数据。虽然这样作在数据库的整体操做次数方面确实会有所增长,可是在系统总体扩展性及架构模块化方面,都是有益的。可能某些操做的单次响应的时间会稍有增长,可是系统的总体性能极可能反而会有必定的提高。而扩展瓶颈问题,就只能依靠下一节将要介绍的数据水平切分架构来解决了。

3  数据的水平切分

数据的垂直切分基本上能够简单地理解为按照表或模块来切分数据,而水平切分则不一样。通常来讲,简单的水平切分主要是将某个访问极其平凡的表再按照某个字段的某种规则分散到多个表中,每一个表包含一部分数据。

简单来讲,能够将数据的水平切分理解为按照数据行的切分,就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其余的数据库中。固然,为了可以比较容易地断定各行数据被切分到哪一个数据库中了,切分老是需要按照某种特定的规则来进行的:如根据某个数字类型字段基于特定数目取模,某个时间类型字段的范围,或者某个字符类型字段的 hash 值。若是整个系统中大部分核心表均可以经过某个字段来进行关联,那这个字段天然是一个进行水平分区的上上之选了,固然,很是特殊没法使用的状况除外。

通常来讲,像如今很是火爆的 Web 2.0 类型网站,基本上大部分数据都可以经过会员用户信息关联上,可能不少核心表都很是适合经过会员 ID 来进行数据的水平切分。而像论坛社区讨论系统,就更容易切分了,能够按照论坛编号来进行水平切分。切分以后基本上不会出现各个库之间的交互。

若是示例系统的全部数据都是和用户关联的,那么就能够根据用户来进行水平拆分,将不一样用户的数据切分到不一样的数据库中。固然,惟一区别是用户模块中的 groups 表和用户没有直接关系,因此 groups 不能根据用户来进行水平拆分。对于这种特殊状况下的表,彻底能够独立出来,放在一个独立的数据库中。其实这个作法能够说是利用了前面一节所介绍的"数据的垂直切分"方法,将在下一节中更为详细地介绍这种垂直切分与水平切分同时使用的联合切分方法。

因此,对于示例数据库来讲,大部分的表均可以根据用户 ID 来进行水平切分。不一样用户相关的数据进行切分以后存放在不一样的数据库中。如将全部用户 ID 经过被2 取模而后分别存放于两个不一样的数据库中。每一个和用户 ID 关联上的表均可以这样切分。这样,基本上每一个用户相关的数据,都在同一个数据库中,即便需要关联,也很是容易实现。

能够经过水平切分示意图(图14-2)更为直观地展现水平切分相关信息:

 
(点击查看大图)图14-2

水平切分的优势:

表关联基本可以在数据库端所有完成;

不会存在某些超大型数据量和高负载的表遇到瓶颈的问题;

应用程序端总体架构改动相对较少;

事务处理相对简单;

只要切分规则可以定义好,基本上较难遇到扩展性限制。

水平切分的缺点:

切分规则相对复杂,很难抽象出一个可以知足整个数据库的切分规则;

后期数据的维护难度有所增长,人为手工定位数据更困难;

应用系统各模块耦合度较高,可能会对后面数据的迁移拆分形成必定的困难。

相关文章
相关标签/搜索