0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

B+树索引如何对Mysql单表数据量造成影响

电子设计 来源:博客园 作者:佚名 2020-04-16 08:08 次阅读

Mysql 单表适合的最大数据量是多少?

我们说 Mysql 单表适合存储的最大数据量,自然不是说能够存储的最大数据量,如果是说能够存储的最大量,那么,如果你使用自增 ID,最大就可以存储 2^32 或 2^64 条记录了,这是按自增 ID 的数据类型 int 或 bigint 来计算的;如果你不使用自增 id,且没有 id 最大值的限制,如使用足够长度的随机字符串,那么能够限制单表最大数据量的就只剩磁盘空间了。显然我们不是在讨论这个问题。

影响 Mysql 单表的最优最大数量的一个重要因素其实是索引

我们知道 Mysql 的主要存储引擎 InnoDB 采用 B+树结构索引。(至于为什么 Mysql 选择 b+树而不是其他数据结构来组织索引,不是本文讨论的话题,之后的文章会讲到。)那么 B+树索引是如何影响 Mysql 单表数据量的呢?

B+树

一棵 B+树如下所示:

B+树索引如何对Mysql单表数据量造成影响

Mysql 的 B+树索引存储在磁盘上,Mysql 每次读取磁盘 Page 的大小是 16KB,为了保证每次查询的效率,需要保证每次查询访问磁盘的次数,一般设计为 2-3 次磁盘访问,再多性能将严重不足。Mysql B+树索引的每个节点需要存储一个指针(8Byte)和一个键值(8Byte)。因此计算16KB/(8B+8B)=1K 16KB 可以存储 1K 个节点,3 次磁盘访问(即 B+树 3 的深度)可以存储 1K _ 1K _ 1K 即 10 亿数据。

如果查询依赖非主键索引,那么还涉及二级索引。这样数据量将更小。

拆分

分而治之——没有什么问题不能通过拆分一次来解决,不行就拆多次。

Mysql 单表存储的数据量有限。一个解决大数据量存储的办法就是分库分表。说白了就是一个数据库一张表放不下那么多数据,那就分多个数据库多张表存储。

拆分可分为垂直拆分和水平拆分。

垂直拆分是按照不同的表(或者 Schema)来切分到不同的数据库(主机)之上,水平拆分则是根据表中的数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上面或多张相同 Schema 的不同表中。

垂直拆分的最大特点就是规则简单,实施也更为方便,尤其适合各业务之间的耦合度非常低,相互影响很小,业务逻辑非常清晰的系统。在这种系统中,可以很容易做到将不同业务模块所使用的表分拆到不同的数据库中。根据不同的表来进行拆分,对应用程序的影响也更小,拆分规则也会比较简单清晰。

水平拆分与垂直切分相比,相对来说稍微复杂一些。因为要将同一个表中的不同数据拆分到不同的数据库中,对于应用程序来说,拆分规则本身就较根据表名来拆分更为复杂,后期的数据维护也会更为复杂一些。

垂直拆分最直接的就是按领域拆分服务,隔离领域数据库。如此每个库所承担的数据压力就减少了。

水平拆分就是将同一个 Schema 的数据拆分到不同的库或不同的表中,这样每个表的数据量也将减小,查询效率将更高效。水平拆分就涉及到表的分片规则问题。

几种典型的分片规则包括:

按照用户 ID 求模,将数据分散到不同的数据库,具有相同数据用户的数据都被分散到一个库中。

按照日期,将不同月甚至日的数据分散到不同的库中。

按照某个特定的字段求摸,或者根据特定范围段分散到不同的库中。

实现

门面模式——没有什么问题不能通过添加一个中间层来解决。

垂直拆分的一个方案就是在应用层使用多个数据源,按业务访问不同的数据源。另外更好方案其实就是微服务化。按不同的业务领域来拆分微服务,明确领域边界,隔离领域数据库。这样将对数据的存取内聚到独立的服务之中,对外提供统一的接口。在需要同时依赖多个服务时,我们可以通过添加门面应用来组合底层服务的数据,以提供更符合上层业务需求的接口,这些服务往往更接近真实的业务。而底层的服务则是更加内聚的资源服务。

代理模式——没有什么问题不能通过添加一个中间层来解决。

