zoukankan      html  css  js  c++  java
  • 一分钟掌握数据库垂直拆分

    一、缘起

    当数据库的数据量非常大时,水平切分垂直拆分是两种常见的降低数据库大小,提升性能的方法。假设有用户表:

    user(

    uid bigint,

    name varchar(16),

    pass varchar(16),

    age int,

    sex tinyint,

    flag tinyint,

    sign varchar(64),

    intro varchar(256)

    …);

    水平切分是指,以某个字段为依据(例如uid),按照一定规则(例如取模),将一个库(表)上的数据拆分到多个库(表)上,以降低单库(表)大小,达到提升性能的目的的方法,水平切分后,各个库(表)的特点是:

    1)每个库(表)的结构都一样

    2)每个库(表)的数据都不一样,没有交集

    3)所有库(表)的并集是全量数据

     

    二、什么是垂直拆分

    垂直拆分是指,将一个属性较多,一行数据较大的表,将不同的属性拆分到不同的表中,以降低单库(表)大小,达到提升性能的目的的方法,垂直切分后,各个库(表)的特点是:

    1)每个库(表)的结构都不一样

    2)一般来说,每个库(表)的属性至少有一列交集,一般是主键

    3)所有库(表)的并集是全量数据

    还是以上文提到的用户表为例,如果要垂直拆分,可能拆分结果会是这样的:

    user_base(

    uid bigint,

    name varchar(16),

    pass varchar(16),

    age int,

    sex tinyint,

    flag tinyint,

    …);

    user_ext(

    uid bigint,

    sign varchar(64),

    intro varchar(256)

    …);

    三、垂直切分的依据是什么

    当一个表属性很多时,如何来进行垂直拆分呢?如果没有特殊情况,拆分依据主要有几点:

    1)将长度较短,访问频率较高的属性尽量放在一个表里,这个表暂且称为主表

    2)将字段较长,访问频率较低的属性尽量放在一个表里,这个表暂且称为扩展表

    如果1和2都满足,还可以考虑第三点:

    3)经常一起访问的属性,也可以放在一个表里

    优先考虑1和2,第3点不是必须。另,如果实在属性过多,主表和扩展表都可以有多个。

    一般来说,数据量并发量比较大时,数据库的上层都会有一个服务层。需要注意的是,当应用方需要同时访问主表和扩展表中的属性时,服务层不要使用join来连表访问,而应该分两次进行查询

    原因是,大数据高并发互联网场景下,一般来说,吞吐量和扩展性是主要矛盾:

    1)join更消损耗数据库性能

    2)join会让base表和ext表耦合在一起(必须在一个数据库实例上),不利于数据量大时拆分到不同的数据库实例上(机器上)。毕竟减少数据量,提升性能才是垂直拆分的初衷。

    四、为什么要这么这么拆分

    为何要将字段短,访问频率高的属性放到一个表内?为何这么垂直拆分可以提升性能?因为:

    1)数据库有自己的内存buffer,会将磁盘上的数据load到内存buffer里(暂且理解为进程内缓存吧)

    2)内存buffer缓存数据是row为单位

    3)在内存有限的情况下,在数据库内存buffer里缓存短row,就能缓存更多的数据

    4)在数据库内存buffer里缓存访问频率高的row,就能提升缓存命中率,减少磁盘的访问

    举个例子就很好理解了:

    假设数据库内存buffer为1G,未拆分的user表1行数据大小为1k,那么只能缓存100w行数据。

    如果垂直拆分成user_baseuser_ext,其中:

    1)user_base访问频率高(例如uid, name, passwd, 以及一些flag等),一行大小为0.1k

    2)user_ext访问频率低(例如签名, 个人介绍等),一行大小为0.9k

    那边内存buffer就就能缓存近乎1000wuser_base的记录,访问磁盘的概率会大大降低,数据库访问的时延会大大降低,吞吐量会大大增加。

    五、总结

    1)水平拆分垂直拆分都是降低数据量大小,提升数据库性能的常见手段

    2)流量大,数据量大时,数据访问要有service层,并且service层不要通过join来获取主表和扩展表的属性

    3)垂直拆分的依据,尽量把长度较短,访问频率较高的属性放在主表里

    转自: 58沈剑 架构师之路

  • 相关阅读:
    IntelliJ IDEA 2018.3 升级功能介绍
    Spring 自动装配及其注解
    在IDEA中实战Git-branch
    IntelliJ IDEA 新版发布:支持CPU火焰图,新增酷炫主题
    java中URL和File的相互转化
    写一个函数,求一个字符串的长度,在main函数中输入字符串,并输出其长度
    输入一行字符,分别统计出其中英文 字母、空格、数字和其它字符的个数
    输入两个正整数m和n,求其最大公约数和最小公倍数。
    一个数如果恰好等于它的因子之和,这个数就称为 "完数 "
    判断101-200之间有多少个素数,并输出所有素数。
  • 原文地址:https://www.cnblogs.com/dsitn/p/7204482.html
Copyright © 2011-2022 走看看