【MySQL】深入理解为什么MySQL使用B+树

【MySQL进阶】深入理解B+树索引底层原理 阅读详情

MySQL使用B+树的原理分析

为什么 MySQL 使用 B+ 树是面试中经常会出现的问题,很多人对于这个问题可能都有一些自己的理解,但是多数的回答都不够完整和准确,大多数人都只会简单说一下 B+ 树和 B 树的区别,但是都没有真正回答 MySQL 为什么选择使用 B+ 树这个问题,笔者将在这篇文章中就会深入分析 MySQL 选择 B+ 树背后的一些原因。

概述

首先需要弄清楚的一点是,MySQL 跟 B+ 树没有直接的关系,真正与 B+ 树有关系的是 MySQL 的默认存储引擎 InnoDB,MySQL 中存储引擎的主要作用是负责数据的存储和提取,除了 InnoDB 之外,MySQL 中也支持 MyISAM 作为表的底层存储引擎。
chuxlu@163.com
我们在使用 SQL 语句创建表时就可以为当前表指定使用的存储引擎,你能在 MySQL 的文档 Alternative Storage Engines 中找到它支持的全部存储引擎,例如:MyISAM、CSV、MEMORY 等,然而默认情况下,使用如下所示的 SQL 语句来创建表就会得到 InnoDB 存储引擎支撑的表:

CREATE TABLE user (
    id INT,
    name CHAR (20)
), PRIMARY KEY (id)) ENGINE=InnoDB;

我们今天最终将要分析的问题其实还是,为什么 MySQL 默认的存储引擎 InnoDB 会使用 MySQL 来存储数据,相信对 MySQL 稍微有些了解的人都知道,无论是表中的数据(主键索引)还是辅助索引最终都会使用 B+ 树来存储数据,其中前者在表中会以 <id, row> 的方式存储,而后者会以 <index, id> 的方式进行存储,这其实也比较好理解:

  • 在主键索引中,id 是主键,我们能够通过 id 找到该行的全部列;
  • 在辅助索引中,索引中的几个列构成了键,我们能够通过索引中的列找到 id,如果有需要的话,可以再通过 id 找到当前数据行的全部内容;

对于 InnoDB 来说,所有的数据都是以键值对的方式存储的,主键索引和辅助索引在存储数据时会将 id 和 index 作为键,将所有列和 id 作为键对应的值。
chuxlu@163.com
在具体分析 InnoDB 使用 B+ 树背后的原因之前,我们需要为 B+ 树找几个『假想敌』,因为如果我们只有一个选择,那么选择 B+ 树也并不值得讨论,找到的两个假想敌就是 B 树和哈希,相信这也是很多人会在面试中真实遇到的问题,我们就以这两种数据结构为例,分析比较 B+ 树的优点。

设计

到了这里我们已经明确了今天待讨论的问题,也就是为什么 MySQL 的 InnoDB 存储引擎会选择 B+ 树作为底层的数据结构,而不选择 B 树或者哈希?在这一节中,我们将通过以下的两个方面介绍 InnoDB 这样选择的原因。

InnoDB 需要支持的场景和功能需要在特定查询上拥有较强的性能;

CPU 将磁盘上的数据加载到内存中需要花费大量的时间,这使得 B+ 树成为了非常好的选择;

数据的持久化以及持久化数据的查询其实是一个常见的需求,而数据的持久化就需要我们与磁盘、内存和 CPU 打交道;MySQL 作为 OLTP 的数据库不仅需要具备事务的处理能力,而且要保证数据的持久化并且能够有一定的实时数据查询能力,这些需求共同决定了 B+ 树的选择,接下来我们会详细分析上述两个原因背后的逻辑。

读写性能

