分区、分表、分库、分片入门

一、分区的概念

数据分区是一种物理数据库的设计技术,它的目的是为了在特定的SQL操作中减少数据读写的总量以缩减响应时间。

分区并不是生成新的数据表,而是将表的数据均衡分摊到不同的硬盘,系统或是不同服务器存储介子中,实际上还是一张表。另外,分区可以做到将表的数据均衡到不同的地方,提高数据检索的效率,降低数据库的频繁IO压力值,分区的优点如下:

  • 1、相对于单个文件系统或是硬盘,分区可以存储更多的数据;
  • 2、数据管理比较方便,比如要清理或废弃某年的数据,就可以直接删除该日期的分区数据即可;
  • 3、精准定位分区查询数据,不需要全表扫描查询,大大提高数据检索效率;
  • 4、可跨多个分区磁盘查询,来提高查询的吞吐量;
  • 5、在涉及聚合函数查询时,可以很容易进行数据的合并;

二、分类 (row 行 ,column 列)

  • 1、水平分区

这种形式分区是对表的行进行分区,通过这样的方式不同分组里面的物理列分割的数据集得以组合,从而进行个体分割(单分区)或集体分割(1个或多个分区)。所有在表中定义的列在每个数据集中都能找到,所以表的特性依然得以保持。

举个简单例子:一个包含十年发票记录的表可以被分区为十个不同的分区,每个分区包含的是其中一年的记录。(朋奕注:这里具体使用的分区方式我们后面再说,可以先说一点,一定要通过某个属性列来分割,譬如这里使用的列就是年份)

  • 2、垂直分区

这种分区方式一般来说是通过对表的垂直划分来减少目标表的宽度,使某些特定的列被划分到特定的分区,每个分区都包含了其中的列所对应的行。

举个简单例子:一个包含了大text和BLOB列的表,这些text和BLOB列又不经常被访问,这时候就要把这些不经常使用的text和BLOB了划分到另一个分区,在保证它们数据相关性的同时还能提高访问速度。

在数据库供应商开始在他们的数据库引擎中建立分区(主要是水平分区)时,DBA和建模者必须设计好表的物理分区结构,不要保存冗余的数据(不同表中同时都包含父表中的数据)或相互联结成一个逻辑父对象(通常是视图)。这种做法会使水平分区的大部分功能失效,有时候也会对垂直分区产生影响。

三、分片、分区、分表、分库的详细理解

一、什么是分片、分区、分表、分库
  • 分片

当数据库数据达到上亿级别时,数据库压力会很大,存不下,可以考虑使用数据库分片。

  • 分区

就是把一张表的数据分成N个区块,在逻辑上看最终只是一张表,但底层是由N个物理区块组成的

  • 分表

就是把一张表按一定的规则分解成N个具有独立存储空间的实体表。系统读写时需要根据定义好的规则得到对应的字表明,然后操作它。

  • 分库

一旦分表,一个库中的表会越来越多

将整个数据库比作图书馆,一张表就是一本书。当要在一本书中查找某项内容时,如果不分章节,查找的效率将会下降。而同理,在数据库中就是分区。

常用的单机数据库的瓶颈
  • 问题描述
    • 单个表数据量越大,读写锁,插入操作重新建立索引效率越低。
    • 单个库数据量太大(一个数据库数据量到1T-2T就是极限)
    • 单个数据库服务器压力过大
    • 读写速度遇到瓶颈(并发量几百)

二、分片

不同的表放到不同的 数据库中—垂直切割。

数据量小,查询性能会提高。 不同数据库位于不同服务器上时,会减小服务器压力。

单张表数据量也很大,如用户量大产生操作量也会很大。单独查询时,压力也会很大。此时垂直分割也无济于事。可以考虑–水平分割。

一张表放到不同数据库中。用户表,放到不同数据库,每个数据库存储部分数据,单表数据量不大。

三、分区

什么时候考虑使用分区?
  • 一张表的查询速度已经慢到影响使用的时候。
  • sql经过优化
  • 数据量大
  • 表中的数据是分段的
  • 对数据的操作往往只涉及一部分数据,而不是所有的数据
分区解决的问题

​ 主要可以提升查询效率

分区的实现方式(简单)

mysql5 开始支持分区功能

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);

MySQL5.1提供的分区(Partition)功能确实可以实现表的分区,但是这种分区是局限在单个数据库范围里的,它不能跨越服务器的限制。

如果能够保证数据量很难超过现有数据库服务器的物理承载量,那么只需利用MySQL5.1提供的分区(Partition)功能来改善数据库性能即可;否则,还是考虑应用Sharding理念吧,spider storage engine就是一个不错的选择。

Sharding与数据库分区(Partition)的区别  

有的时候,Sharding 也被近似等同于水平分区(Horizontal Partitioning),网上很多地方也用水平分区来指代 Sharding,但我个人认为二者之间实际上还是有区别的。的确,Sharding 的思想是从分区的思想而来,但数据库分区基本上是数据对象级别的处理,比如表和索引的分区,每个子数据集上能够有不同的物理存储属性,还是单个数据库范围内的操作,而 Sharding 是能够跨数据库,甚至跨越物理机器的。

