1.由来当数据库中的数据量非常大时,水平拆分和垂直拆分是两种常用的降低数据库规模和提高性能的方法。假设有一个用户表:user(uidbigint,namevarchar(16),passvarchar(16),ageint,sextinyint,flagtinyint,signvarchar(64),introvarchar(256)…);水平切分是指,基于某个字段(如uid),按照一定的规则(如取模),将一个库(表)上的数据切分为多个库(表),以减小单个库(表)的大小),该方法达到了提高性能的目的。横向切分后,各库(表)的特点是:(1)各库(表)的结构相同(2)各库(表)的数据不同,没有交集(3)的所有库(表)的并集就是数据的全量2.什么是垂直拆分垂直拆分是指将一个有很多属性的表和一行数据拆分成不同的属性,以减少单个库(表)的大小并达到提高性能的目的,垂直拆分后,每个库(表)的特点是:(1)每个库(表)的结构不同(2)一般来说,每个库(表)的属性有至少一个列交集,通常是主键。(3)所有库(表)的并集是全量数据吗?还是以上面提到的user表为例。拆分,可能拆分结果会是这样:user_base(uidbigint,namevarchar(16),passvarchar(16),ageint,sextinyint,flagtinyint,…);user_ext(uidbigint,signvarchar(64),介绍varchar(256)...);3.垂直切分的依据是什么当一张表的属性很多时,如何进行垂直切分?如果没有特殊情况,拆分主要有以下几点:(1)尽可能将长度较短、访问频率较高的属性放在一张表中。这张表暂且称为主表。(2)尽可能将字段较长、访问频率较低的属性放在一张表中。这张表称为为了扩表,如果1和2都满足,还可以考虑第三点:(3)经常一起访问的属性也可以放在一张表中,优先1和2,而第三点就没有必要了。另外,如果属性太多,可以有多个主表和扩展表。一般来说,当数据并发量比较大的时候,在数据库的上层会有一个服务层。需要注意的是,当应用端需要同时访问主表和扩展表中的属性时,服务层不应该使用join访问表,而是应该进行两次查询:原因是在大数据高并发的互联网场景,一般来说吞吐量和扩展性是主要的冲突:(1)join对数据库性能的消耗比较大(2)join会把basetable和exttable耦合在一起(必须在一个数据库实例上),这不利于大数据量的时间拆分到不同的数据库实例(在机器上)。毕竟减少数据量,提高性能才是垂直拆分的初衷。4、为什么要这样拆分?为什么要将访问频率高的短字段和属性放在一个表中?为什么这样的垂直拆分可以提高性能呢?因为:(1)数据库有自己的内存缓冲区,会把数据存放在磁盘上。数据加载到内存缓冲区(暂且理解为进程内缓存)(2)内存缓冲区缓存数据以行为单位(3)在内存有限的情况下,缓存一小行在数据库内存缓冲区,可以缓存更多的数据(4)将访问频率高的行缓存在数据库内存缓冲区中,可以提高缓存效率,减少磁盘访问。举个例子很容易理解:假设数据库内存缓冲区为1G,不拆分用户表一行数据大小为1k的话,只能缓存100w行数据。如果垂直拆分成user_base和user_ext,其中:(1)user_base访问频率高(如uid,name,passwd,还有一些flags等),一行大小为0.1k(2)user_ext有访问频率低(如签名、个人介绍等),0.9k行大小的内存缓冲区可以缓存近1000w行user_base记录,访问磁盘的概率会大大降低,数据库访问的延迟将大大减少,吞吐量将大大增加。5.小结(1)水平拆分和垂直拆分是降低数据规模,提高数据库性能的常用手段(2)当流量大,数据量大的时候,必须要有一个服务层来进行数据访问,并且服务层不要通过join来获取主表和扩展表的属性(3)垂直拆分的基础,尽量把长度较短、访问频率较高的属性放在主表中【这篇文章是专栏作者《58神剑》原创稿件,转载请联系原作者】
