分区:把一张表的数据分成N的区块,分散到N个物理区块存储,这些物理区块可以在同一磁盘上,也可以在不同的磁盘上
分表:将一张表按照一定规则分成N个具有独立存储空间的实体表。系统读写时需要根据定义好的规则得到对应的字表明。
分库
MySQL分区语句
CREATE TABLE sales (
id INT AUTO_INCREMENT,
amount DOUBLE NOT NULL,
order_day DATETIME NOT NULL,
PRIMARY KEY(id, order_day)
) ENGINE=Innodb
PARTITION BY RANGE(YEAR(order_day)) (
PARTITION p_2010 VALUES LESS THAN (2010),
PARTITION p_2011 VALUES LESS THAN (2011),
PARTITION p_2012 VALUES LESS THAN (2012),
PARTITION p_catchall VALUES LESS THAN MAXVALUE);
分区和分表
将整个数据库比作图书馆,一张表就是一本书。当要在一本书中查找某项内容时,如果不分章节,查找的效率将会下降。而同理,在数据库中就是分区。
分区解决的问题:
主要可以提升查询效率
分表解决的问题:
- 查询效率提高
- 数据分布在不同的文件,磁盘IO性能提高
- 读写锁影响的数据量变小
- 插入数据库需要重新建立索引的数据减少
分区与分表的区别于联系
- 分区和分表的目的都是减少数据库的负担,以提高表的CRUD效率
- 分区只是一张表中的数据的存储位置发生改变,分表则是将一张表分成多张表
- 当访问量大,且表数据比较多时,两种方式可以互相配合使用
- 当访问量不大,但表数据比较多时,可以值进行分区
分割方式
- 水平分割
- 垂直分割
水平分割
就是按照数据表行的拆分。支持大数据量,需要注意的是分表仅仅是解决了单一表数据过大的问题,但是表的数据还在同一台机器上,其实对于提升MySQL并发能力没有什么意义,所以水平拆分最好配合分区或者分库
水平拆分缺点:会给应用增加复杂度,通常在查询时需要多个表名,查询所有数据需要union操作。
常见场景:
- 电子商务网站,订单表数据量过大,按照年度、月度水平切分
- 网站注册用户、在线用户过多,按照用户id范围等方式,将相关用户以及该用户紧密关联的表做水平切分
- 论坛的指定帖子,因为涉及到分页问题,每页都需要显示置顶帖,这种情况可以把置顶帖水平切分开来,避免置顶时要从所有帖子的表中读取
垂直分割
按照数据表列的拆分,一般用于拆分大字段和访问率低的字段,分离冷热数据
有点:可以使得列数据变少,查询时减少读取的block数,减少io次数,并且简化表结构,易于维护
缺点:主键会出现冗余,并会引起join操作(可以通过在应用层join来解决)。此外,垂直分割会让事务变得更加复杂
常见场景:
- 大字段的垂直切分。单独将大字段建在另外的表中,提高基础表的访问性能,原则上在性能关键的应用中应该避免数据库的大数据
- 按照使用用途垂直切分。例如企业物料属性,可以按照基本属性、销售属性、采购属性、生产制造属性、财务会计属性等用途垂直切分
- 按照访问频率垂直切分。例如在电子商务系统中,如果用户属性设置非常多,可以将基本、使用频繁的属性和不常用的属性垂直切分开
常见分区分表的规则策略
- range
- hash
- 按照时间
- hash之后按照分表个数取模
- 在认证库中保存数据库配置,就是建立一个DB,这个DB单独保存user_id到DB的映射关系
分库
与分表策略类似,分库可以采用一个关键字取模的方式,对数据访问进行路由
分库分表存在的问题
1 事务问题。
在执行分库分表之后,由于数据存储到了不同的库上,数据库事务管理出现了困难。如果依赖数据库本身的分布式事务管理功能去执行事务,将付出高昂的性能代价;如果由应用程序去协助控制,形成程序逻辑上的事务,又会造成编程方面的负担。
2 跨库跨表的join问题。
在执行了分库分表之后,难以避免会将原本逻辑关联性很强的数据划分到不同的表、不同的库上,这时,表的关联操作将受到限制,我们无法join位于不同分库的表,也无法join分表粒度不同的表,结果原本一次查询能够完成的业务,可能需要多次查询才能完成。
3 额外的数据管理负担和数据运算压力。
额外的数据管理负担,最显而易见的就是数据的定位问题和数据的增删改查的重复执行问题,这些都可以通过应用程序解决,但必然引起额外的逻辑运算,例如,对于一个记录用户成绩的用户数据表userTable,业务要求查出成绩最好的100位,在进行分表之前,只需一个order by语句就可以搞定,但是在进行分表之后,将需要n个order by语句,分别查出每一个分表的前100名用户数据,然后再对这些数据进行合并计算,才能得出结果。