对于水平拆分应该尽量屏蔽拆分带来的数据访问困恼,为了让上层业务无需关心下层数据组织方式。水平拆分往往通过添加一个代理层来做这些事情,代理层对上提供虚拟表,这些虚拟表就像我们在单库上设计的单表一样;代理层对下解析和拆分执行 sql,然后按相应规则在不同的库和表执行相应的 sql 请求,再合并数据,并将合并后的结果返回给上层调用者。

一般代理方式分为如下两种:

进程内代理

进程内代理即将代理层嵌入到业务服务内部,拦截 sql 请求并做相应的处理。这样的好处是简单,但是侵入性大,且不够灵活。

进程内代理

进程外代理

进程外代理即将代理独立成服务,代理真实业务服务和数据库之间的请求。这样是比较复杂的,需要高可用的代理服务架构。但是这样对业务的侵入性低,且易于升级扩展。

进程外代理

问题

分布式事务问题

什么是分布式事务?本地事务的定义就是一系列相关的数据库操作完成后要满足 ACID 四大特性,而分布式事务就是将同一进程的操作放到不同的微服务进程中,即不同微服务应用进程的数据库操作满足事务要求,或者对不同数据库的一系列操作需满足事务要求。

这里就有两个问题需要解决。一个是因为应用的分布式造成的,一个是因为数据库本身的分布式造成的。数据库本身的分布式事务问题一般由数据库自身解决,大多数分布式数据库都可以做到一定的数据一致性保证,如 HBase 保证的强一致性,Cassandra 保证的最终一致性。

应用数据的一致性事务方案我们也可以参考分布式数据库的实现原理来实现。业界也有很多分布式事务的解决思路,如:

XA 方案

TCC 方案

本地消息表

可靠消息最终一致性方案

最大努力通知方案

多表 Join 问题

通过分析 Join sql,将 sql 拆分成独立的查询请求,然后分别执行,并将结果合并计算返回给调用者。这个地方会涉及到很多执行优化的问题。

数据统计问题

当数据被分片到不同的数据库或不同的表中时,要对数据做一些全局的或涉及大量数据的统计时便会遇到一些问题。如求 Max,Min,Sum 等聚合问题。如果统计的数据有一定的业务规则,如只会按用户维度去统计,如统计某个用户的订单量,那么对订单表的分片,其实可以采用按用户 id 来分片,如此就可以解决这类统计问题。但是这种方案不通用。很多分片代理服务都需要将 sql 分片到不同的节点上去执行,然后再合并结果返回。

ID 问题

使用分库分表之后,就无法使用 Mysql 的表自增作为 id,因为不同库和表的自增将出现冲突的 id。解决这个问题就需要引入分布式 id 生成技术。

责任编辑:gt


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 引擎
    +关注

    关注

    1

    文章

    360

    浏览量

    22528
  • 大数据
    +关注

    关注

    64

    文章

    8862

    浏览量

    137277
