数据库底层设计(MYSQL索引的数据结构)

MySQL索引底层数据结构全解析:从B+树到索引失效实战 在数据库性能优化中,索引是提升查询效率的核心手段。理解索引底层的数据结构,是掌握MySQL优化技术的基石。从红黑树、Hash到B树、B+树,每种结构都在特定场景下有着独特的取舍:红黑树适合内存动态数据,Hash索引擅长等值查询却无法支持范围扫描,而B+树通过非叶子节点只存键值、叶子节点链表有序,大幅降低磁盘IO次数并稳定查询性能。InnoDB基于B+树实现聚簇索引与二级索引,由此引出回表、覆盖索引、最左前缀等关键概念。实际开发中,索引失效场景如隐式类型转换、函数运算、违反最左前缀等,常导致慢查询。掌握exp 阅读详情

前言

说到数据库这个词,我只能用爱恨交加这个词来形容它。自己之前还单纯懵懂的时候进了数据库的课堂,听完数据库的课,觉得这是一门再简单不过的课程,任何一门编程语言都比SQL要晦涩难懂,任何一门理论课程都比数据库关系要复杂得多。

直到从被面试官按在地上摩擦,到工作中那一条条令人发指的慢查询SQL,这就已经完全颠覆了我对数据库的看法。

在有各种数据库工具的今天,我们是看不到那简单到不能再简单的一张表的背后,隐藏着多少数据结构的支撑,也看不到我们随手敲的一条SELECT,背后会有多少算法和数据结构在给我们做优化,作为一个有技术热情的coder,应该需要对我们每日在用的数据库做一次深入了解。


数据库架构

如何设计一个关系型数据库

这个问题很宽泛,需要我们对于整体有一个掌控,对我们平时所用的数据库要有足够的了解,对整个数据库做模块划分是这道题的关键,这就更需要我们足够了解数据库,对数据库做一个合理的模块设计。

设计

从开始,首先要明白,数据库的最最根本的作用是什么——存储数据,所以我们需要一个存储模块来存储我们的数据,它可以是一个文件系统(机械硬盘?SSD固态硬盘?)。但光有存储模块是不够的,我们还需要一个程序实例,来组织或者获取这些数据,在程序实例中我们需要提供获取和组织这些数据的方式,所以我们需要在程序实例中实现存储管理模块。

我们还可以在存储管理模块中做一些提升效能的工作,例如同时读取多行、分块分页存储等。数据库作为一款对性能要求极高的软件,我们应该加入缓存机制,来提高其速度,当查询到缓存中已存在的数据,我们应该直接将其从缓存中读取,这样可以减少硬盘IO次数,提高效能。

到这里为止,我们已经完成了对数据库的存储方面的功能设计,但是作为数据库,应该需要提供给用户对数据进行增删改查的接口,即平时所写的SQL,所以我们应该提供一个SQL解析模块,来对日常用户所写的SQL语句进行解析,转换成机器可识别的指令,我们也可以直接将编译过的SQL加入缓存,下次再有同样的SQL就直接从缓存中读取,同样可以提高效能。

作为一款成熟的数据库,需要应对各种复杂的环境,要时刻记录数据库的状态,所以我们还需要一个日志管理模块,对操作和错误信息进行记录。数据库中需要支持多用户操作,但每个用户都能操作所有的数据,这是不现实的,所以还需要权限划分模块对数据库用户进行权限管理。

当然数据库说到底也只是一款软件,是软件就会有bug,就会出故障,故障不可怕,可怕的是在数据库这种敏感软件下对故障没有特殊的处理方式,导致数据丢失,毕竟数据是无价的,所以数据库应该引入容灾机制,在数据库挂了的时候,对数据进行恢复。

还有作为数据库最重要的两个模块,也是现今任何一个数据库都需要考虑的问题——并发和查找效率,所以还需引入索引和锁这两个模块,这就是实现一个最基础的数据库所必需的几大模块。

归纳

综上对数据库设计模块做一个汇总:

1.存储模块

2.程序实例

  • 存储管理模块
  • 缓存机制
  • SQL解析模块
  • 日志管理模块
  • 权限划分模块
  • 容灾机制
  • 索引模块
  • 锁模块

索引

为什么要使用索引

要考虑这个问题,首先要从最基础的查找表中数据的过程开始说起。通常我们在查找一个序列中的某一个元素时,用到的最简单的方式就是遍历,数据库也是一样,在一张表中查找某一行数据时,如果不考虑索引的状况下,也会采用一个逐行扫描的方式,只不过数据库通常以块或者页为单位,所以它通常将整个块或者页加载进内存,然后逐块轮询查找到结果并返回。