很多人对 OLTP 这个词可能不是特别了解,我们帮助各位读者快速理解一下,与 OLTP 相比的还有 OLAP,它们分别是 Online Transaction Processing 和 Online Analytical Processing,从这两个名字中我们就可以看出,前者指的就是传统的关系型数据库,主要用于处理基本的、日常的事务处理,而后者主要在数据仓库中使用,用于支持一些复杂的分析和决策。
作为支撑 OLTP 数据库的存储引擎,我们经常会使用 InnoDB 完成以下的一些工作:

  • 通过 INSERT、UPDATE 和 DELETE 语句对表中的数据进行增加、修改和删除;
  • 通过 UPDATE 和 DELETE 语句对符合条件的数据进行批量的删除;
  • 通过 SELECT 语句和主键查询某条记录的全部列;
  • 通过 SELECT 语句在表中查询符合某些条件的记录并根据某些字段排序;
  • 通过 SELECT 语句查询表中数据的行数;
  • 通过唯一索引保证表中某个字段或者某几个字段的唯一性;

如果我们使用 B+ 树作为底层的数据结构,那么所有只会访问或者修改一条数据的 SQL 的时间复杂度都是 O(log n),也就是树的高度,但是使用哈希却有可能达到 O(1) 的时间复杂度,看起来是不是特别的美好。但是当我们使用如下所示的 SQL 时,哈希的表现就不会这么好了:

SELECT * FROM posts WHERE author = 'draven' ORDER BY created_at DESC
SELECT * FROM posts WHERE comments_count > 10
UPDATE posts SET github = 'github.com/draveness' WHERE author = 'draven'
DELETE FROM posts WHERE author = 'draven'

如果我们使用哈希作为底层的数据结构,遇到上述的场景时,使用哈希构成的主键索引或者辅助索引可能就没有办法快速处理了,它对于处理范围查询或者排序性能会非常差,只能进行全表扫描并依次判断是否满足条件。全表扫描对于数据库来说是一个非常糟糕的结果,这其实也就意味着我们使用的数据结构对于这些查询没有其他任何效果,最终的性能可能都不如从日志中顺序进行匹配。
使用 B+ 树其实能够保证数据按照键的顺序进行存储,也就是相邻的所有数据其实都是按照自然顺序排列的,使用哈希却无法达到这样的效果,因为哈希函数的目的就是让数据尽可能被分散到不同的桶中进行存储,所以在遇到可能存在相同键 author = 'draven 或者排序以及范围查询 comments_count > 10 时,由哈希作为底层数据结构的表可能就会面对数据库查询的噩梦 —— 全表扫描。

B 树和 B+ 树在数据结构上其实有一些类似,它们都可以按照某些顺序对索引中的内容进行遍历,对于排序和范围查询等操作,B 树和 B+ 树相比于哈希会带来更好的性能,当然如果索引建立不够好或者 SQL 查询非常复杂,依然会导致全表扫描。

与 B 树和 B+ 树相比,哈希作为底层的数据结构的表能够以 O(1) 的速度处理单个数据行的增删改查,但是面对范围查询或者排序时就会导致全表扫描的结果,而 B 树和 B+ 树虽然在单数据行的增删查改上需要 O(log n) 的时间,但是它会将索引列相近的数据按顺序存储,所以能够避免全表扫描。

数据加载

既然使用哈希无法应对我们常见的 SQL 中排序和范围查询等操作,而 B 树和 B 树和 B+ 树都可以相对高效地执行这些查询,那么为什么我们不选择 B 树呢?这个原因其实非常简单 —— 计算机在读写文件时会以页为单位将数据加载到内存中。页的大小可能会根据操作系统的不同而发生变化,不过在大多数的操作系统中,页的大小都是 4KB,你可以通过如下的命令获取操作系统上的页大小:

$ getconf PAGE_SIZE
4096

当我们需要在数据库中查询数据时,CPU 会发现当前数据位于磁盘而不是内存中,这时就会触发 I/O 操作将数据加载到内存中进行访问,数据的加载都是以页的维度进行加载的,然而将数据从磁盘读取到内存中所需要的成本是非常大的,普通磁盘(非 SSD)加载数据需要经过队列、寻道、旋转以及传输的这些过程,大概要花费 10ms 左右的时间。
chuxlu@163.com
我们在估算 MySQL 的查询时就可以使用 10ms 这个数量级对随机 I/O 占用的时间进行估算,这里想要说的是随机 I/O 对于 MySQL 的查询性能影响会非常大,而顺序读取磁盘中的数据时速度可以达到 40MB/s,这两者的性能差距有几个数量级,由此我们也应该尽量减少随机 I/O 的次数,这样才能提高性能。

