三胖不姓金 發表於 2025-12-30 09:23:00

对线面试官系列:MySQL 常见面试题,你能答对几道?

<p>@</p><div class="toc"><div class="toc-container-header">目录</div><ul><li>前言</li><li>背景</li><li>1. 什么是存储过程?有哪些优缺点?</li><li>2. 数据库三个范式是什么</li><li>3.索引是什么?有什么作用以及优缺点?</li><li>4.什么时候要创建索引?</li><li>5.索引分类有哪些?</li><li>6. 索引的数据结构:</li><li>7. 为什么使用B+Tree作为索引:</li><li>8. MySQL 索引底层结构为什么使用 B+树?</li><li>9. B+ 树的叶子节点链表是单向还是双向?</li><li>10.MySQL主从复制的原理:</li><li>11.Mysql主从复制的好处</li><li>12.Mysql主从数据源的配置</li><li>13.主键一般用自增ID还是UUID?</li><li>14.什么是ACID事务?</li><li>15.   MySQL中四种隔离级别分别是什么?</li><li>16.   数据库的乐观锁和悲观锁是什么?</li><li>17.   Mysql存储引擎?</li><li>18.   Varchar和Char的区别?</li><li>19.   Mysql中表锁和行锁的区别</li><li>20.MySQL和Oracle在操作上的一些区别?</li><li>21. MVCC (多版本并发控制)</li><li>总结</li></ul></div><p></p>
<hr>
<h1 id="前言">前言</h1>
<p><font color="#999AAA">请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i、</font>微信公众号:<strong><code>白码梦想家</code></strong></p>
<p><code>提示:以下是本篇文章正文内容,下面案例可供参考</code></p>
<h1 id="背景">背景</h1>
<blockquote>
<p>Hello 朋友们,接下来为大家开启,<strong>面试题相关系列☞《对线面试官》</strong> <code>自信出击,让 offer 手到擒来!!!</code></p>
</blockquote>
<h1 id="1-什么是存储过程有哪些优缺点">1. 什么是存储过程?有哪些优缺点?</h1>
<p>存储过程就像我们编程语言中的函数一样,封装了我们的代码(PLSQL、T-SQL)。</p>
<ul>
<li>
<p><strong><code>存储过程的优点</code></strong>:<br>
1.能够将代码封装起来<br>
2.保存在数据库之中<br>
3.让编程语言进行调用<br>
4.存储过程是一个预编译的代码块,执行效率比较高</p>
</li>
<li>
<p><strong><code>存储过程的缺点</code></strong>:<br>
1.每个数据库的存储过程语法几乎都不一样,十分难以维护(不通用)<br>
2.业务逻辑放在数据库上,难以迭代</p>
</li>
</ul>
<h1 id="2-数据库三个范式是什么">2. 数据库三个范式是什么</h1>
<p><strong>第一范式:</strong> 字段是最小的的单元不可再分<br>
<strong>第二范式:</strong> 满足第一范式,表中的字段必须完全依赖于全部主键而非部分主键。(主键是唯一的,它们只需要依赖于主键,也就成了唯一的)<br>
<strong>第三范式:</strong> 满足第二范式,非主键外的所有字段必须互不依赖。(就是数据只在一个地方存储,不重复出现在多张表中)</p>
<h1 id="3--索引是什么有什么作用以及优缺点">3.索引是什么?有什么作用以及优缺点?</h1>
<p>(1)是一种快速查询表中内容的机制,类似于新华字典的目录<br>
(2)运用在表中某个些字段上,但存储时,独立于表之外<br>
<strong><code>优点:</code></strong> 索引加快数据库的检索速度<br>
<strong><code>缺点:</code></strong> 索引降低了插入、删除、修改等维护任务的速度(虽然索引可以提高查询速度,但是它们也会导致数据库系统更新数据的性能下降,因为大部分数据更新需要同时更新索引)</p>
<h1 id="4--什么时候要创建索引">4.什么时候要创建索引?</h1>
<p>(1)表经常进行 SELECT 操作<br>
(2)表很大(记录超多),记录内容分布范围很广<br>
(3)列名经常在 WHERE 子句或连接条件中出现</p>
<h1 id="5--索引分类有哪些">5.索引分类有哪些?</h1>
<p><strong>唯一索引、主键索引、聚集索引、非聚集索引</strong></p>
<ul>
<li>
<p><strong><code>主键索引</code>:</strong> 它 是一种特殊的唯一索引,不允许有空值。</p>
</li>
<li>
<p><strong><code>唯一索引:</code></strong> 与"普通索引"类似,不同的就是:索引列的值必须唯一,但允许有空值。</p>
</li>
<li>
<p><strong><code>普通索引:</code></strong> 普通索引 (由关键字KEY或INDEX定义的索引) 的唯一任务是加快对数据的访问速度。</p>
</li>
<li>
<p><strong><code>全文索引:</code></strong> 只能作用MyISAM在CHAR、VARCHAR、TEXT、类型的字段上。创建全文索引需要使用FULLTEXT参数进行约束。</p>
</li>
<li>
<p><strong><code>联合索引:</code></strong> 遵循最左前缀’原则,简单的理解就是只从最左面的开始组合,查询时使用字段中的第一个字段,索引才会被使用。覆盖索引,减少查询次数</p>
</li>
<li>
<p><strong><code>空间索引:</code></strong> 只有 MyISAM 类型的表支持该类型 ‘ 空间索引 ’。而且,索引字段必须有非空约束。</p>
</li>
</ul>
<h1 id="6-索引的数据结构">6. 索引的数据结构:</h1>
<ul>
<li>常见的索引的数据结构有:<strong><code>B+Tree、Hash索引</code></strong>。</li>
</ul>
<ul>
<li>
<p><strong>Hash索引</strong>:<br>
MySQL中只有Memory存储引擎支持hash索引,是Memory表的默认索引类型。hash索引把数据以hash值形式组织起来,因此查询效率非常高,可以一次定位。<br>
hash索引的缺点:<br>
Hash索引仅能满足等值的查询,不能满足范围查询、排序。因为数据在经过Hash算法后,其大小关系就可能发生变化。</p>
</li>
<li>
<p><strong>B+Tree索引</strong>:<br>
B+Tree是mysql使用最频繁的一个索引数据结构,是Innodb和Myisam存储引擎模式的索引类型。<br>
B+Tree索引在查找时需要从根节点到叶节点进行多次IO操作,在查询速度比不上Hash索引,但是更适合排序等操作。</p>
</li>
</ul>
<h1 id="7-为什么使用btree作为索引">7. 为什么使用B+Tree作为索引:</h1>
<p>页内节点不存储内容,<code>每次IO可以读取更多的行,大大减少磁盘I/O读取次数</code><br>
换句话说,索引的数据结构要尽量<code>减少查找过程中磁盘I/O的存取次数</code>。</p>
<h1 id="8-mysql-索引底层结构为什么使用-b树">8. MySQL 索引底层结构为什么使用 B+树?</h1>
<p><strong><code>Hash索引</code></strong> 虽然能够提供 O(1) 的单数据行操作性能,但是对于范围查询和排序却无法很好地支<br>
持,最终导致全表扫描;<br>
<strong><code>B 树</code></strong> 能够在非叶节子点中存储数据,但是这也导致在查询连续数,据时可能会带来更多的随机 I/O;<br>
<strong><code>B+树</code></strong> 的所有叶节点是通过链表指针相互连接,能够减少顺序遍历时产生的额外随机 I/O;</p>
<ul>
<li>
<p>第一,B 树一个节点里存的是数据,而 B+树存储的是索引(地址),所以 B 树里一个节<br>
点存不了很多个数据,但是 B+树一个节点能存很多索引,B+树叶子节点存所有的数据。</p>
</li>
<li>
<p>第二,B+树的叶子节点是数据阶段用了一个链表串联起来,便于范围查找</p>
</li>
</ul>
<h1 id="9-b-树的叶子节点链表是单向还是双向">9. B+ 树的叶子节点链表是单向还是双向?</h1>
<p>双向链表</p>
<h1 id="10--mysql主从复制的原理">10.MySQL主从复制的原理:</h1>
<p>Slave从Master获取binlog二进制日志文件,然后再将日志文件解析成相应的SQL语句在从服务器上重新执行一遍主服务器的操作,通过这种方式来保证数据的一致性。<br>
由于主从复制的过程是异步复制的,因此Slave和Master之间的数据有可能存在延迟的现象,只能保证数据最终的一致性。</p>
<h1 id="11--mysql主从复制的好处">11.Mysql主从复制的好处</h1>
<p>(1)<strong>读写分离</strong>,通过动态增加从服务器来提高数据库的性能,在主服务器上执行写入和更新,在从服务器上执行读功能。<br>
(2)<strong>提高数据安全</strong>,因为数据已复制到从服务器,从服务器可以终止复制进程,所以,可以在从服务器上备份而不破坏主服务器相应数据。<br>
(3)<strong>在主服务器上生成实时数据</strong>,而在从服务器上分析这些数据,从而提高主服务器的性能</p>
<p>通过主从复制可以实现数据备份、故障转移、MySQL集群、高可用、读写分离等。</p>
<h1 id="12--mysql主从数据源的配置">12.Mysql主从数据源的配置</h1>
<p>我们需要配置主从数据库,主从数据库的配置一般都是写在配置文件里面。通过@ConfigurationProperties注解,可以将配置文件<br>
(一般命名为:application.Properties)里的属性映射到具体的类属性上,从而读取到写入的值注入到具体的代码配置中,按照习惯大于约定的原则,<br>
主库我们都是注为master,从库注为slave,本项目采用了阿里的druid数据库连接池,使用build建造者模式创建DataSource对象,DataSource就是<br>
代码层面抽象出来的数据源,接着需要配置sessionFactory、sqlTemplate、事务管理器等</p>
<h1 id="13--主键一般用自增id还是uuid">13.主键一般用自增ID还是UUID?</h1>
<ul>
<li>
<p><strong>使用UUID的优点</strong>:<br>
无需担心业务量泄露的问题。<br>
唯一标识,不用考虑重复问题,在数据拆分、合并时也能达到全局的唯一性。</p>
</li>
<li>
<p><strong>UUID的缺点</strong>:<br>
因为UUID是随机生成的,所以会发生随机IO,影响插入速度,并且会造成硬盘的使用率较低。<br>
UUID占用空间较大,建立的索引越多,造成的影响越大。<br>
UUID之间比较大小较自增ID慢不少,影响查询速度。</p>
</li>
<li>
<p><strong>自增ID的优点</strong>:<br>
字段长度较 UUID 会小很多。<br>
数据库自动编号,按顺序存放,利于检索</p>
</li>
<li>
<p><strong>自增ID的缺点</strong>:<br>
因为是自增,在某些业务场景下,容易被其他人查到业务量。<br>
发生数据迁移时,或者表合并时会非常麻烦<br>
在高并发的场景下,竞争自增锁会降低数据库的吞吐能力</p>
</li>
</ul>
<p>1、项目是单机版的,并且数据量比较大(百万级)时,用自增长的,此时最好能考虑下安全性,做些安全措施。<br>
2、项目是单机版的,并且数据量没那么大,对速度和存储要求不高时,用UUID。<br>
3、项目是分布式的,那么首选UUID,分布式一般对速度和存储要求不高。<br>
4、项目是分布式的,并且数据量达到千万级别可更高时,对速度和存储有要求时,可以用自增长。</p>
<h1 id="14--什么是acid事务">14.什么是ACID事务?</h1>
<p>ACID包含:<br>
<code>原子性(Atomicity):</code>一个事务中的所有操作,要么全部完成,要么全部不完成<br>
<code>一致性(Consistency):</code>在事务开始之前和事务结束以后,数据库的完整性没有被破坏<br>
<code>隔离性(Isolation):</code>多个并发事务同时,其事务对彼此不可见<br>
<code>持久性(Durability):</code>事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失</p>
<h1 id="15---mysql中四种隔离级别分别是什么">15.   MySQL中四种隔离级别分别是什么?</h1>
<p><strong>读未提交</strong>:未提交读隔离级别也叫<strong>脏读</strong>,就是事务可以读取其它事务未提交的数据。</p>
<p><strong>读已提交</strong>:在其它数据库系统比如 SQL Server 默认的隔离级别就是提交读,已提交读隔离级别就是在事务未提交之前所做的修改其它事务是不可见的。</p>
<p><strong>可重复读</strong>:保证同一个事务中的多次相同的查询的结果是一致的,可重复读也是 MySQL的默认隔离级别。</p>
<p><strong>可串行化</strong>:同一数据读写都加锁,避免脏读,性能不忍直视。</p>
<h1 id="16---数据库的乐观锁和悲观锁是什么">16.   数据库的乐观锁和悲观锁是什么?</h1>
<p>确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性,乐观锁和悲观锁是并发控制主要采用的技术手段。</p>
<ul>
<li><code>乐观锁:</code><br>
在修改数据的时候把事务锁起来,通过version的方式来进行锁定</li>
<li><strong>实现方式:</strong> 每次添加修改时使用version版本号或者时间戳</li>
<li><code>悲观锁:</code><br>
在查询完数据的时候就把事务锁起来,直到提交事务</li>
<li><strong>实现方式:</strong> 使用数据库中的锁机制</li>
</ul>
<h1 id="17---mysql存储引擎">17.   Mysql存储引擎?</h1>
<p><strong>Innodb引擎</strong>,Innodb引擎提供了对数据库ACID事务的支持。并且还提供了行级锁和外键的约束。它的设计的目标就是处理大数据容量的数据库系统。<br>
<strong>MyIASM引擎</strong>(原本Mysql的默认引擎),不提供事务的支持,也不支持行级锁和外键。<br>
<strong>MEMORY引擎</strong>:所有的数据都在内存中,数据的处理速度快,但是安全性不高。</p>
<h1 id="18---varchar和char的区别">18.   Varchar和Char的区别?</h1>
<p>Char是一种固定长度的类型,varchar是一种可变长度的类型</p>
<h1 id="19---mysql中表锁和行锁的区别">19.   Mysql中表锁和行锁的区别</h1>
<ul>
<li>
<p><strong><code>行锁</code></strong><br>
特点:锁的粒度小,发生锁冲突的概率低、处理并发的能力强;开销大、加锁慢、会出现死锁<br>
加锁的方式:自动加锁。对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁;对于普通SELECT语句,InnoDB不会加任何锁。</p>
</li>
<li>
<p><strong><code>表锁</code></strong><br>
特点:开销小、加锁快、无死锁;锁粒度大,发生锁冲突的概率高,高并发下性能低</p>
</li>
</ul>
<h1 id="20--mysql和oracle在操作上的一些区别">20.MySQL和Oracle在操作上的一些区别?</h1>
<ul>
<li>
<p>1、<strong>主键</strong><br>
MySQL 一般使用自动增长类型主键,在创建表时只要指定表的主键为auto increment,插入记录时,不需要再指定该记录的主键值,MySQL将自动增长。<br>
Oracle没有自动增长类型,需要自增主键时一般使用的序列,插入记录时将 序列号的下一个值付给该字段即可。如果不需要使用自增主键,一般会选择使用全剧唯一的流水号作为Oracle数据库的主键。</p>
</li>
<li>
<p>2、<strong>分页查询</strong><br>
MySQL一般使用limit关键字进行分页查询,有时候也可以利用自增主键加order by 命令加 limit进行分页查询<br>
Oracle处理翻页的SQL语句就比较繁琐了。每个结果集只有一个ROWNUM字段标明它的位置, 并且只能用ROWNUM&lt;?, 不能用ROWNUM&gt;?,需要大于则要用到别名来进行处理</p>
</li>
<li>
<p>3、<strong>权限与安全</strong><br>
在Oracle中有一个用户的概念,用来登录到数据库,比如openlab用户。用户拥有一定的权限,可以创建表、视图等。用户名下的数据表,安全性高于MySQL。<br>
MySQL中对应于Oracle中用户的概念是database。登陆后要先建立database,才能建表。MySQL的用户与主机有关,很容易被仿冒。</p>
</li>
</ul>
<h1 id="21-mvcc-多版本并发控制">21. MVCC (多版本并发控制)</h1>
<p><strong>实现细节</strong><br>
每行数据都存在一个版本,每次数据更新时都更新该版本。<br>
修改时 Copy 出当前版本随意修改,各个事务之间互不干扰。<br>
保存时比较版本号,如果成功(commit),则覆盖原记录;失败则放弃 copy(rollback)。<br>
<strong>Inno DB 实现</strong><br>
在 InnoDB 中为每行增加两个隐藏的字段,分别是该行数据创建时的版本号和删除时的版本号,<br>
这里的版本号是系统版本号(可以简单理解为事务的 ID),每开始一个新的事务,系统版本号就自动递增,作为事务的 ID 。<br>
通常这两个版本号分别叫做创建时间和删除时间。</p>
<h1 id="总结">总结</h1>
<hr style="border: solid; width: 100px; height: 1px" color="#000000" size="1&quot;">
<p>我是南国以南i记录点滴每天成长一点点,学习是永无止境的!转载请附原文链接!!!</p><br><br>
来源:https://www.cnblogs.com/bgyb/p/19417423
頁: [1]
查看完整版本: 对线面试官系列:MySQL 常见面试题,你能答对几道?