mysql 面试总结

164.数据库的三范式是什么?

1.确保每列的原子性,如果每列都是不可再分的最小数据单元,则满足第一范式

2.每张表只描述一件事情

3.不存在对非主键列的传递依赖

165.一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 mysql 数据库,又插入了一条数据,此时 id 是几?

166.说一下 ACID 是什么?

原子性,一致性,隔离性,持久性

  1. char 和 varchar 的区别是什么?

1、char的长度是不可变的,而varchar的长度是可变的

字段b:类型char(10),     值为:abc,存储为:abc             (abc+7个空格)

字段d:类型varchar(10), 值为:abc,存储为:abc (自动变为3个的长度)

2、超出长度自动截取

字段c:类型char(3),     值为:abcdefg,存储为:abc(defg自动删除)

字段e:类型varchar(3), 值为:abcdefg,存储为:abc (defg自动删除)

3、var(10)和char(10),都表示可存10个字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),都可以存放10个

4、char最多可以存放255个字符

varchar的最大长度为65535个字节,varchar可存放的字符数跟编码有关

字符类型若为gbk,每个字符最多占2个字节,最大长度不能超过32766个字符

字符类型若为utf8,每个字符最多占3个字节,最大长度不能超过21845个字符

5、char和varchar的最大长度限制是mysql规定的

  1. float 和 double 的区别是什么?

float 单精度浮点数在机内占 4 个字节,用 32 位二进制描述。

double 双精度浮点数在机内占 8 个字节,用 64 位二进制描述。

  1. mysql 的内连接、左连接、右连接有什么区别?

167.数据库事务隔离级别

读未提交,读已提交,可重复读,可串行化

Mysql 默认为可重复读

  1. mysql有哪些索引?

普通索引:即一个索引只包含单个列,一个表可以有多个单列索引

唯一索引:索引列的值必须唯一,但允许有空值

复合索引:即一个索引包含多个列

聚簇索引(聚集索引):并不是一种单独的索引类型,而是一种数据存储方式。具体细节取决于不同的实现,InnoDB的聚簇索引其实就是在同一个结构中保存了B-Tree索引(技术上来说是B+Tree)和数据行。

非聚簇索引:不是聚簇索引,就是非聚簇索引

簇索引:将数据存储和索引放在一起、并且是按照一定的顺序组织的,找到索引也就找到了数据,数据的物理存放顺序与索引顺序是一致的,即:只要索引是相邻的,那么对应的数据一定也是相邻的存放在磁盘上的。

171.mysql 索引是怎么实现的?

172.怎么验证 mysql 的索引是否满足需求?

173.回表与覆盖索引,索引下推?

一、什么是回表查询?

通俗的讲就是,如果索引的列在 select 所需获得的列中(因为在 mysql 中索引是根据索引列的值进行排序的,所以索引节点中存在该列中的部分值)或者根据一次索引查询就能获得记录就不需要回表,如果 select 所需获得列中有大量的非索引列,索引就需要到表中找到相应的列的信息,这就叫回表。

InnoDB聚集索引的叶子节点存储行记录,因此, InnoDB必须要有,且只有一个聚集索引:

  1. 如果表定义了主键,则PK就是聚集索引;
    (2)如果表没有定义主键,则第一个非空唯一索引(not NULL unique)列是聚集索引;
    (3)否则,InnoDB会创建一个隐藏的row-id作为聚集索引;

二、什么是索引覆盖?

只需要在一棵索引树上就能获取SQL所需的所有列数据,无需回表,速度更快。explain的输出结果Extra字段为Using index时,能够触发索引覆盖。

https://www.jianshu.com/p/d0d3de6832b9

三、如何实现索引覆盖?

1、常见的方法是:将被查询的字段,建立到联合索引里去。


 

174.说一下 mysql 常用的引擎?

InnoDB 与MyISAM

查看MySQL提供的所有存储引擎

mysql> show engines;

Mysql 中 MyISAM 和 InnoDB 的区别有哪些?

InnoDB支持事务,MyISAM不支持

对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,

所以最好把多条SQL语言放在begin和commit之间,组成一个事务;

InnoDB支持外键,而MyISAM不支持。

对一个包含外键的InnoDB表转为MYISAM会失败;

InnoDB是聚集索引,数据文件是和索引绑在一起的,必须要有主键,通过主键索引效率很高。

但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。

因此主键不应该过大,因为主键太大,其他索引也都会很大。

而MyISAM是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。

主键索引和辅助索引是独立的。

InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。

而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;

Innodb不支持全文索引,而MyISAM支持全文索引,查询效率上MyISAM要高;

是否支持行级锁

MyISAM 只有表级锁(table-level locking),

而InnoDB 支持行级锁(row-level locking)和表级锁,默认为行级锁。

是否支持事务和崩溃后的安全恢复

MyISAM 强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。

但是InnoDB 提供事务支持事务,外部键等高级数据库功能。

具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。

是否支持MVCC :

仅 InnoDB 支持。应对高并发事务, MVCC比单纯的加锁更高效;

MVCC只在 READ COMMITTED 和 REPEATABLE READ 两个隔离级别下工作;

MVCC可以使用 乐观(optimistic)锁 和 悲观(pessimistic)锁来实现;各数据库中MVCC实现并不统一

如何选择:

是否要支持事务,如果要请选择innodb,如果不需要可以考虑MyISAM;

如果表中绝大多数都只是读查询,可以考虑MyISAM,如果既有读写也挺频繁,请使用InnoDB

