Mysql面试必备
1、Mysql常用的引擎
InnoDB 引擎:MySQL 的5.5之后的默认引擎,InnoDB 引擎提供了对数据库事务的支持,并且还提供了行级锁
和外键的约束,它的设计的目标就是处理大数据容量的数据库系统。MySQL 运行的时候,InnoDB 会在内存中建
立缓冲池,用于缓冲数据和索引。由于锁的粒度小,写操作是不会锁定全表的,所以在并发度较高的场景下使用会
提升效率的。
MyISAM 引擎:不提供事务的支持,也不支持行级锁和外键。因此当执行插入和更新语句时,即执行写操作的时
候需要锁定这个表,所以会导致效率会降低。不过和 InnoDB 不同的是,MyIASM 引擎是保存了表的行数,于是
当进行 select count(*) from table 语句时,可以直接的读取已经保存的值而不需要进行扫描全表。所以,
如果表的读操作远远多于写操作时,并且不需要事务的支持的,可以将 MyIASM 作为数据库引擎的首选。
2、innodb与MyIsam的区别
InnoDB支持事务,而MyISAM不支持事务;
InnoDB支持行级锁,而MyISAM支持表级锁;
InnoDB支持MVCC(多版本并发控制), 而MyISAM不支持;
InnoDB支持外键,而MyISAM不支持;
InnoDB不支持全文索引,而MyISAM支持;
3、Mysql有三种级别的锁定
行级锁:
只对用户正在访问的行进行锁定。
如果该用户正在修改某行,那么其他用户就可以更新同一表中该行之外的数据。
行级锁是一种排他锁,防止其他事务修改此行,但是不会阻止读取此行的操作。
表级锁:
表级锁是MySQL中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大
部分MySQL引擎支持。最常使用的MYISAM与INNODB都支持表级锁定。表级锁定分为表共享读锁(共享锁)与
表独占写锁(排他锁)。特点是开销小,加锁快;不会出现死锁;锁定粒度大,发出锁冲突的概率最高,并
发度最低。
页级锁:
页级锁是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度
慢。所以取了折中的页级,一次锁定相邻的一组记录。
4、mysql 索引是怎么实现的?
索引是满足某种特定查找算法的数据结构,而这些数据结构会以某种方式指向数据,从而实现高效查找数据。
MySQL 中的索引,不同的数据引擎实现有所不同,但目前主流的数据库引擎的索引都是 B+ 树实现的 。
5、为什么选择B+树作为索引结构
· 因为B+树的非叶子节点不存放实际的数据,这样每个节点可容纳的元素个数比B-树多,树高比B-树小,这样带
来的好处是减少磁盘访问次数。尽管B+树找到一个记录所需的比较次数要比B-树多,但是一次磁盘访问的时间相当
于成百上千次内存比较的时间,因此实际中B+树的性能可能还会好些。
· B+树的叶子节点使用指针连接在一起,方便顺序遍历(例如查看一个目录下的所有文件,一个表中的所有记录等)。
· B+树的查询效率更加稳定,每次查询的效率一样。
Hash索引底层是哈希表,哈希表是一种以key-value存储数据的结构,所以多个数据在存储关系上是完全没有任何
顺序关系的,所以,对于区间查询是无法直接通过索引查询的,就需要全表扫描。所以,哈希索引只适用于等值
查询的场景。而B+ 树是一种多路平衡查询树,所以他的节点是天然有序的(左子节点小于父节点、父节点小于右
子节点),所以对于范围查询的时候不需要做全表扫描
6、什么样的信息能成为索引
主键,唯一键,普通键都可,只要能让数据有一定区分性的字段。
7、char 和 varchar 的区别是什么?
char(n) :固定长度类型,比如订阅 char(10),当你输入"abc"三个字符的时候,它们占的空间
还是10 个字节,其他 7 个是空字节。
chat 优点:效率高;
缺点:占用空间;
适用场景:存储密码的 md5 值,固定长度的,使用 char 非常合适。
varchar(n) :可变长度,存储的值是每个值占用的字节再加上一个用来记录其长度的字节的长度。
所以,从空间上考虑 varcahr 比较合适;从效率上考虑 char 比较合适,二者使用需要权衡。
8、where与having的区别
1、用的地方不一样
where可以用于select、update、delete和insert into values(select * from table where ..)语句中。
having只能用于select语句中
2、执行的顺序不一样
where的搜索条件是在执行语句进行分组之前应用
3、having的搜索条件是在分组条件后执行的
即如果where和having一起用时,where会先执行,having后执行
9、事务的基本要素ACID
Atomicity(原子性):事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不
执行
Consistency(一致性):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。
Isolation(隔离性):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何
干扰。
事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read
committed)、可重复读(repeatable read)和串行化(Serializable)。
Durability(持久性):事务处理结束后,对数据的修改是永久的。
10、数据库的事务隔离/事务隔离级别
1. 读未提交(READ_UNCOMMITTED)
读未提交,该隔离级别允许脏读取,其隔离级别是最低的。换句话说,如果⼀个事务正在处理某⼀
数 据,并对其进⾏了更新,但同时尚未完成事务,因此还没有提交事务;⽽以此同时,允许另⼀
个事务也 能够访问该数据。
2. 读已提交(READ_COMMITTED)
读已提交是不同的事务执⾏的时候只能获取到已经提交的数据。 这样就不会出现上⾯的脏读的情
况 了。 但是在同⼀个事务中执⾏同⼀个读取,结果不⼀致
3. 可重复读(REPEATABLE_READ)
可重复读就是保证在事务处理过程中,多次读取同⼀个数据时,该数据的值和事务开始时刻是⼀致
的。 因此该 事务级别限制了不可重复读和脏读,但是有可能出现幻读的数据。
幻读
幻读就是指同样的事务操作,在前后两个时间段内执⾏对同⼀个数据项的读取,可能出现不⼀致的
结果
4. 顺序读(SERIALIZABLE)
顺序读是最严格的事务隔离级别。它要求所有的事务排队顺序执⾏,即事务只能⼀个接⼀个地处理,
不能并发。
11、说一下乐观锁和悲观锁
乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一
下在此期间别人有没有去更新这个数据。
数据库的乐观锁需要自己实现,在表里面添加一个 version 字段,每次修改成功值加 1,这样每次
修改的时候先对比一下,自己拥有的 version 和数据库现在的 version 是否一致,如果不一致就
不修改,这样就实现了乐观锁。
悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想
拿这个数据就会阻止,直到这个锁被释放。
一般是 where id=XX for update 来实现 (一般银行转账、工单审批)
优缺点:
乐观锁:性能高、重试失败成本不高建议乐观
悲观锁:性能低,但安全,失败成功高建议悲观,使用不当有死锁风险
12、sql 优化可以从哪些方面考虑?
主要是从怎么合理创建索引 合理使用索引以防止索引失效 合理创建表字段这3个方面入手
1、合理创建索引:
对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
2、防止索引失效:
最佳左前缀法则
指的是查询从索引的最左前列开始并且不跳过索引中的列。 在创建索引的字段中第一个就是最左,每
个左边的字段都是后面一个字段的一整个树,过滤条件要使用索引必须按照索引建立时的顺序,依次
满足,一旦跳过某个字段,索引后面的字段都无法被使用。要按照顺序命中索引
3、合理创建表字段: 最好不要给数据库留NULL,尽可能的使用 NOT NULL填充数据库
不使用 *,使用 LIMIT 语句来限制返回的数据,减少交互次数(批量提交)
先整理这么多,后面继续完善!