古法数据库
作为一个码农你已经会的:
- CRUD
- 联表
- in / exists
- 范式是什么
你不会的但是可能有点用的:
- ER图
你不会的,但是没啥用的:
-
关系代数
-
存储过程
-
触发器
-
视图
-
窗口函数
-
用诡异的方法规范化范式,函数依赖
ER图
概念模型
(1)实体(Entity)。客观存在并可相互区别的事物称为实体。可以是具体的人、事、物,也可以是抽象的概念或联系。
(2)属性(Attribute)。实体所具有的某一特性称为属性。一个实体可以由若干个属性来刻画。
(3)码(Key)。唯一标识实体的属性集称为码。
(4)域(Domain)。属性的取值范围称为该属性的域。
(5)实体型(Entity Type)。用实体名及其属性名集合来抽象和刻画同类实体称为实体型。比如,学生(学号,姓名,性别,年龄,系,年级)是一个实体型。
(6)实体集(Entity Set)。同型实体的集合称为实体集。比如,全体学生、女学生。
(7)联系(Relationship)。现实世界中事物内部以及事物之间的联系,在信息世界中反映为实体(型)内部的联系和实体(型)之间的联系。
以上内容本人无版权,全部为抄袭
实体关系图
Entity-Relationship Diagram
组成元素:
- 实体(Entity):矩形,里面是名字
- 属性:椭圆,实体的属性,即表中的字段,和实体用直线连接
- 联系:菱形,实体之间存在的关系(谓词写在菱形内),菱形与实体的连线上写1/ n/ m表示关系(关系不是仅仅一对的,还可以三个实体共用一个菱形,两两为一种关系,此外关系也并非唯一的,领导和职工既可以一对多也可以一对一)
- 一对一 1 1
- 一对多 1 n
- 多对一 n 1
- 多对多 n m
注意:题目中给出实体相关的信息并非都要作为实体的属性,尽量满足范式要求,如不应在科室下面记录医生,而应该医生的外键是科室名
补充:如何填写关系菱形中的内容?
通常人作为主语:病人入住房间,学生拥有饭卡
1:n:通常1作为主语,班级容纳学生,部门拥有员工(此时和上一条好像矛盾,事实就是愿意怎么写都行)
1:1 / m:n :靠直觉,是谁发出的动作,谁是主语
关系模型
把 ER 概念模型转换成数据库可直接使用的逻辑结构,适配关系型数据库
实体直接转一张表,实体属性为字段,实体主键为表主键
一对多 (1:N):在 “多” 的一方表增加外键,引用 “1” 方主键
一对一 (1:1):任意一方加外键
多对多 (M:N) 联系必须单独建一张中间表
主码就是主键,外码就是外键,
ER 图实体里带下划线的是主键,但实体可能存在其他能唯一标识的属性,那些全部合起来叫候选码。
关系代数 和 SQL
我们只能用沟槽的SQL Server哦
| 关系代数 | SQL 对应语法 |
|---|---|
| $$σ_{条件}(R)$$ | WHERE 条件 |
| πA,B(R) | SELECT A,B |
| R⋈S | FROM R,S WHERE R.xx=S.xx / JOIN |
| R∪S | UNION |
| R−S | EXCEPT |
| R∩S | INTERSECT |
| R÷S | NOT EXISTS 嵌套子查询 |
SQL server 常用函数
聚合函数
| 函数 | 语法 | 功能说明 | 示例 |
|---|---|---|---|
| COUNT(*) | COUNT(*) | 统计所有行数,包含 NULL、重复行 | COUNT (*) 总人数 |
| COUNT (列) | COUNT (字段) | 统计该列非 NULL数据行数 | COUNT (Score) 有成绩人数 |
| COUNT(DISTINCT) | COUNT (DISTINCT 列) | 去重后统计数量 | COUNT (DISTINCT Class) 班级数 |
| SUM() | SUM (数值列) | 求和,仅支持数字,忽略 NULL | SUM (Score) 总分 |
| AVG() | AVG (数值列) | 求平均值,忽略 NULL | AVG (Score) 平均分 |
| MAX() | MAX (任意类型列) | 最大值(数字 / 字符 / 日期均可) | MAX (Score) 最高分 |
| MIN() | MIN (任意类型列) | 最小值(数字 / 字符 / 日期均可) | MIN (Birth) 最小出生年份 |
数学函数
| 函数 | 功能 | 示例 | 结果 |
|---|---|---|---|
| ABS(n) | 求绝对值 | ABS(-12.5) | 12.5 |
| CEILING(n) | 向上取整(往大数靠) | CEILING(3.1) | 4 |
| FLOOR(n) | 向下取整(往小数靠) | FLOOR(3.9) | 3 |
| ROUND (n, 位数) | 四舍五入,保留指定小数位 | ROUND(3.145,2) | 3.15 |
| SQRT(n) | 平方根 | SQRT(64) | 8 |
| POWER(x,y) | x 的 y 次幂 | POWER(2,4) | 16 |
| RAND([seed]) | 生成 0~1 之间随机小数 | RAND() | 0~1 随机数 |
日期时间函数
| 函数 | 作用 |
|---|---|
| GETDATE() | 获取本地当前完整日期时间(datetime) |
| SYSDATETIME() | 高精度本地时间 |
| GETUTCDATE() | 获取世界标准 UTC 时间 |
| 函数 | 功能 | 示例 |
|---|---|---|
| YEAR (日期) | 提取年份 | YEAR(GETDATE()) |
| MONTH (日期) | 提取月份 | MONTH(Birth) |
| DAY (日期) | 提取日期(几号) | DAY(‘2026-06-01’) |
| DATEPART (单位,日期) | 自定义提取:年 yy、月 mm、日 dd、时 hh、星期 wd | DATEPART(WEEKDAY,GETDATE()) |
| 函数 | 格式 | 作用 | 考试经典用法 |
|---|---|---|---|
| DATEDIFF | DATEDIFF (单位,起始,结束) | 计算两个日期差值 | DATEDIFF (YEAR,Birth,GETDATE ()) 计算年龄 |
会个DATEDIFF就够了
然后回忆一下in 和 exists
EXISTS(子查询):判断子查询是否有返回行,找到一行立即终止(短路)。
NOT EXISTS 嵌套双重否定
找出所有课程都及格的学生
变量 和 循环
局部变量
输出别名
循环
神秘游标
|
|
触发器
只考虑DML 触发器
形如
注意需要知道 inserted 虚拟表,INSERT、UPDATE 操作时自动生成,deleted 虚拟表,DELETE、UPDATE 操作时自动生成
| 操作语句 | inserted 虚拟表 | deleted 虚拟表 |
|---|---|---|
| INSERT | 有(新数据) | 无 |
| DELETE | 无 | 有(被删旧数据) |
| UPDATE | 有(更新后新值) | 有(更新前旧值) |
存储过程
形如
视图
数据库设计模型分析
数据依赖
关系模式标准写法:$R(U,F)$
- $R$:关系名(表名)
- $U$:全体属性集合(所有列)
- $F$ = 函数依赖集(Data Dependency) $F$ 是一张表里所有属性之间的函数依赖关系的集合,是描述表内数据约束的规则,用来判断冗余、更新异常、拆分范式(1NF/2NF/3NF/BCNF)。
函数依赖基础符号 $X \to Y$ $X$、$Y$ 是属性子集:
只要两条记录在 $X$ 上的值完全相同,它们在 $Y$ 上的值一定相同; 通俗:X 能唯一确定 Y,记作 $X \to Y$,读作 X 函数决定 Y。
$F={X_1\to Y_1,;X_2\to Y_2,;\dots,;X_n\to Y_n}$ 每一条 $X\to Y$ 都是一条函数依赖FD,全部FD放在一起构成集合 $F$。
e.g.
学生表:$R(U,F)$ $U={\text{Sno学号},\text{Sname姓名},\text{Sdept系},\text{Dname系主任}}$ 业务规则:
- 学号确定姓名:$\text{Sno}\to\text{Sname}$
- 学号确定系:$\text{Sno}\to\text{Sdept}$
- 系确定系主任:$\text{Sdept}\to\text{Dname}$
则函数依赖集: $$F={;\text{Sno}\to\text{Sname},;\text{Sno}\to\text{Sdept},;\text{Sdept}\to\text{Dname};}$$ 这个 $F$ 就完整描述了这张表所有内在数据依赖关系。
人话:
R 就是表,X,Y 为列的集合(既可以是一个字段,也可以是多个字段,类似联合主键)
- 设 $X\to Y$
- 平凡:$Y\subseteq X$(右边属性是左边子集),永远成立,无业务意义 例:$(\text{Sno,Cno})\to\text{Sno}$
- 非平凡:$Y\not\subseteq X$,业务真正有效的依赖,$F$ 只关注这类
-
完全函数依赖 $X \stackrel{F}{\to} Y$ $X$ 的任何真子集都不能单独决定Y,必须整体组合。 选课表 $SC(\text{Sno,Cno,Grade})$ $(\text{Sno,Cno}) \stackrel{F}{\to} \text{Grade}$ 单独学号、单独课程号都不能确定成绩。
-
部分函数依赖 $X \stackrel{p}{\to} Y$ $X$ 是多属性组合,但其中某一部分就能单独决定Y(2NF要消除)。 例:$R(\text{Sno,Cno,Sdept,Grade})$ $(\text{Sno,Cno})\stackrel{p}{\to}\text{Sdept}$ 只用 $\text{Sno}$ 就能确定系,不需要课程号参与。
-
传递函数依赖 $X\to Y,;Y\not\to X,;Y\to Z \implies X \xrightarrow{\text{传递}} Z$ 上面学生例子:$\text{Sno}\to\text{Sdept},;\text{Sdept}\to\text{Dname}$ $\text{Sno}$ 传递决定 $\text{Dname}$(3NF要消除传递依赖)
候选码:能唯一区分记录,且不能再去掉任何一列。可以有多个
闭包
属性闭包就把属性按照F一个个往里面一次次的套,直到不变
先设这个集合为$X^{(0)}$,之后就是1,2,3,……
范式
候选码:最小主键,能唯一确定整条记录
主属性:候选码里包含的字段
非主属性:不在任何候选码里的字段
1NF 第一范式:列不能 “套娃”
2NF 第二范式:干掉「部分依赖」,所有非主属性,必须完整依赖整个候选码,不能只依赖候选码其中一小部分。(复合主键)
3NF 第三范式:干掉「传递依赖」,不能 “A 推 B,B 推 C,A 间接推 C”。如:学号→系名;系名→系主任
BCNF:表中任意一条 “谁→谁”,箭头左边必须是超码。(相比于第三范式,主键之间不能相互推导,如考生号->考场号,考生号,考场号->座位号,这个就不满足了)
1NF:一格只存一个东西
2NF:复合主键不能一半就定别的字段
3NF:普通字段之间不能互相推导,只要能推出别人,左边必须是超码(候选码、主键都属于超码,带多余字段的组合也算)