!!! 本文已参与「新人创作礼」活动,一起开启掘金创作之路。更多干货文章,可以访问 菜鸟厚非
什么是垂直分表
垂直分表则是代表将一张大表按“列”拆分为 2 张以上的小表,通过主外键关联来获取数据。
为什么需要垂直分表
一张表上百个字段,在很多年前做一些项目中,可能习以为常。应为以前项目的数据体量并大,怎样查都不会有太大的性能问题。
随着项目体量数据越来越大,尤其是在互联网大厂,查询等方面会有各方面的性能问题,所以现在必须进行拆分。
水平分表(扩展)
在进行垂直分表前,我们需要了解什么是水平分表。
水平分表是以行为单位对表进行拆分,每个表的结构都是一样的,解决的是数据量大的存储问题。例如:
-
Hash 法 通过定义算法,将数据存储与不同的分片库或表
-
范围法 存储日志,可以根据时间线或者ID进行顺序分片存储
案例分析
接下来通过案例分析为什么需要进行垂直分表
左边是未拆分的商品表里面存储了所有的字段。右边是拆分后的商品表分为基本信息、详情表。
接着,我们看查询情况。乍一看没有什么区别,甚至有点画蛇添足的味道,其实这要从数据库底层进行分析。
如下图所示,最基本的一行一行数据成为 row,管理数据的基本单位称之为 page,在 mysql 中每一页的大小都是固定的 16k ,保存 page 的单位成为 extent,默认情况情况下 extent 有 1M 的存储空间,也就是一个区可以装载 64 个连续的 page。
在 MySQL 中一个概念叫做压缩页,顾明思议可以对也得数据进行压缩,实际的数据存储会比逻辑存储的数据小、既然有压缩必然有解压缩,但是压缩解压缩效率并不算高,所以咋表设计时要确保在每一页存多存储行数据,这样就可以减少跨页检索。
假设有 1 亿条数据,一个商品的信息为 1k,接下来分别对两种情况进行分析
单表:在这种情况下,每页只能存储 16 行数据,1 亿数据需要 625 万页,这种数据的处理效率肯定不会太高
垂直拆分:假设商品的一些基本信息存储在小表 64 字节/行,描述等大字段信息存储与大表,那么小表存在只需 39 万页。这样拆分后的可以根据小表快速检索,分解 id 查询大字段信息,这样效率是非常高的。
假设根据商品标题进行查询,未走索引(未建立或着建立错误等情况),要想查询一个商品就需要扫描 625 万页,也就是全表扫描。这 625 万页是分布在物理磁盘的,而我们的物理磁盘又是有 IO 性能极限的,所以 625 万的扫描肯定是不会快的。
垂直拆分以后,可以看到只需要扫描 39 万页数据,而这个效率比未拆分的情况下快了 16 倍。在扫描到对于的商品后可以根据商品 ID 再到大表对商品详情信息进行提取。而这样一来一回就将扫描效率提高了几十倍。
所以,通过将重要字段单独剥离出一张小表,让每一页能够容纳更多的行,进而缩小数据扫描的范围,达到提高执行效率的目的,这就是垂直分表的依据所在。
垂直分表依据
垂直拆分有很多的好处,那么什么情况下需要垂直分表呢,主要有以下两种情况
- 单表数据量未来可能千万
- 字段超过20个,且包含了超长的 Varchar、CLOB、BLOB 等字段
注意,有些情况存储大字段也无需垂直分表: a. 日志表,有ID、时间、日志信息这个大字段,这种情况下分表是没有意义的, b. 数据少只有几千行
字段存放依据
小表
1 . 数据查询、排序时需要的字段,如分类编号、商户id、品牌编号、逻辑删除标志位等
2 . 高频访问的小字段,如商品名称、子标题、价格、厂商基本等
大表 1 . 低频访问字段:配送信息、售后声明、最后更新时间等
2 . 大字段:商品图文详情、图片BLOB、JSON元数据等
注意: a . 如果某些字段特别大,这种情况需要单独拆分表进行存储,应为这种情况对我们查询时底层扫描实在太大了