四、分表

什么时候考虑分表?
  • 一张表的查询速度已经慢到影响使用的时候。
  • sql经过优化
  • 数据量大
  • 当频繁插入或者联合查询时,速度变慢
分表解决的问题

分表后,单表的并发能力提高了,磁盘I/O性能也提高了,写操作效率提高了

  • 查询一次的时间短了
  • 数据分布在不同的文件,磁盘I/O性能提高
  • 读写锁影响的数据量变小
  • 插入数据库需要重新建立索引的数据减少
分表的实现方式(复杂)

​ 需要业务系统配合迁移升级,工作量较大

#####分区和分表的区别与联系

  • 分区和分表的目的都是减少数据库的负担,提高表的增删改查效率。
  • 分区只是一张表中的数据的存储位置发生改变,分表是将一张表分成多张表。
  • 当访问量大,且表数据比较大时,两种方式可以互相配合使用。
  • 当访问量不大,但表数据比较多时,可以只进行分区。
常见分区分表的规则策略(类似)
  • Range(范围)
  • Hash(哈希)
  • List(链表)
  • 按照时间拆分
  • Hash之后按照分表个数取模
  • 在认证库中保存数据库配置,就是建立一个DB,这个DB单独保存user_id到DB的映射关系

五、分库

什么时候考虑使用分库?
  • 单台DB的存储空间不够
  • 随着查询量的增加单台数据库服务器已经没办法支撑
分库解决的问题

​ 其主要目的是为突破单节点数据库服务器的 I/O 能力限制,解决数据库扩展性问题。

垂直拆分

将系统中不存在关联关系或者需要join的表可以放在不同的数据库不同的服务器中。

按照业务垂直划分。比如:可以按照业务分为资金、会员、订单三个数据库。

需要解决的问题:跨数据库的事务、jion查询等问题。

水平拆分

例如,大部分的站点。数据都是和用户有关,那么可以根据用户,将数据按照用户水平拆分。

按照规则划分,一般水平分库是在垂直分库之后的。比如每天处理的订单数量是海量的,可以按照一定的规则水平划分。需要解决的问题:数据路由、组装。

读写分离

对于时效性不高的数据,可以通过读写分离缓解数据库压力。需要解决的问题:在业务上区分哪些业务上是允许一定时间延迟的,以及数据同步问题。

思路

垂直分库–>水平分库–>读写分离

六、拆分之后面临新的问题

问题
  • 事务的支持,分库分表,就变成了分布式事务
  • join时跨库,跨表的问题
  • 分库分表,读写分离使用了分布式,分布式为了保证强一致性,必然带来延迟,导致性能降低,系统的复杂度变高。
常用的解决方案:

对于不同的方式之间没有严格的界限,特点不同,侧重点不同。需要根据实际情况,结合每种方式的特点来进行处理。

选用第三方的数据库中间件(Atlas,Mycat,TDDL,DRDS),同时业务系统需要配合数据存储的升级。

七、数据存储的演进

单库单表

单库单表是最常见的数据库设计,例如,有一张用户(user)表放在数据库db中,所有的用户都可以在db库中的user表中查到。

单库多表

随着用户数量的增加,user表的数据量会越来越大,当数据量达到一定程度的时候对user表的查询会渐渐的变慢,从而影响整个DB的性能。如果使用mysql, 还有一个更严重的问题是,当需要添加一列的时候,mysql会锁表,期间所有的读写操作只能等待。

可以通过某种方式将user进行水平的切分,产生两个表结构完全一样的user_0000,user_0001等表,user_0000 + user_0001 + …的数据刚好是一份完整的数据。

多库多表

随着数据量增加也许单台DB的存储空间不够,随着查询量的增加单台数据库服务器已经没办法支撑。这个时候可以再对数据库进行水平拆分。

八、总结

总的来说,优先考虑分区。当分区不能满足需求时,开始考虑分表,合理的分表对效率的提升会优于分区。

基础数据存储

Mysql:只存储非文本的基础信息。包括:评论状态,用户,时间等基础数据。以及图片,标签,点赞等附加信息。数据组织形式(不同的数据又可选择不同的库表拆分方案):

  • 评论基础数据按用户ID进行拆库并拆表
  • 图片及标签处于同一数据库下,根据商品编号分别进行拆表
  • 其它的扩展信息数据,因数据量不大、访问量不高,处理于同一库下且不做分表即可
文本存储

文本存储(评论的内容)使用了mongodb、hbase

  • 选择nosql而非mysql
  • 减轻了mysql存储压力,释放msyql,庞大的存储也有了可靠的保障
  • nosql的高性能读写大大提升了系统的吞吐量并降低了延迟
坚持原创技术分享,您的支持将鼓励我继续创作!