如果数据库中只有少量数据,那么进行全表扫描,速度还是会很快,但是如果在数据量很大的表中,这种方法就不再适用了,在数据量很大的表中,由于逐行扫描代价变大,通常需要避免采用这种逐行扫描的方式进行数据查找,数据库为了使查询变得高效,所以引入了索引这种方式对数据进行查找。

C/C++Linux后台服务器开发高级架构师学习视频 点击 linux服务器学习资料 获取,内容知识点包括Linux,Nginx,ZeroMQ,MySQL,Redis,线程池,MongoDB,ZK,Linux内核,CDN,P2P,epoll,Docker,TCP/IP,协程,DPDK等等。免费学习地址:C/C++Linux服务器开发高级架构师/Linux后台架构师-学习视频

什么样的信息能成为索引

  • 主键
  • 唯一键
  • 普通键

索引的数据结构

二叉查找树

众所周知,二叉查找树是每个节点最多由两个子树的树结构,而其还有一个特点是,在任意一颗树中,根节点的左孩子永远小于根节点,根节点的右孩子永远大于根节点,用二叉查找树作为索引,确实可以提高查找效率,其可以使用二分查找将时间复杂度控制在O(lgn),但是二叉查找树有一个显而易见的缺陷,当某种特殊情况(按照某个特定顺序插入树)发生时,二叉查找树将变为下图右侧(线性二叉树)的状况:

此时二叉查找树查找任意某个元素时,其查找顺序与逐行查找无异,查询时间复杂度又将回到O(n),查询效率无法保持。

B-Tree

B-Tree,平衡多路查找树,如果每个节点,最多有N个孩子,那么这样的树就叫N阶B-Tree,
每个节点中主要包含关键字和指向孩子的指针,最多能有几个孩子,取决于节点的容量和数据库的相关配置,通常情况下这个N是很大的。

B-Tree作为一种数据结构,有如下特征:

  1. 根节点至少包含两个孩子
  2. 树中每个节点至多含有N个孩子(N>=2)
  3. 除根节点和叶节点外,其它每个节点至少有ceil(N/2)个孩子。(ceil表示取上限,例如1.2的上限为2,1.1的上限也为2,非四舍五入)
  4. 所有叶子节点都位于同一层,即叶子节点的高度都是一样的。
  5. 假设每个非终端节点包含n个关键字信息(P0,P1…Pn,k1…kn)

1、ki(i=1..n)为关键字,且关键字按顺序升序排序k(i-1)<ki。
2、关键字的个数必须满足:[ceil(m/2)-1]<=n<=m-1]。
3、非叶子节点的指针:P[1],P[2]…P[M];其中P[1]指向关键字小于K[1]的子树,P[N]指向关键字大于K[N-1]的子树,其它P[i]指向关键字属于(K[i-1],K[i])的子树。

遵守上述规则,其目的就是尽量使每个索引块都尽可能多的存储数据,尽可能减少查找次数以提升效率。

举个例子,模拟一下查找过程,以便于理解:假设我们要查询关键字为10的数据,则从根节点出发,10<17,于是通过P1进入其孩子节点,10>8且10<12,于是通过P2进入其孩子节点,最后寻找到10。如果不使用索引,而使用逐行扫描的方式进行查找,则从0开始至少扫描10次才能查找到10号数据,有了索引之后可以看到,查找次数从10变为3,大大提高了查找效率。

如果这里是二叉查找树,会出现极端情况,使得查找时间复杂度为O(n),而如果是B-Tree,由于上述五个约束,可以让节点通过合并、分裂、上移、下移等操作,使得树高度较二叉查找树小,查找效率显然更高。

B+ -Tree(MySQL)

B+ -Tree是B-Tree的一个变体,其定义基本与B树相同,除了:

  1. 非叶子节点的子树指针与关键字个数相同,其表明B+树能存储更多的关键字
  2. 非叶子节点的子树指针P[i],指向关键字值[K[i],K[i+1])的子树。
  3. 非叶子节点仅用来做索引,数据到保存在叶子节点中。(B+树的所有检索都是从根部开始,直到搜索到叶子节点结束。)
  4. 所有叶子节点均有一个链指针,指向下一个叶子节点。(方便直接在叶子节点直接做范围统计)

B+树相较于B树的优势:

  1. B+树的磁盘读写代价更低。
  2. B+树的查询效率更加稳定。
  3. B+树更有利于对数据库的扫描。

Hash

