【数据库常见面试题】常见面试题以及其基础详解,要找工作的建议收藏
我虽然不是名校出身,但我要坚持查漏补缺,我一定要拿到满意的offer!!!!
关于数据看的基础操作可以看我之前写的文章
文章目录
索引
索引是帮助MySQL实现高效查询的一种排好序的数据结构
索引的数据结构:
-
顺序查找
-
二分查找
-
二叉搜索树
-
红黑树
-
Hash树
-
B-Tree
一个没有索引的数据库如何实现查询的?
首先我们数据库的数据是存储在磁盘,并且在磁盘上是随机分布的,因此在执行查询语句时,我们是逐条的对照数据库中的每条语句,因此时间成本和空间成本都比较大。
一个有索引的数据库如何实现查询的
假如需要查找23
那么先到了34,23<34,因此往左边查找,查找到了22,23>22因此要继续在22的右边查找,找到23。
这个例子就说明了索引在数据库执行查询时,的确是能够简化查询的(能非常有效的减少了查询的次数)。
注意实际数据库中,我们很少使用二叉搜索树作为索引的数据结构,因为当建索引的列的数据很集中(比如像Col1列是一个递增的),这时二叉搜索树会退化为一个单链表,这样实际的查询效率并没有提升
红黑树的数据结构
不适合作为索引数据结构的原因:当数据量较大时,红黑树的深度还是比较深,导致了较多的磁盘IO,查询速度比二叉搜索树快,但是还是不是最好的选择
二叉搜索树
如果普通的二叉树每个节点满足:左子树所有的节点值都小于根节点的值,右子树所有的节点数都大于根节点的值,这样的二叉树就是二叉搜索树。
1.插入操作
新节点与当前根节点比较,如果相等就代表已经存在不需要重复插入;如果小于当前节点,那么就会在当前根节点的左子树寻找,如果大于当前节点,那么就会在当前根节点的右子树寻找。重复这个过程直到插入成功数据。
2.删除操作
删除操作主要分为三种情况,即要删除的节点无子节点,要删除的节点只有一个子节点,要删除的节点有两个子节点。
-
对于要删除的节点无子节点可以直接删除,即让其父节点将该子节点置空即可。
-
对于要删除的节点只有一个子节点,则替换要删除的节点为其子节点。
-
对于要删除的节点有两个子节点,则首先找该节点的替换节点(即右子树中最小的节点),接着替换要删除的节点为替换节点,然后删除替换节点。
3.查询过程
查找操作的主要流程为:先和根节点比较,如果相同就返回,如果小于根节点则到左子树中递归查找,如果大于根节点则到右子树中递归查找。因此在排序二叉树中可以很容易获取最大(最右最深子节点)和最小(最左最深子节点值。
常见索引原则
**1.**选择唯一性索引
1.唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。
**2.**为经常需要排序、分组和联合操作的字段建立索引:
3.为常作为查询条件的字段建立索引。
4.限制索引的数目:
越多的索引,会使更新表变得很浪费时间。
尽量使用数据量少的索引
6.如果索引的值很长,那么查询的速度会受到影响。
尽量使用前缀来索引
7.如果索引字段的值很长,最好使用值的前缀来索引。
7.删除不再使用或者很少使用的索引
8 . 最左前缀匹配原则,非常重要的原则。
10 . 尽量选择区分度高的列作为索引
区分度的公式是表示字段不重复的比例
**11 .**索引列不能参与计算,保持列“干净”:带函数的查询不参与索引。
**12 .**尽量的扩展索引,不要新建索引
数据库三范式
- 第一范式:
列不可分
,确保每列的原子性,每个列表示的含义都是不同的,不存在多个列表示同一种属性 - 第二范式:
没有非主属性对主属性的部分依赖
,每个列都要完全依赖于主属性,而不是依赖于主属性(键可以是单键也可以是联合主键)的部分。 - 第三范式:
没有非主属性对于主属性的传递依赖
,表中的非主属性都要直接依赖于主属性,而不是传递依赖于主属性。
图示:演示传递依赖:顾客姓名依赖于非主键顾客编号,因此不满足第三范式。
- 注意:满足第二范式,必须满足第一范式,满足第三范式必须满足第二范式。
数据库事务
四个重要的属性:
- 原子性:事务的操作是一个完整的过程,要么全做,要么都不做
- 一致性:当数据库事务完成时,数据要保持一致
- 隔离性:对数据进行修改的所有并发操作是彼此隔离的,事务是独立的,不能对其他事务造成影响。
- 持久性:事务完成后,数据要能持久化保存,数据库有事务日志(可以回滚来恢复数据)。
事务隔离级别
- 读未提交
- 读已提交
- 不可重复读
- 序列化读
数据库并发策略
并发控制一般采用三种方式:分别是乐观锁,悲观锁和时间戳。
乐观锁任务自己在读数据,别人不会去写自己读的数据。悲观锁相反,认为自己读的数据,别人一定是在写数据,时间戳是不加锁,使用时间戳来判断数据是否发生了修改。
1.乐观锁
乐观锁任务自己在读数据,别人不会去写自己读的数据。
何时使用乐观锁:对于经常查询,但是不太会修改的数据可以使用乐观锁。
2.悲观锁
悲观锁就是在读取数据的时候,为了不让别人修改自己读取的数据,就会先对自己读取的数据加锁,只有自己把数据读完了,才允许别人修改那部分数据,或者反过来说,就是自己修改某条数据的时候,不允许别人读取该数据,只有等自己的整个事务提交了,才释放自己加上的锁,才允许其他用户访问那部分数据。
何时使用悲观锁:对于经常修改的数据,要使用悲观锁,防止数据发生不一致。
3.时间戳
时间戳就是在数据库表中单独加一列时间戳,比如“TimeStamp”,每次读出来的时候,把该字段也读出来,当写回去的时候,把该字段加1,提交之前 ,跟数据库的该字段比较一次,如果比数据库的值大的话,就允许保存,否则不允许保存,这种处理方法虽然不使用数据库系统提供的锁机制,但是这种方法可以大大提高数据库处理的并发量。
- 时间戳只有在重新写数据的时候才会修改时间戳,读数据是不会修改时间戳的。
数据高频面试题
1.什么是存储过程?有什么特点?
存储过程就像编程语言中的函数一样,将我们的SQL语句封装起来。
特点:
- 能够将SQL语句封装起来
- 保存在数据库中,让编程语言调用
- 存储过程是一个预编译的代码块,因此执行效率比较高
- 大量的SQL语句封装起来一起执行,可以减少网络通信的次数,提高通信效率
- 缺点:存储过程存储在数据库中,难以更新迭代
2.什么是视图?视图的使用场景?
视图是一种虚表(其实视图不存储数据,它是基于数据表的一种虚表,仅仅是呈现了查询的结果,真正的数据还在基表上)
- 视图建立在已有表的基础上,视图赖以建立的表称为基表。
- 向视图提供数据的语句是select语句
- 视图向用户提供基本数据的另一种表现形式
- 操作的是视图,但基表的数据也会发生改变
视图的使用场景,一张表上的数据并不是用户都想要看的,我们仅仅给用户展示视图(基表的查询结果),不仅能让用户有好的体验,也能保证数据的安全性
注意:视图能让我们专注,但是并不能提高查询的效率
3.drop,truncate和delete的区别:
drop:
- 属于DDL
- 不可回滚
- 不可带where
- 表结构和内容删除
- 删除速度快
trunate:
- 属于DDL
- 不可回滚
- 不可带where
- 内容删除
- 删除速度快
delete:
- 属于DML
- 可回滚
- 可以有where
- 表结构在,内容看where
- 删除速度慢,要逐行删除
总结:
- 不在需要一张表的时候使用drop
- 想删除部分数据行,用delete,使用where
- 保留表结构但是删除表中的所有内容,使用truncate
4.什么是索引?有什么作用和优缺点?
索引是让MySQL实现高效查询的一种数据结构
作用:加快查询效率。
特点:
- 无需在查询语句中指定使用哪个索引,数据库会自主选择
- 在定义主键,唯一约束系统会自动在相应的列上创建索引
- 可以自主创建索引
什么时候需要索引:
- 经常使用查询
- 表中的数据量很大
- 列名经常在where中出现或者在连接条件中出现
优缺点:
- 加快查询
- 减低添加,修改,删除的效率(因为这三种操作的同时也会操作索引)
因此在经常INSERT,DELETE,UPDATE的表中不要使用索引
5.什么是事务?
语句中指定使用哪个索引,数据库会自主选择
- 在定义主键,唯一约束系统会自动在相应的列上创建索引
- 可以自主创建索引
什么时候需要索引:
- 经常使用查询
- 表中的数据量很大
- 列名经常在where中出现或者在连接条件中出现
优缺点:
- 加快查询
- 减低添加,修改,删除的效率(因为这三种操作的同时也会操作索引)
因此在经常INSERT,DELETE,UPDATE的表中不要使用索引
5.什么是事务?
数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。