科帮网-Java论坛、Java社区、JavaWeb毕业设计

登录/注册
您现在的位置:论坛 资料库 数据库开发 > 1分钟搞定数据库垂直拆分
总共47683条微博

动态微博

查看: 674|回复: 2

1分钟搞定数据库垂直拆分

[复制链接]

93

主题

3

听众

2127

金钱

版主

  • TA的每日心情
    郁闷
    2019-5-30 10:07
  • 签到天数: 12 天

    [LV.3]偶尔看看II

    优秀版主

    发表于 2017-01-12 17:38:26 |显示全部楼层

    一、缘起
    当数据库的数据量非常大时,水平切分垂直拆分是两种常见的降低数据库大小,提升性能的方法。假设有用户表:
    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_base和user_ext,其中:
    (1)user_base访问频率高(例如uid, name, passwd, 以及一些flag等),一行大小为0.1k
    (2)user_ext访问频率低(例如签名, 个人介绍等),一行大小为0.9k
    那边内存buffer就就能缓存近乎1000w行user_base的记录,访问磁盘的概率会大大降低,数据库访问的时延会大大降低,吞吐量会大大增加。
    五、总结
    (1)水平拆分垂直拆分都是降低数据量大小,提升数据库性能的常见手段
    (2)流量大,数据量大时,数据访问要有service层,并且service层不要通过join来获取主表和扩展表的属性
    (3)垂直拆分的依据,尽量把长度较短,访问频率较高的属性放在主表里


    科帮网-Java论坛、Java社区、JavaWeb毕业设计 1、本主题所有言论和图片纯属会员个人意见,与本社区立场无关
    2、本站所有主题由该帖子作者发表,该帖子作者与科帮网-Java论坛、Java社区、JavaWeb毕业设计享有帖子相关版权
    3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和科帮网-Java论坛、Java社区、JavaWeb毕业设计的同意
    4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
    5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
    6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
    7、科帮网-Java论坛、Java社区、JavaWeb毕业设计管理员和版主有权不事先通知发贴者而删除本文


    JAVA爱好者①群:JAVA爱好者① JAVA爱好者②群:JAVA爱好者② JAVA爱好者③ : JAVA爱好者③

    已有 1 人评分帮币 收起 理由
    admin + 5 那有一分钟 我读了好几分钟

    总评分:  帮币 + 5         查看全部评分

    admin    

    1221

    主题

    539

    听众

    1万

    金钱

    管理员

     成长值: 3750
  • TA的每日心情
    擦汗
    2019-10-18 17:39
  • 签到天数: 25 天

    [LV.4]偶尔看看III

    管理员

    发表于 2017-01-14 09:57:46 |显示全部楼层
    赏你了!!!
    来自苹果客户端来自苹果客户端
    回复

    使用道具 举报

    18

    主题

    0

    听众

    2680

    金钱

    七袋长老

    该用户从未签到

    发表于 2017-08-13 16:16:11 |显示全部楼层
    涨知识啦,谢谢分享
    来自安卓客户端来自安卓客户端
    回复

    使用道具 举报

    快速回复
    您需要登录后才可以回帖 登录 | 立即注册

       

    发布主题 快速回复 返回列表 联系我们 官方QQ群 科帮网手机客户端
    快速回复 返回顶部 返回列表