B 树与 B+ 树的最大区别就是,B 树可以在非叶结点中存储数据,但是 B+ 树的所有数据其实都存储在叶子节点中,当一个表底层的数据结构是 B 树时,假设我们需要访问所有『大于 4,并且小于 9 的数据』:
chuxlu@163.com
如果不考虑任何优化,在上面的简单 B 树中我们需要进行 4 次磁盘的随机 I/O 才能找到所有满足条件的数据行:

  1. 加载根节点所在的页,发现根节点的第一个元素是 6,大于 4;
  2. 通过根节点的指针加载左子节点所在的页,遍历页面中的数据,找到 5;
  3. 重新加载根节点所在的页,发现根节点不包含第二个元素;
  4. 通过根节点的指针加载右子节点所在的页,遍历页面中的数据,找到 7 和 8;

当然我们可以通过各种方式来对上述的过程进行优化,不过 B 树能做的优化 B+ 树基本都可以,所以我们不需要考虑优化 B 树而带来的收益,直接来看看什么样的优化 B+ 树可以做,而 B 树不行。

由于所有的节点都可能包含目标数据,我们总是要从根节点向下遍历子树查找满足条件的数据行,这个特点带来了大量的随机 I/O,也是 B 树最大的性能问题。

B+ 树中就不存在这个问题了,因为所有的数据行都存储在叶节点中,而这些叶节点可以通过『指针』依次按顺序连接,当我们在如下所示的 B+ 树遍历数据时可以直接在多个子节点之间进行跳转,这样能够节省大量的磁盘 I/O 时间,也不需要在不同层级的节点之间对数据进行拼接和排序;通过一个 B+ 树最左侧的叶子节点,我们可以像链表一样遍历整个树中的全部数据,我们也可以引入双向链表保证倒序遍历时的性能
chuxlu@163.com
有些读者可能会认为使用 B+ 树这种数据结构会增加树的高度从而增加整体的耗时,然而高度为 3 的 B+ 树就能够存储千万级别的数据,实践中 B+ 树的高度最多也就 4 或者 5,所以这并不是影响性能的根本问题。

总结

任何不考虑应用场景的设计都不是最好的设计,当我们明确的定义了使用 MySQL 时的常见查询需求并理解场景之后,再对不同的数据结构进行选择就成了理所当然的事情,当然 B+ 树可能无法对所有 OLTP 场景下的查询都有着较好的性能,但是它能够解决大多数的问题。

我们在这里重新回顾一下 MySQL 默认的存储引擎选择 B+ 树而不是哈希或者 B 树的原因:

  • 哈希虽然能够提供 O(1) 的单数据行操作性能,但是对于范围查询和排序却无法很好地支持,最终导致全表扫描;
  • B 树能够在非叶节点中存储数据,但是这也导致在查询连续数据时可能会带来更多的随机 I/O,而 B+
    树的所有叶节点可以通过指针相互连接,能够减少顺序遍历时产生的额外随机 I/O;

如果想要追求各方面的极致性能也不是没有可能,只是会带来更高的复杂度,我们可以为一张表同时建 B+ 树和哈希构成的存储结构,这样不同类型的查询就可以选择相对更快的数据结构,但是会导致更新和删除时需要操作多份数据。

从今天的角度来看,B+ 树可能不是 InnoDB 的最优选择,但是它一定是能够满足当时设计场景的需要,从 B+ 树作为数据库底层的存储结构到今天已经过了几十年的时间,我们不得不说优秀的工程设计确实有足够的生命力。而我们作为工程师,在选择数据库时也应该非常清楚地知道不同数据库适合的场景,因为软件工程中没有银弹。

MySQL 索引底层全解析:深入理解 B+树原理与实战 在数据库的世界里,索引就如同书籍的目录。没有目录,查找特定内容可能需要翻遍整本书;而有了目录,我们就能快速定位。在 MySQL 中,这个“目录”的核心实现就是 ——B+树(B+ Tree)。它是 MySQL 高性能查询的根基。你可能会问:为什么不用更简单的二叉树或 AVL 树?数据结构问题二叉树顺序插入时退化成链表,查询效率回到 O(N)。平衡二叉树(AVL)虽然平衡,但每个节点只有两个子节点,树高过大,磁盘 I/O 次数太多。数据库存储在磁盘上,每次节点访问都是一次磁盘 I/O。 阅读详情

