天天看点

MySQL 第六个模块 数据库面试题

第六个模块 数据库面试题

    • 1.数据库的三范式是什么?
    • 2.一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 mysql 数据库,又插入了一条数据,此时 id 是几?
    • 3. 说一下 ACID(事务的特性) 是什么?
    • 4.char 和 varchar 的区别是什么?
    • 5.float 、double 和decimal的区别是什么?
    • 6.mysql 的内连接、左连接、右连接有什么区别?
    • 7.mysql 索引是怎么实现的?
    • 8.怎么验证 mysql 的索引是否满足需求?
    • 9.说一下数据库的事务隔离?
    • 10.说一下 mysql 常用的引擎?
    • 11.说一下 mysql 的行锁和表锁?
    • 12.说一下乐观锁和悲观锁?
    • 13.mysql 问题排查都有哪些手段?
    • 14. 如何做 mysql 的性能优化?
    • 15.删除表的三种方式?
    • 16. 查看重复的数据
    • 17.什么是存储过程?
    • 18.什么是事务?
    • 19.数据库设计规范?
    • 20.字段设计规范
    • 21.数据库开发规范
    • 22.Hash索引和B+树的区别是什么?

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

第一范式:强调的是列的原子性,即数据库表中的每一个字段都是不可分割的原子数据项。
-- 数据库表中的字段都是单一属性的,不可再分。例如,姓名字段,其中的姓和名必须作为一个整体,无法区分哪部分是姓,哪部分是名,如果要区分出姓和名,必须设计成两个独立的字段。
    
第二范式:要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性。
-- 数据库表中的每个实例或者行必须可以唯一地区分,唯一属性的列被称为主键,实体的属性完全依赖于主关键字。
    
第三范式:任何非主属性不依赖于其它非主属性。
-- 数据库中不包含已在其他表中包含的非关键字信息。
 第三范式必须满足第二范式和第一范式
           

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

表类型如果是 MyISAM ,那 id 就是 18。

表类型如果是 InnoDB,那 id 就是 15
InnoDB 表只会把自增主键的最大 id 记录在内存中,所以重启之后会导致最大 id 丢失。
           

3. 说一下 ACID(事务的特性) 是什么?

Atomicity(原子性):原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 
        
    Consistency(一致性):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等。
--事务必须使数据库从一个一致性状态变换到另外一个一致性状态。 
--事务要正确提交后状态才会发生改变
        
	Isolation(隔离性):事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不防止被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。 
-- 包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。 

	持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
        

           

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

char(n) :固定长度类型
--比如订阅 char(10),当你输入"abc"三个字符的时候,它们占的空间还是 10 个字节,其他 7 个是空字节。
char 优点:效率高;缺点:占用空间;适用场景:存储密码的 md5 值,固定长度的,使用 char 非常合适。

varchar(n) :可变长度,存储的值是每个值占用的字节再加上一个用来记录其长度的字节的长度。
所以,从空间上考虑 varcahr 比较合适;从效率上考虑 char 比较合适,二者使用需要权衡。
           

5.float 、double 和decimal的区别是什么?

- float 最多可以存储 8 位的十进制数,并在内存中占 4 字节。
- double 最可可以存储 16 位的十进制数,并在内存中占 8 字节。
1.在DECIMAL(P,D) 的语法中:
P 是表示有效数字数的精度。
P 范围为 1〜65。
D 是表示小数点后的位数。 
D 的范围是 0~30。MySQL 要求 D 小于或等于(<=)P。
 如:DECIMAL(6,2)中最多可以存储 6 位数字,小数位数为 2 位;因此,列的范围是从-9999.99 到 9999.99。
           

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

内连接关键字:inner join;内连接是把匹配的关联数据显示出来;
左连接:left join;左连接是左边的表全部显示出来,右边的表显示出符合条件的数据;
右连接:right join。右连接和左连接正好相反。
           

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

索引是满足某种特定查找算法的数据结构,而这些数据结构会以某种方式指向数据,从而实现高效查找数据。
     B+ 树索引,B+ 树的搜索效率,可以到达二分法的性能,找到数据区域之后就找到了完整的数据结构了,所有索引的性能也是更好的。
    哈希索引,底层是哈希表,查询速度快
           

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

使用 explain 查看 SQL 是如何执行查询语句的,从而分析你的索引是否满足需求。

explain 语法:explain select * from table where type=1。
           

9.说一下数据库的事务隔离?

MySQL 的事务隔离是在 MySQL.ini 配置文件里添加的,在文件的最后添加:transaction-isolation = REPEATABLE-READ
可用的配置值:READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE。

- READ-UNCOMMITTED:未提交读,最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读)。
- READ-COMMITTED:提交读,一个事务提交后才能被其他事务读取到(会造成幻读、不可重复读)。
- REPEATABLE-READ:可重复读,默认级别,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(会造成幻读)。
- SERIALIZABLE:序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、幻读。

脏读 :表示一个事务能够读取另一个事务中还未提交的数据。比如,某个事务尝试插入记录 A,此时该事务还未提交,然后另一个事务尝试读取到了记录 A。

不可重复读 :是指在一个事务内,多次读同一数据。