Hash索引是根据Hash结构的定义,只需要一次运算便可以找到数据所在位置,不像B+树或者B树需要从根结点出发寻找数据,所以Hash索引的查询效率理论上要高于B+树索引,但是MySQL中并没有采用这一种索引,这是由于这种索引除查询效率之外的缺陷是十分明显的。

  1. 仅仅只能满足"=","IN",不能使用范围查询。由于其是由Hash运算获取的数据存放位置,每次Hash运算获取的是一个确定的值,且这个值并不与数据本身的大小有关系,所以其并不能满足范围查询。
  2. 无法被用来避免数据的排序操作。和1的意思差不多,Hash的索引值是由Hash运算获取的,其索引值与数据本身的大小并无明显关系。
  3. 不能利用部分索引键查询。
  4. 不能避免表扫描。由于Hash索引会产生Hash冲突,存在Hash冲突的数据会被连接到同一个链表上,当大量数据被连接到相同链表上时,查询某条数据就变成了扫描该链表,时间复杂度并不能保证在O(1)。
  5. 遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。

BitMap索引

位图索引,当表中的某个字段只有几种值的时候,例如:性别,此时用位图索引是一个最佳的选择。目前使用位图索引的比较主流的数据库有Oracle数据库。

密集索引和稀疏索引的区别

  1. 密集索引文件中的每个搜索码都对应一个索引值,稀疏索引文件只为索引码的某些值建立索引项。
  2. 密集索引将数据存储与索引放到了一块,找到索引也就找到了数据,稀疏索引将数据和索引分开存储,索引结构的叶子节点指向数据的对应行。

关于MySQL的MyISAM和InnoDB

MyISAM不论是主键索引、唯一键索引、还是普通索引,都采用的是稀疏索引,而InnoDB必须有且仅有一个密集索引。

InnoDB密集索引规则:

  1. 若一个主键被定义,该主键则作为密集索引。
  2. 若没有主键被定义,该表的第一个唯一非空索引则作为密集索引。
  3. 若不满足以上条件,InnoDB内部会生成一个隐藏主键(密集索引)。
  4. 非主键索引存储相关键位和其对应的主键值,包含两次查找。

注:InnoDB如果查询条件为主键索引,则只需查询一次,但是辅助索引需要查询两次,先通过辅助索引查询到主键索引,再查询到数据。

从上图中可以看到,如果一个索引是聚集索引,则其叶子节点上存放的即是数据本身,而如果一个索引是稀疏索引,叶子节点存放的仅是地址,指向将要查找的数据。

C/C++Linux后台服务器开发高级架构师免费学习地址:C/C++Linux服务器开发高级架构师/Linux后台架构师-学习视频

如何定位并优化慢查询SQL

首先先建立一张表

CREATE DATABASE sqltest;
use sqltest;
create table tb_test(
  test_id int primary key auto_increment,
  test_name varchar(1024),
  test_date datetime,
  test_desc varchar(1024)
);

在这张表中灌入200w数据。

1.根据慢日志定位慢查询SQL

#查找慢日志
slow_query_log

记录慢日志SQL运行时间阈值

设置慢查询阈值为1秒,重连数据库 set global long_query_time = 1;

制造慢查询:

2.使用explain工具分析SQL explain select test_name from tb_test order by test_name desc

type:找到数据的方式,根据效率从高到低排序有如下几种

system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>all

如果type为index或all,表示本次扫描为全表扫描,说明这个语句是需要优化的。

extra:可以用来辅助type帮助我们进行SQL优化,extra中出现以下两项,意味着MySQL根本不能使用索引,效率会受到重大影响,应该尽可能对此进行优化。

Using filesort:表示MySQL会对结果使用一个外部索引排序,而不是从表里按索引次序读到相关内容,可能在内存或者磁盘上进行排序。MySQL中无法例用索引完成的排序操作称为“文件排序”。

Using temporary:表示MySQL在对查询结果排序时使用临时表,常见于排序 order by和分组查询group by。

3.修改SQL,尽量让SQL走索引

我们可以知道,创建表时,我们将id设为主键,那么id也就自然称为了索引,所以我们只要修改排序字段为id,即可以通过索引排序。

explain select test_id from tb_test order by test_id desc

key:PRIMARY 代表使用了主键索引

另一种情况,在特定状况下一定需要使用name进行排序,那还有一种做法,就是将name字段加索引。

#加索引
ALTER TABLE tb_test add index index_name(test_name);
#再次分析
explain select test_name from tb_test order by test_name desc;

结果:

