面试知识查缺补漏
本笔记用于本热面试查漏补缺。
什么是E-R图?
E-R图是 entity-relationship图。
由以下三个要素组成:
- 实体:通常是业务对象,如咨询师,答题人。实体用矩形框表示。
- 属性:用来描述组成实体的要素,可以理解为字段。用椭圆图来表示
- 联系:即实体和实体之间的联系,这个关系不仅有业务关联关系,还能通过数字表示实体之间的对照关系,一般用菱形框
- 连线:用于描述实体和属性,实体和联系之间的关系。对于一对一联系,一般是两个实体线方向都写1;对于一对多联系,一般是一的地方写1,多的地方写N;对于多对多关系,一般是两个实体线方向,一遍写N,一边写M。
我们以一个题库平台来展示示例:
参考文档:
zhuanlan.zhihu.com/p/270299029
数据库三大范式
1NF(第一范式)
对于关系型数据库来说,属性应该不可再细分,确保属性的原子性。例如一个题目不能是一个string字段,因为题目里面会有选项。如果都存在一个字段里,就违反了第一范式。
2NF (第二范式)
首先,第二范式必须满足第一范式。第二范式就是非主属性必须要有主键。也就是id。第二范式要确保每列与主键相关,不能和主键部分相关。主键列和非主键列遵循完全函数依赖关系。
简单的来说就是,我们不能把和这个表描述的事物,没太大关联的属性放一起。它要求实体的属性完全依赖于关键字。
打个比方,题目的基本属性有,问题,类型。这张表是用来描述题目这个实体的。但是你不能把做这道题的userId放进去。这样就打破了第二范式,因为做它的人和这个题目本身没有关系。
3NF(第三范式)
首先,第三范式必须满足第二范式。属性不依赖其他非主属性。
比如,这是一张测评表。
| id | evaluation_name | evaluator_phone | evaluator_name |
|---|---|---|---|
我们知道,evaluator_phone和evaluator_name是一一对应的关系。这其实导致了依赖传递。当修改name的时候我们还得维护phone这个字段。
因此,我们可以改进。
| id | evaluation_name | evaluator_id |
|---|---|---|
| id | evaluator_name | evaluator_phone |
|---|---|---|
为什么不推荐使用外键和级联
外键是什么?
举个例子,测评表 需要绑定测评师表的主键id(consultant_id)。此时 consultant_id就是外键。此时更新咨询师表的主键id,测评师表的consultant_id也会同步更新,即为级联更新。
这样,数据的一致性问题可以解决,同时,代码量也会减少。
既然这样,为什么我们要废弃外键?
其实是因为级联更新是强阻塞,更新请求多了,响应时间会变慢。同时,外键影响插入效率。——《阿里巴巴开发手册》
且当你的服务不是单机,是微服务的话,每个微服务都有个库,他是没办法做到分库分表的同时,外键生效。
如果说你的公司业务变更,实体关系改变,维护困难。
什么是存储过程?
存储过程可以想象成一堆sql,处理复杂业务好用,有可能一个操作需要一堆sql,它速度肯定是比单纯的sql来的快,因为它预编译过。
但为什么不用呢?
一堆sql意味着,定制化程度高,可移植性差,业务变更直接用不了。
禁止使用存储过程,存储过程难以调试和扩展,更没有可移植性 ——《阿里巴巴开发手册》
drop,delete,truncate区别?
用法不同
- drop table 表名,直接删除表
- truncate table 表名,只删除表中的数据,再插入数据id为1,通常再清空表的时候使用。
- delete from 表名 where 列名 = 值。可以附加where条件,如果不加where和truncate类似。
总结:truncate 和 delete 均只删数据不删结构。
drop会把结构也删除掉。
属于的数据库语言不同
首先我们得知道两个概念。
DML:Data Manipulation Language 数据库操作语言,是对表记录的操作。包括对表的增删改查,是开发人员最常用到的。
DDL: Data Definition Language.是数据定义的意思,DML仅仅对内部数据更改,不涉及表结构。他会改表结构,更多被数据库管理员使用
因此,delete属于 DML。drop,truncate则属于 DDL。
放在DDL中的drop,truncate 不会被放在 rollback segement中,因此不能回滚。而放在DML中的 delete操作可以。
那什么是 rollback segment呢?
- 他是数据库中的一段存储空间,用来记录数据修改之前的值。
- 如果用户没有执行commit 操作,那么该空间内的值是可以通过rollback恢复到数据库中的。如果执行了,那么这个里面的值就会标识成失效,此时数据永久改变。
- 如果select语句在读取一张表,同时数据被更新了,那么此时select 语句是更新前的数据,因为修改前的数据存入了 rollback segment中。