iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >Mysql数据库分库分表全面瓦解
  • 284
分享到

Mysql数据库分库分表全面瓦解

2024-04-02 19:04:59 284人浏览 泡泡鱼
摘要

目录1 为什么要分库分表2 垂直拆分(Scale Up 纵向扩展)2.1 垂直分库2.2 垂直分表 3 水平拆分(Scale Out 横向扩展) 3.1 库内分表

1 为什么要分库分表

物理服务机的CPU、内存、存储设备、连接数等资源有限,某个时段大量连接同时执行操作,会导致数据库在处理上遇到性能瓶颈。为了解决这个问题,行业先驱门充分发扬了分而治之的思想,对大库表进行分割,然后实施更好的控制和管理,同时使用多台机器的CPU、内存、存储,提供更好的性能。而分治有两种实现方式:垂直拆分和水平拆分。

2 垂直拆分(Scale Up 纵向扩展)

垂直拆分分为垂直分库和垂直分表,主要按功能模块拆分,以解决各个库或者各个表之间的资源竞争。比如分为订单库、商品库、用户库...这种方式,多个数据库之间的表结构是不同的。

2.1 垂直分库

先说说垂直分库。垂直分库其实是一种简单逻辑分割。比如我们的数据库中有商品表Products、还有对订单表Orders,还有积分表Scores。接下来我们就可以创建三个数据库,一个数据库存放商品,一个数据库存放订单,一个数据库存放积分。

垂直分库有一个优点,他能够根据业务场景进行孵化,比如某一单一场景只用到某2-3张表,基本上应用和数据库可以拆分出来做成相应的服务。拆分方式如下图所示:

2.2 垂直分表 

再来说说垂直分表,比较适用于那种字段比较多的表,假设我们一张表有100个字段,我们分析了一下当前业务执行的sql语句,有20个字段是经常使用的,而另外80个字段使用比较少。

这样我们就可以把20个字段放在主表里面,我们再创建一个辅助表,存放另外80个字段。当然主表和辅助表都是有主键的,他们通过主键进行关联合并,就可以组合成100个字段的表。拆分方式如下图所示。

除了这种访问频率的冷热拆分之外,还可以按照字段类型结构来拆分,比如大文本字段单独放在一个表中,与基础字段隔离,提高基础字段的访问效率。

也可以将字段按照功能用途来拆分,比如采购的物料表可以按照基本属性、销售属性、采购属性、生产制造属性、财务会计属性等用途垂直拆分。

总体来说:垂直拆分有以下优点:

  • 跟随业务进行分割,类似微服务的分治理念,方便解耦之后的管理及扩展。
  • 高并发的场景下,垂直拆分使用多台服务器的CPU、I/O、内存能提升性能,同时对单机数据库连接数、一些资源限制也得到了提升,能实现冷热数据的分离。

垂直拆分的缺点:

  • 部分业务表无法join,应用层需要很大的改造,只能通过聚合的方式来实现。增加了开发的难度。
  • 单表数据量膨胀的问题依然没有得到有效的解决。分布式事务也是一个难题。

3 水平拆分(Scale Out 横向扩展) 

水平拆分又分为库内分表和分库分表,来解决单表中数据量增长出现的压力,这些数据库中的表结构完全相同。

3.1 库内分表

先说说库内分表。假设当我们的Orders表达到了5000万行记录的时候,非常影响数据库的读写效率,怎么办呢?

我们可以考虑按照订单编号的order_id进行rang分区,就是把订单编号在1-1000万的放在order1表中,将编号在1000万-2000万的放在order2中,以此类推,每个表中存放1000万数据。

关于水平分表的时机,业内的标准不是很统一,阿里的Java 开发手册的标准是当单表行数超过 500万行或者单表容量超过 2 GB时,才推荐进行分库分表。百度的则是1000 W行的进行分表,这个是百度的DBA经过测试推算出的结果。

但是这边忽略了单表的字段数和字段类型,如果字段数很多,超过50列,对性能影响也是不小的,我们曾经有个业务,表字段是随着业务的增长而自动扩增的,到了后期,字段越来越多,查询性能也越来越慢。

所以个人觉得不必拘泥于500W 还是1000W,开发人员在使用过程中,如果压测发现因为数据基数变大而导致执行效率慢下来,就可以开始考虑分表了。

3.2 库内分表的实现策略

目前在Mysql中支持四种表分区的方式,分别为HASH、RANGE、LIST及KEY,当然在其它的类型数据库中,分区的实现方式略有不同,但是分区的思想原理是相同,具体如下:

3.2.1 HASH(哈希)

