绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
数据库究竟该怎么垂直拆?
2020-06-10 15:06:32
缘起上周,有网友问我说:
都知道业务垂直拆分,数据库要怎么垂直拆分呢?
今天,简单聊聊数据库垂直拆分。

什么是数据库水平切分,垂直拆分?
当数据库的数据量非常大时,水平切分垂直拆分都是常见的降低库空间,提升库性能的方法。

太抽象,能不能举个例子?
假设有用户表:

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)将字段较长,访问频率较低的属性尽量放在一个表里,这个表暂且称为扩展表;
(3)经常一起访问的属性,也可以放在一个表里;
画外音:优先考虑1和2。

另,如果属性过多,可以有多个扩展表。
画外音:一般来说,只有1个主表。
 
为何要将字段短,访问频率高的属性放到一个表内?
为何这么垂直拆分可以提升性能?
(1)数据库有自己的内存缓冲池,会将磁盘上的数据load到缓冲池里;
画外音:详见《数据库缓冲池,这次彻底懂了!》。
(2)数据库缓冲池以row为单位缓存数据
(3)在内存有限的情况下,在数据库缓冲池里缓存短row,就能缓存更多的数据
(4)在数据库缓冲池里缓存高频访问row,就能提升缓存命中率,减少磁盘的访问
 
能不能举个例子?
假设数据库缓冲池为1G,未拆分的user表1行数据大小为1k,那么只能缓存100w行数据。

如果垂直拆分成user_base和user_ext,其中:
(1)user_base访问频率高,一行大小为0.1k;
画外音:例如uid, name, passwd, 以及一些flag等。
(2)user_ext访问频率低,一行大小为0.9k;
画外音:例如签名, 个人介绍等。
那边缓冲池就就能缓存近乎1000w行user_base的记录,访问磁盘的概率会大大降低,数据库访问的时延会大大降低,吞吐量会大大增加。
 
总结
(1)水平拆分和垂直拆分都是降低数据量大小,提升数据库性能的常见手段;
(2)垂直拆分的依据,尽量把长度较短,访问频率较高的属性放在主表里;

分享好友

分享这个小栈给你的朋友们,一起进步吧。

架构师之路
创建时间:2019-12-19 10:54:22
架构师之路,沈剑和他的朋友们,聊聊职场,聊聊互联网,聊聊管理,聊聊架构,聊聊人生
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

栈主、嘉宾

查看更多
  • 58沈剑
    栈主
  • hwayw
    嘉宾
  • 唐川ITPUB
    嘉宾
  • 渔人
    嘉宾

小栈成员

查看更多
  • ?
  • 山中老狐狸
  • gaokeke123
  • 栈栈
戳我,来吐槽~