联合索引的最左匹配原则的成因

上文中只是用了单一索引对表进行排序,如果使用联合索引又会是什么样的一种状况?
最左匹配原则:假设数据表中有两列,A and B,我们将A、B设置为联合索引,然后在where语句中调用where A = ? AND B = ?,该查询语句会使用AB联合索引,调用where A = ?,该查询语句也会使用AB联合索引,但当调用where B = ?时,它将不会使用AB联合索引。

官方定义:

1.最左前缀匹配原则,MySQL会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如 a=3 and b=4 and c>5 and d=6,如果建立(a,b,c,d)顺序的索引,d是无法使用索引的,如果建立(a,b,d,c)的索引则都可以使用到,a、b、d的顺序可以任意调整。
2.=和in可以乱序,比如 a=1 and b=2 and c=3 建立(a,b,c)索引可以任意顺序,MySQL的查询优化器会帮你优化成索引可以识别的形式。

索引是建立的越多越好吗

答:NO,数据量小的表不需要建立索引,建立会增加额外的索引开销。另外数据变更需要维护索引,因此更多的索引意味着更多的维护成本。更多的索引还需要消耗更多的空间。


锁 and 锁 and 锁

MyISAM与InnoDB关于锁方面的区别是什么

  1. MyISAM默认使用表级锁,不支持行级锁。
  2. InnoDB默认使用行级锁,也支持表级锁。

InnoDB在使用索引时,默认使用行级锁,但当其没有用到索引时,默认使用表级锁。

表级锁

当一条数据库语句对某条数据进行操作时,默认将整张表进行加锁,其余操作无法对表进行更改,需等到当前操作执行完毕释放锁后,才能对该表进行更改。

行级锁

当一条数据库语句对某条数据或多条数据进行操作时,默认将正在操作的这几条数据进行加锁,其余操作无法对当前语句正在操作的这几条数据进行操作,但可以操作其他数据。

共享锁和排他锁

共享锁:当对某行或某张表上了共享锁之后,其它任意语句依然支持上共享锁,但不支持上排他锁。(MySQL使用lock in share mode加共享锁)

排他锁:当对某行或某张表上了排他锁之后,其它任意语句对这一行或者这一张表进行读或写都是不允许的。(MySQL使用 for update 加排他锁)

乐观锁和悲观锁

悲观锁:总是假设最坏的情况,认为竞争总是存在,认为每次对数据的修改总会产生冲突,因此每次都会先上锁,其他线程阻塞等待释放锁。

乐观锁:总是假设最好的情况,认为竞争总是不存在,认为每次对数据的修改都不会产生冲突,因此不会先上锁,再最后更新的时候,比较数据是否已经被更新,可用版本号或CAS实现。

行级锁一定比表级锁优吗?

答:不一定,锁的粒度越细,其消耗的资源代价越高。行级锁在上锁的时候需要扫描到某行再进行上锁,这样的代价是较大的。

MyISAM和InnoDB各自适合的场景

MyISAM适合的场景:

  1. 频繁执行全表count语句。
  2. 对数据进行增删改的频率不高,查询非常频繁。
  3. 没有事务

InnoDB适合的场景:

  1. 数据增删改查都相当频繁。
  2. 可靠性要求比较高,存在事务。

数据库事务四大特性ACID

事务:作为单个逻辑单元执行的一个操作,要么全部完成,要么全部失败。

原子性

事务包含的所有操作,要么全部执行,要么全部失败。

隔离性

多个事务并发执行时,一个事务的执行不应该影响其它事务的执行。

一致性

事务应保证数据库状态从一个一致性状态转换到另一个一致性状态。(一致性状态:数据库的数据应满足完整性约束)

持久性

一个事务一旦提交,它的数据应该永久地保存在数据库中。

事务隔离级别以及各级别下的并发访问问题

    1. 更新丢失:一个事务的更新,引起另一个事务提交的丢失,MySQL所有事务隔离级别在数据库层面上均可避免。
    2. 脏读:一个事务读到另一个事务未提交的数据,READ-COMMITTED事务隔离级别以上可避免。(ORACLE默认隔离级别为READ-COMMITTED)
    3. 不可重复读:事务A多次读取同一数据时,事务B修改该数据,导致事务A每次读取到的数据结果不一致,REPEATABLE-READ隔离级别下可避免。
    4. 幻读:事务A多次读取同一数据时,事务B对事务A的影响区间内进行增删操作,导致事务A读取到的数据一会多、一会少,就像产生幻觉了一样。SERIALIZABLE事务隔离级别可避免。(但实际上MySQL的InnoDB在REPEATABLE-READ隔离级别下避免了幻读的发生)