HASH分区主要用来确保数据在预先确定数目的分区中平均分布,而在RANGE和LIST分区中,必须明确指定一个给定的列值或列值集合应该保存在哪个分区中,而在HASH分区中,mysql自动完成这些工作,

你所要做的只是基于将要被哈希的列值指定一个列值或表达式,以及指定被分区的表将要被分割成的分区数量。 示例如下:

1 drop table if EXISTS  `t_userinfo`; 
 2 CREATE TABLE `t_userinfo` (
 3 `id` int(10) unsigned NOT NULL,
 4 `personcode` varchar(20) DEFAULT NULL,
 5 `personname` varchar(100) DEFAULT NULL,
 6 `depcode` varchar(100) DEFAULT NULL,
 7 `depname` varchar(500) DEFAULT NULL,
 8 `gwcode` int(11) DEFAULT NULL,
 9 `gwname` varchar(200) DEFAULT NULL,
10 `gravalue` varchar(20) DEFAULT NULL,
11 `createtime` DateTime NOT NULL
12 ) ENGINE=InnoDB DEFAULT CHARSET=utf8
13 PARTITioN BY HASH(YEAR(createtime))
14 PARTITIONS 10;

上面的例子,使用HASH函数对createtime日期进行HASH运算,并根据这个日期来分区数据,这里共分为10个分区。 

建表语句上添加一个“PARTITION BY HASH (expr)”子句,其中“expr”是一个返回整数的表达式,它可以是字段类型为MySQL 整型的一列的名字,也可以是返回非负数的表达式。

另外,可能需要在后面再添加一个“PARTITIONS num”子句,其中num 是一个非负的整数,它表示表将要被分割成分区的数量。 

3.2.2 RANGE(范围)

基于属于一个给定连续区间的列值,把多行分配给同一个分区,这些区间要连续且不能相互重叠,使用VALUES LESS THAN操作符来进行定义。示例如下:

1 drop table if EXISTS  `t_userinfo`; 
 2 CREATE TABLE `t_userinfo` (
 3 `id` int(10) unsigned NOT NULL,
 4 `personcode` varchar(20) DEFAULT NULL,
 5 `personname` varchar(100) DEFAULT NULL,
 6 `depcode` varchar(100) DEFAULT NULL,
 7 `depname` varchar(500) DEFAULT NULL,
 8 `gwcode` int(11) DEFAULT NULL,
 9 `gwname` varchar(200) DEFAULT NULL,
10 `gravalue` varchar(20) DEFAULT NULL,
11 `createtime` DateTime NOT NULL
12 ) ENGINE=InnoDB DEFAULT CHARSET=utf8
13 PARTITION BY RANGE(gwcode) (
14 PARTITION P0 VALUES LESS THAN(101) ,
15 PARTITION P1 VALUES LESS THAN(201) ,
16 PARTITION P2 VALUES LESS THAN(301) ,
17 PARTITION P3 VALUES LESS THAN MAXVALUE
18 );

上面的示例,使用了范围RANGE函数对岗位编号进行分区,共分为4个分区,

岗位编号为1~100 的对应在分区P0中,101~200的编号在分区P1中,依次类推即可。那么类别编号大于300,可以使用MAXVALUE来将大于300的数据统一存放在分区P3中即可。 

3.2.3 LIST(预定义列表)

类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择分区的。LIST分区通过使用“PARTITION BY LIST(expr)”来实现,其中“expr” 是某列值或一个基于某个列值、并返回一个整数值的表达式,

然后通过“VALUES IN (value_list)”的方式来定义每个分区,其中“value_list”是一个通过逗号分隔的整数列表。 示例如下:

1 drop table if EXISTS  `t_userinfo`; 
 2 CREATE TABLE `t_userinfo` (
 3 `id` int(10) unsigned NOT NULL,
 4 `personcode` varchar(20) DEFAULT NULL,
 5 `personname` varchar(100) DEFAULT NULL,
 6 `depcode` varchar(100) DEFAULT NULL,
 7 `depname` varchar(500) DEFAULT NULL,
 8 `gwcode` int(11) DEFAULT NULL,
 9 `gwname` varchar(200) DEFAULT NULL,
10 `gravalue` varchar(20) DEFAULT NULL,
11 `createtime` DateTime NOT NULL
12 ) ENGINE=InnoDB DEFAULT CHARSET=utf8
13 PARTITION BY LIST(`gwcode`) (
14 PARTITION P0 VALUES IN (46,77,89) ,
15 PARTITION P1 VALUES IN (106,125,177) ,
16 PARTITION P2 VALUES IN (205,219,289) ,
17 PARTITION P3 VALUES IN (302,317,458,509,610) 
18 );

