数据库基本知识

160 阅读5分钟

面试知识查缺补漏

本笔记用于本热面试查漏补缺。

什么是E-R图?

E-R图是 entity-relationship图。

由以下三个要素组成:

  1. 实体:通常是业务对象,如咨询师,答题人。实体用矩形框表示。
  2. 属性:用来描述组成实体的要素,可以理解为字段。用椭圆图来表示
  3. 联系:即实体和实体之间的联系,这个关系不仅有业务关联关系,还能通过数字表示实体之间的对照关系,一般用菱形框
  4. 连线:用于描述实体和属性,实体和联系之间的关系。对于一对一联系,一般是两个实体线方向都写1;对于一对多联系,一般是一的地方写1,多的地方写N;对于多对多关系,一般是两个实体线方向,一遍写N,一边写M。

我们以一个题库平台来展示示例:

image-20230302173439189

参考文档:

zhuanlan.zhihu.com/p/270299029

javaguide.cn/database/ba…

数据库三大范式

1NF(第一范式)

对于关系型数据库来说,属性应该不可再细分,确保属性的原子性。例如一个题目不能是一个string字段,因为题目里面会有选项。如果都存在一个字段里,就违反了第一范式。

2NF (第二范式)

首先,第二范式必须满足第一范式。第二范式就是非主属性必须要有主键。也就是id。第二范式要确保每列与主键相关,不能和主键部分相关。主键列和非主键列遵循完全函数依赖关系

简单的来说就是,我们不能把和这个表描述的事物,没太大关联的属性放一起。它要求实体的属性完全依赖于关键字。

打个比方,题目的基本属性有,问题,类型。这张表是用来描述题目这个实体的。但是你不能把做这道题的userId放进去。这样就打破了第二范式,因为做它的人和这个题目本身没有关系。

3NF(第三范式)

首先,第三范式必须满足第二范式。属性不依赖其他非主属性。

比如,这是一张测评表。

idevaluation_nameevaluator_phoneevaluator_name

我们知道,evaluator_phone和evaluator_name是一一对应的关系。这其实导致了依赖传递。当修改name的时候我们还得维护phone这个字段。

因此,我们可以改进。

idevaluation_nameevaluator_id
idevaluator_nameevaluator_phone

为什么不推荐使用外键和级联

外键是什么?

举个例子,测评表 需要绑定测评师表的主键id(consultant_id)。此时 consultant_id就是外键。此时更新咨询师表的主键id,测评师表的consultant_id也会同步更新,即为级联更新。

这样,数据的一致性问题可以解决,同时,代码量也会减少。

既然这样,为什么我们要废弃外键?

其实是因为级联更新是强阻塞,更新请求多了,响应时间会变慢。同时,外键影响插入效率。——《阿里巴巴开发手册》

且当你的服务不是单机,是微服务的话,每个微服务都有个库,他是没办法做到分库分表的同时,外键生效。

如果说你的公司业务变更,实体关系改变,维护困难。

什么是存储过程?

存储过程可以想象成一堆sql,处理复杂业务好用,有可能一个操作需要一堆sql,它速度肯定是比单纯的sql来的快,因为它预编译过。

但为什么不用呢?

一堆sql意味着,定制化程度高,可移植性差,业务变更直接用不了。

禁止使用存储过程,存储过程难以调试和扩展,更没有可移植性 ——《阿里巴巴开发手册》

drop,delete,truncate区别?

用法不同

  1. drop table 表名,直接删除表
  2. truncate table 表名,只删除表中的数据,再插入数据id为1,通常再清空表的时候使用。
  3. 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中。

参考文献

javaguide.cn/database/sq…