幻读 :指同一个事务内多次查询返回的结果集不一样。比如同一个事务 A 第一次查询时候有 n 条记录,但是第二次同等条件下查询却有 n+1 条记录,这就好像产生了幻觉。发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据,同一个记录的数据内容被修改了,所有数据行的记录就变多或者变少了。
           

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

InnoDB 引擎:InnoDB 引擎提供了对数据库 acid 事务的支持,并且还提供了行级锁和外键的约束,它的设计的目标就是处理大数据容量的数据库系统。MySQL 运行的时候,InnoDB 会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎是不支持全文搜索,同时启动也比较的慢,它是不会保存表的行数的,所以当进行 select count(*) from table 指令的时候,需要进行扫描全表。由于锁的粒度小,写操作是不会锁定全表的,所以在并发度较高的场景下使用会提升效率的。


MyIASM 引擎:MySQL 的默认引擎,但不提供事务的支持,也不支持行级锁和外键。因此当执行插入和更新语句时,即执行写操作的时候需要锁定这个表,所以会导致效率会降低。不过和 InnoDB 不同的是,MyIASM 引擎是保存了表的行数,于是当进行 select count(*) from table 语句时,可以直接的读取已经保存的值而不需要进行扫描全表。所以,如果表的读操作远远多于写操作时,并且不需要事务的支持的,可以将 MyIASM 作为数据库引擎的首选。
           

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

MyISAM 只支持表锁,InnoDB 支持表锁和行锁,默认为行锁。

- 表级锁:开销小,加锁快,不会出现死锁。锁定粒度大,发生锁冲突的概率最高,并发量最低。
- 行级锁:开销大,加锁慢,会出现死锁。锁力度小,发生锁冲突的概率小,并发度最高。
           

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

- 乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下在此期间别人有没有去更新这个数据。
- 悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻止,直到这个锁被释放。

数据库的乐观锁需要自己实现,在表里面添加一个 version 字段,每次修改成功值加 1,这样每次修改的时候先对比一下,自己拥有的 version 和数据库现在的 version 是否一致,如果不一致就不修改,这样就实现了乐观锁。
           

13.mysql 问题排查都有哪些手段?

- 使用 show processlist 命令查看当前所有连接信息。
- 使用 explain 命令查询 SQL 语句执行计划。
- 开启慢查询日志,查看慢查询的 SQL。
           

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

- 为搜索字段创建索引。
- 避免使用 select *,列出需要查询的字段。
- 垂直分割分表。
- 选择正确的存储引擎。
           

15.删除表的三种方式?

drop:删除表数据和表结构 DROP TABLE user;
truncate:保留表结构,删除数据,释放空间 TRUNCATE TABLE user;
delete:保留表结构,删除数据,释放空间 DELETE FROM user;
三种的执行速度,一般来说:drop>truncate>delete
    
1.通过 delete 删除的行数据是不释放空间的,如果表 id 是递增式的话,那么表数据的 id 就可能不是连续的;而通过 truncate 删除数据是释放空间的,如果表 id 是递增式的话,新增数据的 id 又是从头开始,而不是在已删数据的最大 id 值上递增。

2.使用 delete 删除数据时,mysql 并没有把数据文件删除,而是将数据文件的标识位删除,没有整理文件,因此不会彻底释放空间。被删除的数据将会被保存在一个链接清单中,当有新数据写入的时候,mysql 会利用这些已删除的空间再写入。即,删除操作会带来一些数据碎片,正是这些碎片在占用硬盘空间
           

16. 查看重复的数据

刚刚的语句已经把每个组对应的count数查询出来了,那么count>1的自然是重复的数据

SELECT id,`name`,age,count(1) as c
	FROM user GROUP BY `name`,age having c > 1
           

17.什么是存储过程?

一些SQL语句的集合,中间加了一些逻辑控制语句,它的执行速度快,因为存储过程是预编译过的
    缺点:难以调试和扩展,没有移植性,会消耗数据库资源
           

18.什么是事务?

事务是逻辑上的一组操作,要么全部执行,要么都不执行
           

19.数据库设计规范?

1.所有表使用Innodb引擎,支持事务和外键
2.编码集统一使用utf8
3.给所有表和字段添加注释
4.谨慎使用分区表,会使查询效率变低
5.禁止存储图片,文件大的二进制数据,太大,IO很耗时
6.禁止在线上左数据库压力测试,禁止在测试环境直接连接生成环境数据库    
           

20.字段设计规范

1.优先选择符合储存需要的最小的数据类型,无符号类型相对于有符号类型多一倍的空间
2.尽可能把所有列定为not null,因为null会额外占用空间
3.同财务相关的数据必须使用精准浮点型:decimal类型,计算时不会丢失精度    
           

21.数据库开发规范

1.建议使用预编译语句进行数据库操作(prepareStatement),直传参数,可以解决sql注入问题,一次编译,多次使用,效率快
2.避免使用子查询,子查询的结果集无法使用索引,临时表不会存储索引,会消耗过多的cpu和IO资源,产生大量的慢查询
3.在使用or时,多使用in,可以更高效的利用索引    
           

22.Hash索引和B+树的区别是什么?

1.B+数可以进行范围查询,哈希索引不能
2.B+树联合索引的最左侧原则,哈希索引不支持
3.B+数支持order by排序,哈希索引不支持
4.B+树可以进行模糊查询,哈希索引不能
5.Hash索引在等值查询上效率高