InnoDB可重复读隔离级别下如何避免幻读

表象

快照读(非阻塞读)--伪MVCC。使用此种机制避免使我们看到“幻行”。

当前读:select …lock in share mode,select …for update,update,delete,insert.即加了锁的增删改查语句。由于其读取的是记录的最新版本,所以称为当前读。

快照读:不加锁的非阻塞读(非SERIALIZABLE),select。基于提升并发性能的考虑,基于多版本并发控制。既然是基于多版本,也就是说快照读有可能读到非最新版本的数据。

内在

next-key锁(行锁+gap锁):next-key锁由两部分组成,行锁+gap锁,行锁即对单个行记录上的锁。Gap锁,即对插入索引间的空隙上锁,即锁定一个范围,但不包括记录本身。

Gap锁的目的,是为了防止一个记录两次当前读出现幻读的情况。Gap锁只存在与Read-Committed(不包括Read-committed)以上的隔离级别存在。如果查询时,where条件全部命中(精确查询时),则不会用Gap锁,只会加记录锁。

因为在精确查询的状况下,即使在读结果集的过程中,另一个事务增加一条数据,也不会增加到当前结果集下,只会在where条件的范围之外,所以并不会产生幻读现象,加行锁就足够了。如果where条件部分命中或者全不命中,则会加Gap锁。

RC、RR级别下的InnoDB的非阻塞读(快照读)如何实现

1.数据行里的DB_TRX_ID、DB_ROLL_PTR、DB_ROW_ID字段,DB_TRX_ID标识最近一次对本行记录做修改的事务ID,DB_ROLL_PTR回滚指针,当事务回滚时,去往undo日志寻找上一版本的数据,DB_ROW_ID行号(MySQL自动创建的隐藏自增主键)。

2.undo日志:存储历史版本的数据。当某行的某个字段进行修改时,首先用排他锁锁住该行,然后将该行数据拷贝一份放入undolog中,通过行中的DB_ROLL_PTR指针,指向undolog中的这条数据,然后修改当前行的值,并填写DB_TRX_ID字段为当前事务的ID。

3.read view:可见性判断。决定当前事务能看到的是哪个版本的数据。

深入理解 Mysql 索引底层原理 一步一步推导出 Mysql 索引的底层数据结构。 Mysql 作为互联网中非常热门的数据库,其底层的存储引擎和数据检索引擎的设计非常重要,尤其是 Mysql 数据的存储形式以及索引的设计,决定了 Mysql 整体的数据检索性能。 我们知道,索引的作用是做数据的快速检索,而快速检索的实现的本质是数据结构。通过不同数据结构的选择,实现各种数据快速检索。在数据库中,高效的查找算法是非常重要的,因为数... 阅读详情

相关推荐

避坑指南:Livox Mid-360双雷达SLAM配置中,那些官方文档没说的细节(IP设置、话题分离与时间同步)

本文详细解析了Livox Mid-360双雷达SLAM配置中的关键优化点,包括IP设置、话题分离与时间同步等官方文档未提及的细节。通过实战案例和代码示例,帮助开发者解决点云错位、IMU数据混乱等问题,提升SLAM系统的稳定性和精度。特别针对网络架构设计、驱动修改和时间同步机制提供了专业指导。

weixin_29745609的博客 426

【从入门到入土】令人脱发的数据库底层设计

当你点击进这篇文章,你至少能明白一个事实——简简单单的数据库,和.......渐渐脱落的三千烦恼丝。

Object的博客 1146

从零开始:用ADS 2023手把手教你设计2.4GHz Wi-Fi LNA(基于ATF-54143,附模型文件)

本文详细介绍了如何使用ADS 2023软件设计2.4GHz Wi-Fi频段的低噪声放大器(LNA),基于ATF-54143晶体管。内容涵盖模型导入、直流工作点确定、稳定性优化、噪声匹配等关键步骤,并提供可下载的模型文件包,帮助工程师快速掌握LNA设计技巧。

weixin_42531128的博客 320

数据库作业——SQL总结

没想到已经过去了这么久,数据库课程也已经结束了基础篇第1~5章的学习,下面就对这一段时间的学习做一个总结,主要总结一些重点的内容。希望通过总结,可以重拾对知识的记忆,未来学着也更踏实。话不多说,开始干活! 第1章 绪论 一、数据库的4个基本概念 1.数据(data): 数据是数据库中存储的基本对象。描述事物的符号记录称为数据。数据的解释是指对数据含义的说明,数据的含义称为数据的语义,数据与其语义是不可分的。 2.数据库(DataBase,DB): 数据库时长期存储在计算机内、有组织的、可共享的大量数据的集合