上面的例子,使用了列表匹配LIST函数对员工岗位编号进行分区,共分为4个分区,编号为46,77,89的对应在分区P0中,106,125,177类别在分区P1中,依次类推即可。

不同于RANGE的是,LIST分区的数据必须匹配列表中的岗位编号才能进行分区,所以这种方式只是适合比较区间值确定并少量的情况。 

3.2.4 KEY(键值)

类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL 服务器提供其自身的哈希函数。必须有一列或多列包含整数值。 示例如下:

1 drop table if EXISTS  `t_userinfo`; 
 2 CREATE TABLE `t_userinfo` (
 3 `id` int(10) unsigned NOT NULL,
 4 `personcode` varchar(20) DEFAULT NULL,
 5 `personname` varchar(100) DEFAULT NULL,
 6 `depcode` varchar(100) DEFAULT NULL,
 7 `depname` varchar(500) DEFAULT NULL,
 8 `gwcode` int(11) DEFAULT NULL,
 9 `gwname` varchar(200) DEFAULT NULL,
10 `gravalue` varchar(20) DEFAULT NULL,
11 `createtime` DateTime NOT NULL
12 ) ENGINE=InnoDB DEFAULT CHARSET=utf8
13 PARTITION BY KEY(gwcode)
14 PARTITIONS 10;

注意:此种分区算法目前使用的比较少,使用服务器提供的哈希函数有不确定性,对于后期数据统计、整理存在会更复杂,所以我们更倾向于使用由我们定义表达式的Hash,大家知道其存在和怎么使用即可。 

3.2.5 Composite(复合模式)

Composite是上面几种模式的组合使用,比如你在Range的基础上,再进行Hash 哈希分区。

3.3 分库分表

库内分表解决了单表数据量过大的瓶颈问题,但使用还是同一主机的CPU、IO、内存,另外单库的连接数也有限制,并不能完全的降低系统的压力。

此时,我们就要考虑另外一种技术叫分库分表。分库分表在库内分表的基础上,将分的表挪动到不同的主机和数据库上。可以充分的使用其他主机的CPU、内存和IO资源。 拆分方式进一步演进到下面:

4 分库分表存在的问题

4.1 事务问题

在执行分库分表之后,由于数据存储到了不同的库上,数据库事务管理出现了困难。如果依赖数据库本身的分布式事务管理功能去执行事务,将付出高昂的性能代价;如果由应用程序去协助控制,形成程序逻辑上的事务,又会造成编程方面的负担。

4.2 跨库跨表的join问题

在执行了分库分表之后,难以避免会将原本逻辑关联性很强的数据划分到不同的表、不同的库上,这时,表的关联操作将受到限制,我们无法join位于不同分库的表,也无法join分表粒度不同的表,结果原本一次查询能够完成的业务,可能需要多次查询才能完成。 

4.3 额外的数据管理负担和数据运算压力

额外的数据管理负担,最显而易见的就是数据的定位问题和数据的增删改查的重复执行问题,这些都可以通过应用程序解决,但必然引起额外的逻辑运算,例如,对于一个记录用户成绩的用户数据表userTable,业务要求查出成绩最好的100位,在进行分表之前,

只需一个order by语句就可以搞定,但是在进行分表之后,将需要n个order by语句,分别查出每一个分表的前100名用户数据,然后再对这些数据进行合并计算,才能得出结果。

以上就是Mysql数据库分库分表全面瓦解的详细内容,更多关于Mysql分库分表的资料请关注编程网其它相关文章!

您可能感兴趣的文档:

--结束END--

本文标题: Mysql数据库分库分表全面瓦解