收藏 人收藏

    评论

    相关推荐

    MySQL数据索引的底层是怎么实现的

    ' 。就能查出特定列(姓名列)的特定值(张三)的记录。另外,它是一种数据结构。那么mysql数据结构,采用的是B+。那么,为啥选
    发表于 07-28 15:30

    基于B+的动态数据持有性证明方案

    针对云存储环境下的数据持有性证明( PDP)方案效率较低、不能很好支持全动态更新的问题,设计了一种基于B+的动态数据持有性证明方案。该方案引入双线性对技术和
    发表于 11-30 17:14 0次下载
    基于<b class='flag-5'>B+</b><b class='flag-5'>树</b>的动态<b class='flag-5'>数据</b>持有性证明方案

    基于KD和R的多维索引结构

    针对云存储系统大多基于键值对 key,value模型存储数据,多维查询需要对整个数据集进行完全扫描,查询效率较低的问题,提出了一种基于KD和R的多维
    发表于 01-25 15:13 0次下载
    基于KD<b class='flag-5'>树</b>和R<b class='flag-5'>树</b>的多维<b class='flag-5'>索引</b>结构

    MySQL索引使用原则

    一般来说, MySQL 中的 B-Tree 索引的物理文件大多都是以 Balance Tree 的结构来存储的,也就是所有实际需要的数据都存放于 Tree 的 Leaf Node(叶子
    的头像 发表于 02-11 15:17 2699次阅读
    <b class='flag-5'>MySQL</b><b class='flag-5'>索引</b>使用原则

    MySQL索引的使用问题

    一、前言 在MySQL中进行SQL优化的时候,经常会在一些情况下,对MySQL能否利用索引有一些迷惑。譬如:1、MySQL 在遇到范围查询条件的时候就停止匹配了,那么到底是哪些范围条件
    的头像 发表于 01-06 16:13 1581次阅读

    关于MySQL ORDER BY的详解

    回答一些常见的问题(下文仅讨论InnoDB存储引擎)。 2 索引扫描排序和文件排序(filesort)简介 我们知道InnoDB存储引擎以B+作为索引的底层实现,
    的头像 发表于 02-08 11:20 2444次阅读
    关于<b class='flag-5'>MySQL</b> ORDER BY的详解

    掌握这几种方法 你的接口查询速度将飞速提升

    1. MySQL查询慢是什么体验? 大多数互联网应用场景都是读多写少,业务逻辑更多分布在写上。对读的要求大概就是要快。那么都有什么原因会导致我们完成一次出色的慢查询呢? 1.1 索引数据量不是
    的头像 发表于 07-06 14:38 1786次阅读

    B+ 索引MySQL 中的认识

    概述 本质:数据库维护某种数据结构以某种方式引用(指向)数据 索引取舍原则:索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数
    的头像 发表于 11-08 11:11 1248次阅读
    对 <b class='flag-5'>B+</b> <b class='flag-5'>树</b>与<b class='flag-5'>索引</b>在 <b class='flag-5'>MySQL</b> 中的认识

    Mysql索引为什么使用B+

    比方说我们想要查找行数据5。会先从顶层页的record们入手。record里包含了主键id和页号(页地址)。关注黄色的箭头,向左最小id是1,向右最小id是7。那id=5的数据如果存在,那必定在左边
    的头像 发表于 06-08 16:34 682次阅读
    <b class='flag-5'>Mysql</b><b class='flag-5'>索引</b>为什么使用<b class='flag-5'>B+</b><b class='flag-5'>树</b>?

    MySQL高级进阶:索引优化

    MySQL官方对于索引的定义:索引是帮助MySQL高效获取数据数据结构。
    的头像 发表于 06-11 11:13 550次阅读
    <b class='flag-5'>MySQL</b>高级进阶:<b class='flag-5'>索引</b>优化

    MySQL为什么选择B+作为索引结构?

    MySQL中,无论是Innodb还是MyIsam,都使用了B+索引结构(这里不考虑hash等其他索引)。本文将从最普通的二叉查找
    的头像 发表于 07-20 11:28 915次阅读
    <b class='flag-5'>MySQL</b>为什么选择<b class='flag-5'>B+</b><b class='flag-5'>树</b>作为<b class='flag-5'>索引</b>结构?

    MySQL索引的常用知识点

    索引结构:B+ 索引其实是一种数据结构 注意B+
    的头像 发表于 09-30 16:43 432次阅读

    索引是什么意思 优缺点有哪些

    数据结构,以协助快速查询、更新数据数据索引的实现通常使用B
    的头像 发表于 10-09 10:19 2785次阅读

    MySQL数据量限制:为何2000万行成为瓶颈?

    很多人认为:数据量超过500万行或2000万行时,引起B+tree的高度增加,延长了索引的搜索路径,进而导致了性能下降。事实果真如此吗?
    的头像 发表于 02-27 10:38 5593次阅读
    <b class='flag-5'>MySQL</b><b class='flag-5'>单</b><b class='flag-5'>表</b><b class='flag-5'>数据量</b>限制:为何2000万行成为瓶颈?

    一文了解MySQL索引机制

    的呢?一起静下心来,耐心看完这篇文章吧,干货不啰嗦,相信你一定会有所收获。 一、索引模型 模型也就是数据结构,常见的三种模型分别是哈希、有序数组和搜索。 了解
    的头像 发表于 07-25 14:05 234次阅读
    一文了解<b class='flag-5'>MySQL</b><b class='flag-5'>索引</b>机制