CodeSnippet.Cn
代码片段
Csharp
架构设计
.NetCore
西班牙语
kubernetes
MySql
Redis
Algorithm
Other
Ubuntu
Linux
.NetMvc
VisualStudio
Python
Git
pm
WPF
java
Plug-In
分布式
CSS
微服务架构
JavaScript
DataStructure
Shared
数据库究竟该怎么垂直拆?
0
架构设计
MySql
小笨蛋
发布于:2021年06月06日
更新于:2021年06月06日
161
#custom-toc-container
> 缘起:都知道业务垂直拆分,数据库要怎么垂直拆分呢? 今天,简单聊聊数据库垂直拆分。 **什么是数据库水平切分,垂直拆分?** 当数据库的数据量非常大时,水平切分和垂直拆分都是常见的降低库空间,提升库性能的方法。 **太抽象,能不能举个例子?** 假设有用户表: ```sql 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)所有库(表)的**并集是全量数据**; 以上文提到的用户表为例,垂直拆分结果可能是这样的: ```sql 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)垂直拆分的依据,尽量把**长度较短,访问频率较高**的属性放在主表里;
这里⇓感觉得写点什么,要不显得有点空,但还没想好写什么...
返回顶部
About
京ICP备13038605号
© 代码片段 2025