xxxibgdrgn博客 6262

UVM和System verilog笔记总结(四)

virtual sequence 即虚seq,用于管理多个实sequence的执行顺序。 下面有三个sequence,此时需要virtual sequence去管理这三个的顺序。 virtual sequence和virtual sequencer需要成对写,使用例化实的sequence和sequencer控制: 此时在virtual sequence里面启动,而不是之前在test.sv里面用default或start函数启动。具体方法如下:先例化 再启动,用 `uvm_do_on 实sequence

weixin_42655118的博客 642

从零到一:AIC8800 USB-WiFi模块在Linux内核6.x下的驱动适配与避坑指南

本文详细介绍了AIC8800 USB-WiFi模块在Linux内核6.x下的驱动适配全流程,包括环境准备、源码编译、内核API变更处理及常见问题解决方案。重点针对驱动适配中的符号导出、设备ID识别和固件加载等核心挑战提供实用指南,帮助开发者高效完成硬件驱动兼容性调试。

k8l9m0n的博客 1026

数据库关系代数表达式

关系代数是关系数据库系统查询语言的理论基础。很有必要学习一下,有些是用代数表达式很方便的东西,用SQL写出来还是挺麻烦的,并不是想象当中那么直接。 一、关系代数的9种操作: 关系代数中包括了:并、交、差、乘、选择、投影、联接、除、自然联接等操作。 五个基本操作: 并(∪)、差(-)、笛卡尔积(×)、投影(σ)[Where]、选择(π)[Select] 四个组合操作: 交(∩)、 联接(等值联接):等值连接表示(1)先做笛卡尔积(×)之后,(2)对相应列进行选择或等值关联后的结果(仅筛选行、不筛选列)   

qq_34246965的博客 5万+

第58篇:AI技术实战:基于深度学习的智能音频内容审核系统

深度学习技术为智能音频内容审核系统提供了强大的支持,通过CNN、RNN和Transformer等模型,能够实现高效的音频内容检测和过滤。使用TensorFlow和Keras可以快速构建和训练音频审核模型,而预训练模型则可以进一步提升性能。数据预处理、特征提取和性能优化是提升智能音频审核系统性能的关键。希望本文的代码示例和注意事项能帮助你更好地理解和应用这些技术。接下来,我们将继续探索更多AI技术实战案例。

加入“Super Entity”,与全能开发团队共探AI智能体与数字人项目,开启前沿技术之旅。 708

数据库练习(16年12月13日)-- 牛客网

1.在一个关系R中,若每个数据项都是不可再分割的,那么R一定属于(第一范式) 解析:目前有迹可寻的共有8种范式,依次是:1NF,2NF,3NF,BCNF,4NF,5NF,DKNF,6NF。通常所用到的只是前三个范式,即:第一范式(1NF),第二范式(2NF),第 三范式(3NF)。下面就简单介绍下这三个范式。 ◆ 第一范式(1NF):强调的是列的原子性,即列不能够再分成其他几...

weixin_33849942的博客 179

1.FPGA开发软件安装——Vivado

目前主流的FPGA公司包括xilinx和Intel(原altera公司),其开发软件分别为vivado和quartusii。我们这里以目前国内应用较多的vivado为例进行安装讲解。 1、首先是去官网下载 Vivado 安装包:https://www.xilinx.com/support/download.html。下载这个最大的、支持所有的 OS 如 Windows/Linux 的安装包。 2、下载完之后,就进行解压。(最好在解压和安装之前都关闭所有的杀毒软件以防万一)。紧接着,解压完之后...

FPGA/MATLAB学习教程/源码/项目合作开发 8257

【人工智能】《Deep Dive into LLMs like ChatGPT 》—— Andrej Karpathy 第三阶段:强化学习(Reinforcement Learning, RL)

摘要:强化学习(RL)阶段通过让模型自主生成并验证答案,突破SFT阶段的模仿局限,使其在数学、代码等领域形成独特的推理路径。RL流程包括批量生成解答、自动批改筛选正确路径,并采用PPO/GRPO算法优化模型。模型会自发涌现自我检查、回滚等策略,显著提升正确率(如AIME竞赛准确率从15%升至56%)。与SFT模型相比,RL模型具备主动链式思维、验算能力,响应时间更长但效果更优,形成真正的“思考模型”。三阶段对比显示,RL通过可验证题的对错奖励机制,赋予模型超越人类范式的推理能力。

奶爸的编程之路,也就一周冷个三天 149

数据库 关系代数

一、概念 关系模型源于数学,关系是由元组构成的集合,可以通过关系的运算来表达查询要求 关系代数是关系操作语言的一种传统的表示方式,它是一种抽象的查询语言 关系代数的运算可分为两大类: 传统的集合运算: 广义笛卡尔积 并 交 差 专门的关系运算: 选择 投影 连接 除 二、传统的集合运算 1、符号 1)R,t ∈ R,t[Ai] 设关系模式为R(A1,A2,…,An) R是关系模式 R(A1,A2,…,An) 的一个关系 t ∈ R:表示 t 是 R 的一个元组 t[

土味儿 3329

Python爬虫实战:实时监控美国SEC官网文件更新,助你第一时间掌握市场动态

在资本市场中,信息就是财富。美国证券交易委员会(SEC)官网公开了大量公司披露文件,涵盖财报、招股说明书、内幕交易等重要信息。对投资者、分析师及法律合规人员来说,实时监控这些公开文件具有重要价值。

2201_76125261的博客 594

MySQL索引的底层原理详解

MySQL索引的底层原理基于B+树结构,这种结构通过平衡树的深度和有序存储,提供了高效的查询性能。InnoDB存储引擎的聚集索引和二级索引设计,进一步优化了数据存储和检索效率。理解这些原理,有助于在实际工作中优化数据库性能,提高查询效率。希望本文能够帮助读者深入理解MySQL索引的底层原理,并在实际应用中进行有效的性能优化。

MrxiaoAXiao的博客 807

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

mysql底层原理 书籍_深入理解 MySQL 索引底层原理

Mysql 作为互联网中非常热门的数据库,其底层的存储引擎和数据检索引擎的设计非常重要,尤其是 Mysql 数据的存储形式以及索引的设计,决定了 Mysql 整体的数据检索性能。我们知道,索引的作用是做数据的快速检索,而快速检索的实现的本质是数据结构。通过不同数据结构的选择,实现各种数据快速检索。在数据库中,高效的查找算法是非常重要的,因为数据库中存储了大量数据,一个高效的索引能节省巨大的时间。比...

weixin_35878962的博客 749

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

深入理解 MySQL 索引底层原理

Mysql 作为互联网中非常热门的数据库,其底层的存储引擎和数据检索引擎的设计非常重要,尤其是 Mysql 数据的存储形式以及索引的设计,决定了 Mysql 整体的数据检索性能。 我们知道,索引的作用是做数据的快速检索,而快速检索的实现的本质是数据结构。通过不同数据结构的选择,实现各种数据快速检索。在数据库中,高效的查找算法是非常重要的,因为数据库中存储了大量数据,一个高效的索引能节省巨大的时间。比如下面这个数据表,如果 Mysql 没有实现索引算法,那么查找 id=7 这个数据,那么只能采取暴力顺序遍历

Slayer_Zhao的博客 314

【Java架构师体系课 | MySQL篇】② 深入理解MySQL索引底层数据结构与算法

这一章其实也是一个老生常谈的面试题了,我们直接说答案,InnoDB的索引底层数据结构是B+树,那么为什么InnoDB的索引要采用B+树呢?我们先一步步来!!!

qq_38196449的博客 3268

【数据库索引底层原理:从B树到B+树的演进与高性能索引设计】

B+树是数据库索引的基石:其高度可控、适合磁盘存储、支持高效范围查询的特性,使其成为数据库索引的理想选择。聚簇索引与非聚簇索引各有优劣:聚簇索引适合主键查询和范围查询,非聚簇索引适合多维度查询,但需要注意回表开销。索引设计需要权衡多方面因素:包括查询性能、存储空间、维护成本等,不存在通用的最优方案。索引优化是一个持续的过程:需要根据实际查询模式和数据分布不断调整优化。

m0_64006292的博客 647

深度理解mysql索引

Mysql 作为互联网中非常热门的数据库,其底层的存储引擎和数据检索引擎的设计非常重要,尤其是 Mysql 数据的存储形式以及索引的设计,决定了 Mysql 整体的数据检索性能。 我们知道,索引的作用是做数据的快速检索,而快速检索的实现的本质是数据结构。通过不同数据结构的选择,实现各种数据快速检索。在数据库中,高效的查找算法是非常重要的,因为数据库中存储了大量数据,一个高效的索引能节省巨大的时间。比如下面这个数据表,如果 Mysql 没有实现索引算法,那么查找 id=7 这个数据,那么只能采取暴力顺序遍历

HANG.NIAN 455

【MYSQL数据库一】基本概念、控制语句、底层数据结构

使用SQL语句,可以完成对数据库信息的检索、更新数据库信息、修改表结构,标准的SQL语句有五种类型。** 查询语句**:数据库查询语句,通常用select完成,查询数据库信息。DDL语句:数据库定义语句,通常由drop、create、alter、truncate组成。DCL语句:数据库控制语句,通常由grant、revoke两个关键字组成,DCL语句一般用于对数据库用户授权或者指定用户权限的回收。DML语句:数据库操作语句,通常由insert、update、delete构成。事务控制语句。.........

xwl137487622的博客 720

MySQL 索引底层原理剖析:B+ 树结构、索引创建维护与性能优化策略全解读

本文深入剖析 MySQL 索引底层原理,重点讲解 B+ 树结构特点及优势,阐述索引创建与维护过程。同时,给出索引性能优化策略,包括选择合适索引列、设计复合索引、避免索引失效及定期优化索引等,助力读者掌握索引核心技术,提升数据库查询性能与查找效率。

大模型全栈工程师 · Thanks_ks 1108

MySQL如何快速查询海量数据?彻底搞懂索引的底层原理

MySQL索引原理详解:用字典目录类比,深入解析B+树结构与二级索引机制。索引本质是以空间换时间,通过B+树实现高效查询,其矮胖结构仅需2-3次I/O即可定位亿级数据。重点剖析二级索引的回表问题及覆盖索引优化方案,提供索引设计口诀:高频/高选择性字段优先,遵循最左匹配原则,避免LIKE'%xx'和函数操作。掌握索引能显著提升百万级数据查询速度,是解决90%数据库性能问题的关键。

大四在找工作,如果公司有需要的可以联系我13086825462@163.com 947

MySQL索引

覆盖索引是指一个索引包含了查询所需的所有字段,而不需要回表查询原始数据。例如,假设我们有一个用户表,包含了用户的id,姓名,年龄,性别等字段,我们想要查询所有年龄大于18岁的用户的姓名和性别,那么我们可以创建一个包含了姓名,性别和年龄的索引,这样就可以直接从索引中获取查询结果,而不需要再访问用户表。覆盖索引的优点是:- 减少了磁盘I/O,提高了查询速度- 减少了内存占用,节省了资源- 减少了锁的竞争,提高了并发能力,它可以避免回表查询原始数据,从而减少了对数据行的访问和锁定。

Atuto的博客 179

MySQL 索引详解:从基础到原理

MySQL索引详解摘要 本文全面介绍了MySQL索引的核心概念、类型及优化策略。主要内容包括: 索引概述:定义、作用与代价 常见索引类型:普通索引、唯一索引、主键索引、复合索引、全文索引和空间索引 底层数据结构:B-Tree/B+Tree索引原理,InnoDB的聚簇/辅助索引结构 优化策略:最左前缀原则、索引选择性与基数分析、避免索引失效的方法 通过SQL示例和原理分析,帮助开发者合理设计索引以提升查询性能。

三两肉的博客 1194

MySQL学习笔记:索引和数据库设计

数据库的索引,可以理解成字典的目录,是为了方便数据库快速查询数据用的。为什么创建索引,查询速度会更快?创建索引的过程,是创建数据结构,提高查询速度。如果创建索引,数据库根据引擎的不同,会通过B+tree(MySQL innnoDB默认)、哈希表等数据结构的方式构建索引。比如用B+tree,要查询student_name为王二麻子的记录,只需要几次就可以查到。有哪几种索引?

qq_17862337的博客 719

深入理解MySQL索引底层数据结构与算法

在日常开发中,我们经常遇到这样的场景:一张千万级数据量的用户表,一个简单的查询语句竟然需要运行几十秒甚至更久。而加上合适的索引后,查询时间瞬间降到了毫秒级别。这种性能上的巨大差异,背后究竟隐藏着什么样的技术秘密?索引的本质,是在空间换时间的策略下,为数据查询构建的加速结构。理解索引的底层原理,不仅能帮助我们写出高效的SQL,更能在系统设计和性能优化时做出正确的技术决策。本文将从数据结构的角度,深入剖析MySQL索引的设计哲学和实现细节,并通过实际场景对比,让你真正掌握索引的精髓。选择性原则。

零陵上将军_xdr的博客 432
上一篇: 网络编程—IO多路复用详解
下一篇: IM(即时通讯)服务端(上)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值