系统奔溃后,MyISAM恢复起来更困难,能否接受;

MySQL5.5版本开始Innodb已经成为Mysql的默认引擎(之前是MyISAM),说明其优势是有目共睹的,

如果你不知道用什么,那就用InnoDB,至少不会差。


查看MySQL提供的所有存储引擎

mysql> show engines;

查看MySQL当前默认的存储引擎

我们也可以通过下面的命令查看默认的存储引擎。

mysql> show variables like '%storage_engine%';

查看表的存储引擎

show table status like "table_name" ;

  1. 说一下 mysql 的行锁和表锁?

  1. 说一下乐观锁和悲观锁? 

177.mysql 索引实现原理? 

索引(Index)是帮助MySQL高效获取数据的数据结构

索引实现原理(b+树)

MyISAM 索引实现 

MyISAM 引擎使用 B+Tree 作为索引结构,叶节点的 data 域存放的是数据记录的地址。

辅助索引 

在 MyISAM 中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求 key 是唯一的,而辅助索引的 key 可以重复。如果我们在 Col2 上建立一个辅助索引,则此索引的结构

InnoDB 索引实现

虽然 InnoDB 也使用 B+Tree 作为索引结构,但具体实现方式却与 MyISAM 截然不同。

1.第一个重大区别是 InnoDB 的数据文件本身就是索引文件。从上文知道,MyISAM 索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。

而在InnoDB 中,表数据文件本身就是按 B+Tree 组织的一个索引结构,这棵树的叶点data 域保存了完整的数据记录。这个索引的 key 是数据表的主键,因此 InnoDB 表数据文件本身就是主索引。

2.第二个与 MyISAM 索引的不同是 InnoDB 的辅助索引 data 域存储相应记录主键的值而不是地址。换句话说,InnoDB 的所有辅助索引都引用主键作为 data 域。

178.如何做 mysql 的性能优化?

179. Buffer Pool在数据库里的地位

Buffer Pool的一句话总结

Buffer Pool是数据库中我们第一个必须要搞清楚的核心组件,因为增删改操作首先就是针对这个内存中的Buffer Pool里的数据执行的,同时配合了后续的redo log、刷磁盘等机制和操作。

所以Buffer Pool就是数据库的一个内存组件,里面缓存了磁盘上的真实数据,然后我们的系统对数据库执行的增删改操作,其实主要就是对这个内存数据结构中的缓存数据执行的。

1、如何配置你的Buffer Pool的大小?

我们应该如何配置你的Buffer Pool到底有多大呢? 因为Buffer Pool本质其实就是数据库的一个内存组件,你可以理解为他就是一片内存数据结构,所以这个内存数据结构肯定是有一定的大小的,不可能是无限大的。 这个Buffer Pool默认情况下是128MB,还是有一点偏小了,我们实际生产环境下完全可以对Buffer Pool进行调整。 比如我们的数据库如果是16核32G的机器,那么你就可以给Buffer Pool分配个2GB的内存,使用下面的配置就可以了。 [server] innodb_buffer_pool_size = 2147483648 如果你不知道数据库的配置文件在哪里以及如何修改其中的配置,那建议可以先在网上搜索一些MySQL入门的资料去看看,其实这都是最基础和简单的。 我们先来看一下下面的图,里面就画了数据库中的Buffer Pool内存组件

原文链接:

https://www.cnblogs.com/wxlevel/p/12995324.html

  1. 一条数据库语句的执行流程

179.MVCC解析

MVCC(MultiVersion Concurrency Control)叫做多版本并发控制。在小编这个被病毒封在家的冬天,在《高性能MySQL》这本书上看到过一段对于MVCC很详细的解释:“InnoDB(MySQL数据库的引擎之一)的MVCC,是通过在每行记录的后面保存两个隐藏的列来实现的,其中一个列保存行的创建时间,一个列保存了行的过期时间,当然存储的并不是实际的时间值,而是系统的版本号。”简单说来实现是想就是通过数据的多版本来做到读写分离的操作,从而就可以做到不加锁读进而做到读写并行。而MySQL在mysql实现依赖的就是undo log和read view。其中undo log中有其中undo log中有记录某行数据的多个版本数据,read view可以用来判断当前版本数据的可见性

180 数据库事务实现

原子性:主要依靠undo.log日志实现,即在事务失败时执行回滚。undo.log日志会记录事务执行的sql,当事务需要回滚时,通过反向补偿回滚数据库状态

持久性:主要依靠redo.log日志实现。首先,mysql持久化通过缓存来提高效率,即在select时先查缓存,再查磁盘;在update时先更新缓冲,再更新磁盘。以减少磁盘io次数,提高效率。但由于缓存断电就没了,所以需要redo.log日志。在执行修改操作时,sql会先写入到redo.log日志,再写入缓存中。这样即使断电,也能保证数据不丢失,达到持久性

隔离性:我的理解就是多线程时多事务之间互相产生了影响,要避免这个影响,那就加锁。mysql的锁有表锁,行锁,间隙锁,好像还有一个锁数据库的,叫全局锁还是什么来着。写写操作通过加锁实现隔离性,亵渎操作通过MVCC实现

一致性:就是事务再执行的前和后数据库的状态都是正常的,表现为没有违反数据完整性,参照完整性和用户自定义完整性等等。而上面三种特性就是为了保证数据库的有一致性

18Mysql 里的各种锁

 

182 .数据库的隔离级别有哪些

读未提交,读已提交,可重复读,可串行化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值