为什么要做垂直拆分?
一 原因
先来看如下这张表,银行的一张表,具有上百个字段
什么是垂直拆分?
垂直拆分就是指将一张表的字段按列,存储为2个及以上的表。
如下展示就是垂直拆分:
将商品表根据业务属性拆分为商品表,基本信息以及详情表。
我们来看看拆分前后的sql:
#调整前
SELECT * FROM 商品表 WHERE 商品标题='AD钙奶';
#调整后
SELECT * FROM 商品基本信息表 a,商品详情表 b WHERE a.商品id=b.商品id and a.商品标题='AD钙奶';
以前明明一条sql就能写完的东西,为什么要拆分后还需要通过主键关联来查询?这就不得不从innodb的底层讲起:
我们来看一张图:
如图所示,mysql最基本的数据(行),被称为row,管理数据的基本单位被称为页(page),原因就从这里讲起,mysql默认的页大小都是16k,而mysql保存页的单位被称为区(extent),默认情况一个区有1m的存储空间,即64个连续的页,innodb 1.0之后,存在新的概念压缩页,即采用一定算法,使页能存储比预计更多的数据,既然有压缩,那么就涉及到解压缩,原因就在这里诞生,如果说我进行压缩的数据在一页,但是我解压缩之后垮页了,那么我的检索效率必然下降,因为检索的次数变多了,所以我门要在业务允许的情况下,尽可能的让一页能存放更多的row,所以我们应该选择将一些大数据的字段提取到另外一张表里边。
实际计算: 如果说在做拆分之前,我们一行有1kb,如果有一亿条数据,那么就需要625万页,如果我们将频繁检索的热门检索的数据提取出来成小表,即商品的sku,spu等信息,假设只有64byte,那么我们存储一亿条数据只需要39万行,检索效率将大大提升。
再来看拆分前后的检索过程,如果不拆分,我们在得到一条数据的前提下,如果是模糊查询或者由于一些原因没有走索引,我们需要全表扫描625万页,即在磁盘的,效率非常恐怖,但是如果做了大小表拆分,即我们根据小表拿到id,只需要39万页的检索,然后根据id去匹配大表,效率的提升非常明显,如下图:
基于以上的原因,我们可以得出几点初步的分表习惯:
- 单表未来可能超过千万级数据
- 字段超多,且包含一些超长的varchar,clob,blob数据。
- 关联性不太强,例如三个字段就是需要同时存在才有用,那就看情况,一般没必要做分表
那么,哪些字段应该做拆分呢?
- 数据查询、排序时需要的字段,如分类编号、商户id、品牌编号、逻辑删除标志位等
- 高频访问的小字段,如商品名称、子标题、价格、厂商基本等
哪些不该做拆分呢?
- 低频访问字段:配送信息、售后声明、最后更新时间等
- 大字段:商品图文详情、图片BLOB、JSON元数据等