相关推荐

数据库学习03——深入理解 MySQL InnoDB 和 MyISAM 底层 B + 树的区别

InnoDB:聚簇索引叶子节点存储数据,辅助索引叶子节点存储主键值。MyISAM:索引叶子节点存储数据指针,数据单独存储在数据文件。

GoppViper的博客 1354

mysql为什么使用b+树

MySQL 使用 B 树有以下几个原因: 查询效率高:B 树的查询时间复杂度是 log(n) 级别的,相比链表和二叉树的 O(n),性能要高得多。 支持范围查询:B 树能够支持范围查询,这在 MySQL 中经常用于 WHERE 子句中的 BETWEEN 和 IN 运算符。 支持索引和排序:B 树可以用来实现索引,而且在查询时能够保证结果的有序性。 支持动态扩展:B 树可以动态地向两侧扩展,...

weixin_42588555的博客 2078

SIMPLIS实战:从零构建理想BUCK电路,精准计算与POP稳态分析

本文详细介绍了如何使用SIMPLIS软件从零开始构建并仿真一个理想的BUCK降压电路。通过设定关键参数、计算理想器件值,并搭建仿真模型,文章重点演示了暂态仿真以观察电路上电过程,并深入讲解了高效的POP(周期性工作点)稳态分析技术,帮助工程师快速验证设计、评估稳态性能,从而加速电源设计迭代。

weixin_29165465的博客 395

mysql为什么要用b+树

mysql为什么要用b+树

qq_40263124的博客 6232

Realtek RTD1319D芯片解析:H.266与AV1双解码的机顶盒SoC

视频编解码技术是数字媒体传输的核心,H.266/VVC作为新一代标准,相比H.265提升50%压缩效率,显著降低带宽需求。其实现原理依赖于专用硬件解码器和并行处理架构,在超高清视频传输领域具有重要价值。Realtek RTD1319D作为首款商用H.266处理器,采用异构计算设计,集成四核ARM CPU和独立视频处理单元,同时支持AV1解码,兼顾市场兼容性。该SoC特别适合4K机顶盒、数字标牌等应用场景,其HDMI 2.1a接口和DVB解调器为超高清内容传输提供完整解决方案。开发时需注意散热设计和内存配置优

weixin_42591413的博客 671

如何把ORCAD 中的修改同步到PADS 中

Generate ECO file(*.eco),eco 文件的默然保存地址是在pads 的。ECO Files (*.eco),接着在文件中找到所生成的eco 文件,找到。再下来是产生eco 文件,先打开old_design.pcb,然后选择。PCB Design 前面的选项选中,意思把当前文件做为原始的比对。安装目录下(可修改eco 文件的保存目录),这里把eco 文件保存。接下来用新生成asc 文件的文件产生新的PCB 文件,新生成。不对新生成的pcb 做任何的修改,直接保存文件,这里把新文件。

智光工作室 993

MySQL为什么使用B+树,而不是B树?

在MySQL中,B+树被广泛应用于索引结构,因为它支持高效的范围查询和区间扫描,并且有助于减少磁盘I/O操作,从而提高查询效率。B+树相对于B树来说,其内部节点只存储键值信息,而不存储数据信息,这样可以让每个节点能够存储更多的键值信息,从而使得查询同一层次的所有数据时,能够一次性读入更多的数据块,减少磁盘I/O操作。由于B+树的非叶子节点只存储键值信息,而不存储指向数据的指针,因此当进行范围查询时,只需要遍历B+树的叶子节点即可,而不需要遍历非叶子节点,大大加快了查询速度。

jkzyx123的博客 4690

【Zemax光学设计实训一】---单透镜光学设计

建立一个焦距为100mm、入瞳直径为25mm的单透镜系统,该透镜中心厚度为4mm,其两个面的曲率半径分别为100mm、-100mm,全视场2w=10°。该系统在可见光下工作,采用BK7玻璃,光阑设置在人射光线遇到的透镜的第一个光学表面;并对其展开优化。