本文链接: https://www.lsjlt.com/news/163978.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Mysql数据库分库分表全面瓦解
    目录1 为什么要分库分表2 垂直拆分(Scale Up 纵向扩展)2.1 垂直分库2.2 垂直分表 3 水平拆分(Scale Out 横向扩展) 3.1 库内分表...
    99+
    2024-04-02
  • MySQL分表分库如何进行数据切分
    这篇文章主要讲解了“MySQL分表分库如何进行数据切分”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“MySQL分表分库如何进行数据切分”吧!数据库分布式核心...
    99+
    2024-04-02
  • MySQL-分库分表详解(七)
    ♥️作者:小刘在C站 ♥️个人主页: 小刘主页  ♥️努力不一定有回报,但一定会有收获加油!一起努力,共赴美好人生! ♥️学习两年总结出的运维经验,以及思科模拟器全套网络实验教程。专栏:云计算技术 ♥️小刘私信可以随便问,只要会...
    99+
    2023-09-02
    mysql 数据库
  • 怎么在MySQL数据库中实现分表分库操作
    这篇文章将为大家详细讲解有关怎么在MySQL数据库中实现分表分库操作,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。分表分库垂直拆分垂直拆分就是要把表按模块划...
    99+
    2024-04-02
  • MariaDB Spider数据库分库分表的方法
    本文小编为大家详细介绍“MariaDB Spider数据库分库分表的方法”,内容详细,步骤清晰,细节处理妥当,希望这篇“MariaDB Spider数据库分库分表的方法”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入...
    99+
    2023-06-29
  • 数据库中如何实现分库分表
    这篇文章将为大家详细讲解有关数据库中如何实现分库分表,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 分片是解决数据库存储容量限制的直接途径。分片包括垂直分片与水平分片两...
    99+
    2024-04-02
  • MariaDBSpider数据库分库分表实践记录
    目录分库分表部署 MariaDB 实例Docker 部署虚拟机部署MariaDB 配置检查每个实例配置 Spider远程表基准性能测试加入后端数据库哈希分片根据值范围分片根据列表分片...
    99+
    2024-04-02
  • MySQL分库分表总结讲解
    项目开发中,我们的数据库数据越来越大,随之而来的是单个表中数据太多。以至于查询变慢,而且由于表的锁机制导致应用操作也受到严重影响,出现了数据库性能瓶颈。 当出现这种情况时,我们可以考虑分库分表,即将单个数据...
    99+
    2024-04-02
  • 数据库分库分表是什么,什么情况下需要用分库分表
    目录数据量在什么情况下需要分表?1、oracle2、mysql3、sqlserver分库分表是什么,什么情况下需要用分库分表1、什么是分库分表?2、什么情况下需要分库分表?3、分库分...
    99+
    2024-04-02
  • MySQL分库分表详情
    一、业务场景介绍 假设目前有一个电商系统使用的是MySQL,要设计大数据量存储、高并发、高性能可扩展的方案,数据库中有用户表。用户会非常多,并且要实现高扩展性,你会怎么去设计? OK...
    99+
    2024-04-02
  • 数据库的分表分库算法有哪些
    这篇文章主要讲解了“数据库的分表分库算法有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“数据库的分表分库算法有哪些”吧!以下是几种常见的分表算法。1.按...
    99+
    2024-04-02
  • MySQL如何分库分表
    1. 我们为什么需要分库分表 在分库分表之前,就需要考虑为什么需要拆分。我们做一件事,肯定是有充分理由的。所以得想好分库分表的理由是什么。我们现在就从两个维度去思考它,为什么要分库?为什么要分表? 1.1 为什么要分库 如果业务量剧增,数...
    99+
    2023-08-17
    mysql 数据库
  • PHP如何实现MySQL数据库分表
    本篇内容介绍了“PHP如何实现MySQL数据库分表”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、MySQL分表的概念MySQL分表是将一...
    99+
    2023-07-06
  • Mysql数据库中的分库分表怎么利用MyBatis来实现
    本篇文章给大家分享的是有关Mysql数据库中的分库分表怎么利用MyBatis来实现,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。MyBatis实现分表最简单步骤我们模拟用户表数...
    99+
    2023-05-31
    mybatis mysql
  • PHP中的数据分库和分表
    PHP是一种常用的编程语言,用于开发Web应用程序。在现代Web应用程序中,数据处理是非常重要的一部分。随着Web应用程序中使用数据的不断增加,数据的分库和分表已经成为数据处理的基本技术之一。在PHP应用中,数据分库和分表也是一个非常重要的...
    99+
    2023-05-23
    PHP编程 数据分库 数据分表
  • 数据库分库分表后非分片键怎么查询
    这篇文章主要介绍“数据库分库分表后非分片键怎么查询”,在日常操作中,相信很多人在数据库分库分表后非分片键怎么查询问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”数据库分库分表后...
    99+
    2023-03-13
    数据库
  • 怎么解决数据库分库分表无限扩容问题
    这篇文章主要讲解了“怎么解决数据库分库分表无限扩容问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么解决数据库分库分表无限扩容问题”吧!单体应用每个创业...
    99+
    2024-04-02
  • 数据库的分库分表需要注意什么
    这篇文章主要讲解了“数据库的分库分表需要注意什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“数据库的分库分表需要注意什么”吧!切入层次以下,范围界定在JA...
    99+
    2024-04-02
  • MySQL分库分表实例分析
    这篇“MySQL分库分表实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“MySQL分库分表实例分析”文章吧。一、为什么...
    99+
    2023-06-30
  • 怎么在MySQL中分表分库时对数据进行切分
    今天就跟大家聊聊有关怎么在MySQL中分表分库时对数据进行切分,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。数据库分布式核心内容无非就是数据切分(Sharding)以及切分后对数据的...
    99+
    2023-06-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作