数据库分表和分库 一点积累
数据库分库分表一般是存储了百万级乃至千万级条记录的表。这样的表过于庞大,导致数据库在查询和插入的时候耗时太长,性能低下,如果涉及联合查询的情况,性能会更加糟糕。分表和表分区的目的就是减少数据库的负担,提高数据库的效率,通常点来讲就是提高表的增删改查效率。
什么是分表?
分表是将一个大表按照一定的规则分解成多张具有独立存储空间的实体表,我们可以称为子表,每个表都对应三个文件,MYD数据文件,.MYI索引文件,.frm表结构文件。这些子表可以分布在同一块磁盘上,也可以在不同的机器上。app读写的时候根据事先定义好的规则得到对应的子表名,然后去操作它。
什么是分区?
分区和分表相似,都是按照规则分解表。不同在于分表将大表分解为若干个独立的实体表,而分区是将数据分段划分在多个位置存放,可以是同一块磁盘也可以在不同的机器。分区后,表面上还是一张表,但数据散列到多个位置了。app读写的时候操作的还是大表名字,db自动去组织分区的数据。
MYISAM 分表方法,就是根据自增id的尾数来分,也就是说分0-9一共10个表,其取值也很好做,就是对10进行取模。另外,还可以根据某一字段的md5值取其中几位进行分表,这样的话,可以分的表就很多了。
(
)
MySQL的单表承载的数据量有限,一般在1000万以内,字段多一些还会更少,我们解决这种业务就需要对数据进行拆分,也叫sharding ,将一个表拆分多个表,或者多个数据库,分表逻辑分库差不多。
拆分需要考虑的数据和业务逻辑。按照用户维度、商品维度或订单维度等拆分。
拆分因子选择
因子选择,要看这个表所支撑的业务。
举例1、京东的京豆
京豆是属于用户维度的,我们的操作都是查询某个人的京豆,所以这个京豆库存流水信息就可以按照用户维度进行拆分,保证同一个人的京豆都存储在同一张表里面。
举例2、电商的商品信息
商品信息属于商家维度,我们一般都是进到一个店铺,查看这个店铺有哪些商品,商家查看自己的商品,所以这个商品信息就可以按照商家维度拆分,保证同一个商家的信息在同一表里面。
极端例子:订单表
订单表即属于商家,又属于用户,此时我们的选择是优先用户,可以按照用户维度进行拆分,其次通过冗余索引或冗余数据来为商户提供服务,比如创建一套商户维度的数据,然后商户维度数据采用异步非实时的机制进行同步数据。
拆分方法
如果你的业务是按照时间进行分表,每隔一段时间创建一个新表的话,就没有具体的拆分方式了,一定时间创建一个新表就可以了,但如果是有拆分因子,可以按照如下步骤考虑:
1、预估容量
预估该系统要支撑几年,大概的一个数据量,按照每个表1000w左右进行评估,如果未来5年可以达到1亿数据,那么拆分10张表即可,加上一定的上浮空间,一般用2的倍数,拆分成16张就够了。
2、考虑扩展性
如果我们16张表不够用的时候,该怎么办,那32张是否足够,如果提前做好扩展性。
实践
比如每个订单,都给用户发放一定的奖励金,我们要记录每次发放的奖励金信息,我们按照用户维度进行分表;
1、每天100w订单,也就100w条记录
2、系统支撑5年,5*365*100w 约等于 18.25亿
3、每张表最多存1000w数据,大约182张表
考虑到扩展性 我们准备最多分256张表(2的倍数)可以先拆分出16张表,随着业务扩展最多分256张。
考虑到扩展性 我们准备最多分256张表(2的倍数)可以先拆分出16张表,随着业务扩展最多分256张.
表的命名,user_001,user_016,user_032 ... user_240 累计16张表,选择等步长为了每个表之间可以做扩展
一致性Hash算法