登录 |  注册
首页 >  数据库 · 存储 >  MySql实战精选笔记 >  什么是数据库水平切分,垂直拆分

什么是数据库水平切分,垂直拆分

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

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. 垂直拆分的依据,尽量把长度较短,访问频率较高的属性放在主表里

上一篇: 面试: 为什么 MySQL 索引要使用 B+树而不是B 树?
下一篇: 性别字段为什么不适合加索引
推荐文章
  • mysql只支持一种join算法:Nested-LoopJoin(嵌套循环连接),但Nested-LoopJoin有三种变种:SimpleNested-LoopJoin,IndexNested-LoopJoin,BlockNested-LoopJoin(简单-索引-缓冲区)原理:1.SimpleNe
  • redis是一个内存数据库,一旦断电或服务器进程退出,内存数据库中的数据将全部丢失,所以需要redis持久化 redis持久化就是把数据保存在磁盘上,利用永久性存储介质将数据保存,在特定的时间将保存的数据进行恢复的工作机制redis提供两种持久化机制RDB:存储数据结果,关注点在数据AOF:存储操作
  • 通过SQL的执行过程来介绍MySQL的基础结构.     首先有一个user_info表,表里有一个id字段,执行下面这条查询语句:Select * form user_info where i
  • 索引(Index)是帮助MySQL高效获取数据的数据结构,索引的目的在于提高查询效率,就像字典和书籍的目录一样,有了目录,可以帮助你快速查找你需要的内容。可以理解为一个排好序的快速查找数据结构。也就是
  • 说到数据库事务,大家脑子里一定很容易蹦出一堆事务的相关知识,如事务的ACID特性,隔离级别,解决的问题(脏读,不可重复读,幻读)等等,但是可能很少有人真正的清楚事务的这些特性又是怎么实现的,为什么要有四个隔离级别。今天我们就先来聊聊MySQL中事务的隔离性的实现原理,后续还会继续出文章分析其他特性的
  • 前面我们系统了解了一个查询语句的执行流程,并介绍了执行过程中涉及的处理模块。相信你还记得,一条查询语句的执行过程一般是经过连接器、分析器、优化器、执行器等功能模块,最后到达存储引擎。那么,一条更新语句
学习大纲