菜菜哥,上次听你给我讲了分库的状况后,我明白了不少,能再给我讲讲分表吗mysql
有收获就好,分表其实有不少状况和分库相似程序员
还有不同的状况吗?web
有呀,原本数据库和表是不一样层面的东西,确定有差别算法
那你给讲讲呗sql
讲能够,一杯coffee如何?数据库
为何分编程
在正式开始以前,菜菜仍是要强调一点,你的数据表是否应该分,须要综合考虑不少因素,好比业务的数据量是否到达了必需要切分的数量级,是否能够有其余方案来解决当前问题?我不止一次的见过,有的leader在不考虑综合状况下,盲目的进行表拆分业务,致使的状况就是你们不停的加班,连续几周996,难道leader你不掉头发吗?还有的架构师在一个小小业务初期就进行表拆分,你们为了配合你也是快马加鞭的加班赶进度,上线以后反而发现业务数据量很小,可是代码上却被分表策略牵制了太多。拆表引发的问题在特定的场景下,有时候代价真的很大。缓存
数据库表的拆分解决的问题主要是存储和性能问题,mysql在单表数据量达到必定量级后,性能会急剧降低,相比较于sqlserver和Oracle这些收费DB来讲,mysql在某些方面仍是处于弱势,可是表的拆分这个策略却适用于几乎全部的关系型数据库。架构
数据库进行表拆分不要太盲目并发
分表策略
表的拆分和数据库的拆分有类似之处,可是拆分的规则也有不一样。如下的拆分规则针对的是拆分一个表。
横向切分
横向切分是诸多业务中最经常使用的切分方式,本质是把一个表中的数据行按照规则分散到多个表中,好比最多见的按照ID范围,按照业务主键的哈希值等。至于表数据到达什么数量级以后进行切分,这和表中存的数据格式有关,好比一个表只有几列的int字段确定要比几列text类型的表存储的极限要高。姑且认为这个极限是1000万吧。可是做为一个系统的负责人或者架构师来讲,当表的数据量级到达千万级别要引发重视,由于这是一个系统性能瓶颈的隐患。
相对于数据表的横向切分,在符合业务优化的场景下我更倾向于作表分区,按照规则把不一样的分区分配到不一样的物理磁盘,这样的话,业务里的sql语句几乎能够不用改动。我司的一个sqlserver数据库,某个业务的表作了表分区以后,已经到达几十亿级别的数据量,可是查询和插入速度仍是能知足业务的需求(优化一个系统仍是要花精力优化业务层面)。
垂直切分
说到垂直拆分,表也能够按照业务来拆分,好比一个数据库中有用户的信息,根据业务能够划分为基础信息和扩展信息,若是对业务有利,彻底能够拆分为基础信息表和扩展信息表。固然也能够按照别的规则来拆,好比把访问频繁的信息拆分红一个表,其余不频繁的信息拆分红一个表,具体的拆分规则仍是要看当时要解决的问题是什么。垂直拆分可能会引入必定复杂性,好比原来查询一个用户的基础信息和扩展信息能够一次性查询出结果,分表以后须要进行Join操做或者查询两次才能查询出结果。
分表代价
1. 数据表垂直切分以后,原来一次查询有可能会变为连表的join查询,在必定程度上会有性能损失。
2. 数据表横向切分须要必定的规则,经常使用的主要有两种规则:范围切分和哈希值切分。范围切分是指按照某个字段的范围来切分,好比用户表按照用户ID来切分,id为1到10万的位于User表1中,100001到200000万的位于User2中,这样切分的优点是,能够无限的扩容下去,不用考虑数据迁移的问题,劣势就是新表和旧表数据分布不均匀,并且分表的范围选取有必定难度,范围过小会致使表太多,太大会致使问题根本上没有解决的困惑。另一种分表策略就是把某一列按照哈希值来路由到不一样的表中,一样以用户ID为例,假如咱们一开始就规划了10个数据库表,路由算法能够简单地用 user_id %10的值来表示数据所属的数据库表编号,ID为985的用户放到编号为 5的子表中,ID为10086的用户放到编号为 6 的字表中。这种切分规则的优点是每一个表的数据分布比较均匀,可是后期扩容会设计到部分数据的迁移工做。
3. 表拆分以后若是遇到有order by 的操做,数据库就无能为力了,只能由业务代码或者数据库中间件来完成了。
4. 当有搜索的业务需求的时候,sql语句只能是Join多个表来进行连表查询了,相似的还有统计的需求,例如count的统计操做。
你在业务中进行过表拆分吗?公众号回复“抽奖”,送书活动还在继续!!
架构师之路,菜菜与君一块儿成长
长按识别二维码关注