164.数据库的三范式是什么?
1.确保每列的原子性,如果每列都是不可再分的最小数据单元,则满足第一范式
2.每张表只描述一件事情
3.不存在对非主键列的传递依赖
165.一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 mysql 数据库,又插入了一条数据,此时 id 是几?
166.说一下 ACID 是什么?
原子性,一致性,隔离性,持久性
- 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规定的
- float 和 double 的区别是什么?
float 单精度浮点数在机内占 4 个字节,用 32 位二进制描述。
double 双精度浮点数在机内占 8 个字节,用 64 位二进制描述。
- mysql 的内连接、左连接、右连接有什么区别?
167.数据库事务隔离级别
读未提交,读已提交,可重复读,可串行化
Mysql 默认为可重复读
- mysql有哪些索引?
普通索引:即一个索引只包含单个列,一个表可以有多个单列索引
唯一索引:索引列的值必须唯一,但允许有空值
复合索引:即一个索引包含多个列
聚簇索引(聚集索引):并不是一种单独的索引类型,而是一种数据存储方式。具体细节取决于不同的实现,InnoDB的聚簇索引其实就是在同一个结构中保存了B-Tree索引(技术上来说是B+Tree)和数据行。
非聚簇索引:不是聚簇索引,就是非聚簇索引
聚簇索引:将数据存储和索引放在一起、并且是按照一定的顺序组织的,找到索引也就找到了数据,数据的物理存放顺序与索引顺序是一致的,即:只要索引是相邻的,那么对应的数据一定也是相邻的存放在磁盘上的。
171.mysql 索引是怎么实现的?
172.怎么验证 mysql 的索引是否满足需求?
173.回表与覆盖索引,索引下推?
一、什么是回表查询?
通俗的讲就是,如果索引的列在 select 所需获得的列中(因为在 mysql 中索引是根据索引列的值进行排序的,所以索引节点中存在该列中的部分值)或者根据一次索引查询就能获得记录就不需要回表,如果 select 所需获得列中有大量的非索引列,索引就需要到表中找到相应的列的信息,这就叫回表。
InnoDB聚集索引的叶子节点存储行记录,因此, InnoDB必须要有,且只有一个聚集索引:
- 如果表定义了主键,则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" ;
- 说一下 mysql 的行锁和表锁?
- 说一下乐观锁和悲观锁?
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
- 一条数据库语句的执行流程
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 .数据库的隔离级别有哪些
读未提交,读已提交,可重复读,可串行化