yh的博客 3618

MySQL的索引结构为什么是B+树?

博客主页:🏆看看是李XX还是李歘歘🏆 🌺每天分享一些包括但不限于计算机基础、算法等相关的知识点🌺 💗点关注不迷路,总有一些📖知识点📖是你想要的💗 ⛽️今天的内容是 MySQL的索引结构为什么是B+树? ⛽️💻💻💻 先来看一下树的演化: 树:非线性结构,每个节点有唯一的一个父结点和多个子结点(子树),为一对多的关系。 二叉树:每个结点最多有两颗子树,并且子树有左右之分,不能颠倒。 满二叉树:每一层的结点个数都达到了当层能达到的最大结点数。 完全二叉树:除了最...

分享包括但不限于计算机基础知识、数据结构与算法、Golang技术栈。年与时驰,意与日去,遂成枯落,多不接世,悲守穷庐,将复何及! 5977

AutoCAD 2024 LISP实用技巧:自定义快捷命令与高效绘图工具集

本文详细介绍了如何在AutoCAD 2024中部署和使用LISP脚本,打造高效绘图工具集。通过自定义快捷命令,如WFF(超级文字查找替换)、GQT(图层隔离)和LLTJ(智能长度统计),可大幅简化图层管理、文字编辑和测量统计等重复性操作,显著提升绘图效率。

gan8painter的博客 319

【数字IC设计】芯片设计中的RDC

在芯片设计中,RDC是的缩写,类似于CDC(clock domain crossing),由于现在SOC芯片是有很多ECUs组成,为了使整个系统能够快速从复位中恢复, 用户希望SOC里面每个ECU模块都可以有自己独立的异步复位信号,这样可以在出问题的时候只复位有错误逻辑的模块,而使其它模块保持正常工作。

qq_40268672的博客 2185

【MySQL基础】为什么大部分人选择使用MySQL数据库?

主要讲述为什么大部分人选择使用MySQL数据库作为后端数据库存储;以及对MySQL作了一个简单的介绍,以及对MySQL特点和版本的讲述。

四季轮换叶,一路招摇胜 9324

Transformer模型详解

​本文主要介绍Transformer系列,从基础到理论,对注意力机制进行总结并解释《Attention is all you need》,提出解决sequence to sequence问题的transformer模型,用全attention的结构代替了lstm,抛弃了之前传统的encoder-decoder模型必须结合cnn或者rnn的固有模式,只用attention。文章的主要目的是在减少计算量和提高并行效率的同时不损害最终的实验结果。

专注大数据与人工智能技术分享,欢迎私信加群互相学习! 5296

深入理解MySql为何使用B+树而不是B树

深入理解MySql为何使用B+树而不是B树

weixin_45743816的博客 1563

Docker Desktop 从 C 盘迁移到 D 盘的正确方法

本文介绍了三种将Docker数据目录从C盘迁移到D盘的方案。方案1针对WSL2用户,通过导出/导入虚拟磁盘实现迁移;方案2采用软链接方式,适合所有Docker模式;方案3则建议重装Docker到D盘。其中WSL2迁移方案(方案1)最为稳定可靠,推荐使用。文章详细说明了各方案的操作步骤及注意事项,并提供了迁移后常见问题的解决方法,帮助用户彻底解决Docker占用C盘空间的问题。

sg_knight的专栏 2178

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

深入理解Mysql的B+树

在 MySQL 里 InnoDB 存储引擎是采用 B+ 树来组织数据的。如图:可以得出B+树的特点。

weixin_54498224的博客 1424

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【MySQL】深入理解B+树索引

索引,是MySQL快速查询的秘籍。如果没有索引,是怎么查询记录的呢?首先,假如表中记录比较少,所有记录都可以存放在一个页中。以主键为搜索条件,这种就可以通过页目录使用二分法快速定位到相应的槽,接着遍历槽中的记录,就可以快速找到指定记录了。以其他列作为搜索条件,因为页中没有为非主键建立所谓的页目录,所以无法通过二分法定位槽的方式查找。只能从Infimum记录开始依次遍历单项链表的每条记录,然后对比是否符合搜索条件。(效率最低)如果表中记录很多,就需要用比较多的页存储这些记录定位记录所在页。

