数据库-分区、分表、分库、分片

原创
2020/03/11 12:33
阅读数 736

以下文章纯属自己对网络文章的阅读后总结,如有问题欢迎指出。

众所周知,数据库往往最容易成为应用系统的瓶颈。随着系统用户的越俩越多,我们的数据库数据越来越大。随之而来的是单个表中数据太多,以至于查询速度越来越慢,而且由于表的锁机制(表锁定和行锁定)导致应用操作也受到严重影响,出现数据库性能瓶颈。当出现这种情况的时候我们就需要对数据库进行优化,所以就有了数据库分区、分表、分库、分片等。

一、数据库分区

分区是指根据一定规则,将数据库中的一张表分解成多个更小的,容易管理的部分。从逻辑上看,只有一张表,但是底层却是由多个物理分区组成。数据分割成多个块存放,这样我们查找一条数据时,就不用在全表中查找,只要知道这条数据在哪一个分区,然后在指定分区寻找就可以了。如果表的数据太大,可能一个磁盘放不下,我们可以把数据分配到不同的磁盘里面去。

两种分区方法

  • 水平分区(Horizontal Partitioning),这种形式分区是对表的行进行分区,所有在表中定义的列在每个数据集中都能找到,所以表的特性依然得以保持。
    举个简单的🌰:一个包含十年发票记录的表可以被分区为十个不同的分区,每个分区包含的是其中一年的记录,这样在sql语句中附带日期信息的时候就可以根据年份到指定的分区去找数据。
  • 垂直分区(Vertical Partitioning),这种分区方式一般来说是通过对表的垂直划分来减少目标表的宽度,使某些特定的列被划分到特定的分区,每个分区都包含了其中的列所对应的行。
    举个简单的🌰:一个包含了大 text 和 BLOB 列的表,这些 text 和 BLOB 列又不经常被访问,这时候就要把这些不经常使用的 text 和 BLOB 了划分到另一个分区,在保证它们数据相关性的同时还能提高访问速度

 

二、数据库分表

分表是将一个大表按照一定规则分解成多张具有独立存储空间的实体表,这些表可以分布在同一块磁盘上,也可以在不同的机器上。

两种分表方法

  • 垂直分表,在日常开发和设计中比较常见,通俗的说法叫做“大表拆小表”,拆分是基于关系型数据库中的“列”(字段)进行的。通常情况,某个表中的字段比较多,可以新建立一张“扩展表”,将不经常使用或者长度较大的字段拆分出去放到“扩展表”中。拆分字段的操作建议在数据库设计阶段就做好。如果是在发展过程中拆分,则需要改写以前的查询语句,会额外带来一定的成本和风险,建议谨慎。
    举个简单的🌰:客户信息相关的数据可以拆分成customer表和customer_ext两张表,将一些不常用的字段或者大字段放到customer_ext表当中。
  • 水平分表,也称为横向分表,比较容易理解,就是将表中不同的数据行按照一定规律分布到不同的数据库表中(这些表保存在同一个数据库中),这样来降低单表数据量,优化查询性能。最常见的方式就是通过主键或者时间等字段进行Hash和取模后拆分。
    举个简单的🌰:当订单表中的订单数据超过百万条时,查询性能可能会比较低,在来个联合查询可能死在那里了。这时如果将表拆分成10个小表同时查询,一定程度上可以缓解查询性能瓶颈。

 

三、数据库分库

分库是将一个数据库中大量的表,按照业务划分成多个模块放到多个数据库的技术。当数据库中数据量变大,并发程度高到一定程度的时候必然会达到数据库的I/O瓶颈。这时候就需要对数据库进行分库。

两种分库方法:

  • 垂直分库,在“微服务”盛行的今天已经非常普及了。基本的思路就是按照业务模块来划分出不同的数据库,而不是像早期一样将所有的数据表都放到同一个数据库中(这里可以理解为垂直分表),表存放在多个库中解决了垂直分表的数据库I/O瓶颈的问题。
    举个简单的🌰:CRM系统中可以将表按照业务模块分成 客户模块、订单模块、基础配置模块等,将对应模块的表存放在对应的数据库中。
  • 水平分库水平分库与上面讲到的水平分表的思想相同,唯一不同的就是将这些拆分出来的表保存在不同的数据库中。这也是很多大型互联网公司所选择的做法。
    举个简单的🌰:电商平台中的订单表每天都以上十万的量增加,很快就会达到数据库的I/O瓶颈,这个时候可以考虑将订单表水瓶切分,数据放到多个数据库中,来提高数据库读写效率。

 

四、数据库分片

任何看到显著增长的应用程序或网站,最终都需要进行扩展,以适应流量的增加。以确保数据安全性和完整性的方式进行扩展,对于数据驱动的应用程序和网站来说十分重要。人们可能很难预测某个网站或应用程序的流行程度,也很难预测这种流行程度会持续多久。所以有些机构会选择“可动态扩展的”数据库架构。也就是分片数据库。

分片方式:

数据分片一般都是使用Key或Key的哈希值来计算Key的分布。为了确保数据记录以正确的方式被放置在正确的分片中,哈希函数中输入的值都应该来自同一列。此列称为分片键。简单来说,分片键与主键类似,因为它们都是列,用于为各个行建立唯一标识符,详情参考

  • Key Based Sharding 基于键的分片,比如按照主键区间进行存放,或者按照主键取模进行存放。
  • Range Based Sharding 基于范围的分片,比如商品信息表,可以按照商品价格的区间进行分片。
  • Directory Based Sharding 基于目录的分片,根据分片键,到目录表中找到数据存放的分片信息。

分片解决问题

  1. 应用程序数据量增长到超过单个数据库节点的存储容量。
  2. 对数据库的读写量,超过单个节点或其只读副本可以处理的量,从而导致响应时间增加或超时。
  3. 应用程序所需的网络带宽,超过单个数据库节点和任何只读副本可用的带宽,从而导致响应时间增加或超时。

 

参考文章:

https://www.cnblogs.com/qcloud1001/p/10405281.html

https://blog.csdn.net/qq_28289405/article/details/80576614

https://www.cnblogs.com/cxxjohnson/p/9048518.html

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部