沉迷写代码的程序猿的博客 1734

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

mysql之深入理解b+树原理

对应一个扇区,512B。从最顶层遍历到响应序号,继续向下索引到对应扇区,也是32块数据, 直至到叶子节点,也是能对应找到对应32个数据,从32个数据中查找。一次扇区的查找,对应一次io,这样就有了b+树对io次数的优化,并且b+树。因为 B + 树是平衡树,所有叶子节点都在同一层,所以无论查询哪个数据,IO 次数都是固定的(比如 MySQL 中通常是 2-3 次),这保证了 SQL 查询性能的稳定性。B + 树是多路平衡查找树,非叶子节点只存索引和指针,数据全在叶子节点,而且叶子节点用双向链表串起来。

2401_87338545的博客 1050

深入理解MySQL索引和B+树

数据库索引是一种数据结构,用于快速查找数据库中的记录。它类似于书籍的目录,可以加速查询操作。通过本文的介绍,相信你已经对MySQL索引和B+树有了更深入的了解。索引是数据库优化的核心工具之一,合理设计和使用索引可以显著提升数据库查询性能。同时,我们也探讨了索引在性能和安全性方面的考量,并提供了具体的Java JDBC示例来演示索引的创建和使用。如果你有任何问题或者想要进一步了解,请随时在评论区留言!

q68686的博客 785

从 B+ 树开始,深入理解 MySQL索引

MySQL InnoDB 索引本质上是 B+ 树数据结构,主键索引(聚簇索引)的叶子节点存储完整数据行,普通索引(二级索引)存储索引列和主键值。查询时通过 B+ 树快速定位数据,二级索引需要回表查询完整数据,而覆盖索引可直接返回结果。联合索引遵循最左前缀原则,B+ 树的多路分支和叶子节点有序特性使其适合磁盘存储和范围查询,这就是索引加速查询的底层原理。设计索引时应考虑主键长度、查询模式等因素以优化性能。

m0_47570236的博客 320

【mysql是怎样运行的】-B+树索引深入理解

各个数据页可以组成一个,而每个数据页中的记录会按照主键值从小到大的顺序组成一个。

JH灰色的博客 968

深入理解 MySQL 索引:从 B+ 树到索引下推

本文深入解析InnoDB索引机制。B+树通过非叶子节点存储键值和页号实现高效查找,3层结构即可支持千万级数据查询。聚簇索引存储完整数据,二级索引仅存储索引字段和主键。文章揭示了索引优化的关键点:前缀索引需评估区分度、低选择性索引会失效、覆盖索引避免回表。同时解释了最左匹配原则和索引下推技术(ICP)如何显著减少磁盘I/O。这些原理对大数据量表索引设计具有重要指导意义。

weixin_48471044的博客 684

深入理解MySQL索引优化从B+树原理到实战性能提升

索引下推是MySQL 5.6引入的重要特性,它允许在索引遍历过程中,对索引中包含的字段先做判断,过滤掉不满足条件的记录,减少回表次数。通过分析EXPLAIN的输出,我们可以获知查询是否使用了索引、使用了哪个索引、表的连接顺序、需要扫描的行数等关键信息。与聚簇索引相对的是二级索引(或称辅助索引),其叶子节点存储的不是完整的数据行,而是对应记录的主键值。对于较长的字符串列,可以考虑使用前缀索引,只对前N个字符建立索引,以平衡索引大小和查询效率。此外,对于频繁更新的列,索引的维护成本很高,需要谨慎评估。

zqm1078330121的博客 780

MySQL面试题深入理解 MySQL InnoDB 为何选择 B+ 树作为索引结构

B+树的索引分两种,一种是聚簇索引,一种是非聚簇索引。采用B+树能够减少磁盘IO次数。

2201_75642742的博客 255
上一篇: 【分布式锁】并发场景下的数据插入
下一篇: 【排序】堆排序详解 附代码
少侠露飞
博客等级 码龄9年 214粉丝 117原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值