一、本周学习收获
1. 数据库分类与整体认知
本周先建立了对数据库的整体认知:数据库分为关系型数据库和非关系型数据库两大类。关系型数据库以表的形式组织数据,表与表之间通过外键建立联系,适合结构清晰、需要强一致性的业务场景;非关系型数据库则更灵活,适合海量数据、高并发读写或结构不固定的场景。
学习数据库的第一步是建库建表,而建表之前要先学会画ER 图(实体关系图)。ER 图把现实业务抽象成「实体」和「关系」,实体对应一张表,关系对应表与表之间的关联方式,画清楚 ER 图,后面的建表思路就顺了。
2. 表关系与外键设计
ER 图里最核心的是三种关系,以及外键该放在哪张表上:
- 一对多:外键要放在「多」的那张表上。例如一个班级有多个学生,学生表里放班级 id 作为外键。
- 多对多:需要建立一张中间表,把两个实体的主键都放进去,共同组成关联。
- 一对一:两张表通过唯一外键关联,一般用于把不常用或敏感字段拆出去。
一句话总结:外键是用来维护表与表之间关系的,放错位置关系就断了。
3. 增删改查(CRUD)
CRUD 是数据库操作的基本功,对应四种操作:
| 操作 | 关键字 | 说明 |
|---|---|---|
| 增 | INSERT INTO | 向表中插入数据 |
| 查 | SELECT | 查询数据,最复杂也最常用 |
| 改 | UPDATE | 修改已有数据 |
| 删 | DELETE | 删除数据 |
新增:
INSERTINTO表名(字段1,字段2)VALUES(值1,值2);修改:
UPDATE表名SET字段1=值1,字段2=值2WHERE条件;删除:
DELETEFROM表名WHERE条件;这里有个很重要的实践认知:一般不会做物理删除,而是做逻辑删除。也就是加一个状态字段(如is_deleted),删除时只改状态,数据仍然保留,方便追溯和恢复。
4. 查询:从单条件到多条件
查询是本周花时间最多的部分,按难度递进整理如下。
单条件查询:用WHERE加条件。
- 比较运算:
<、>、!=、= - 范围查询:
BETWEEN A AND B - 模糊查询:
LIKE,例如LIKE '%关键字%' IN查询:WHERE id IN (1, 2, 3)- 空值判断:
IS NULL/IS NOT NULL
多条件查询:用AND、OR连接,注意AND的优先级高于OR,混用时最好加括号明确逻辑。
排序:ORDER BY 字段 DESC(降序)/ASC(升序)。
分页:LIMIT 起始值, 步长长度,起始值默认为 0。例如LIMIT 0, 10表示从第 0 条开始取 10 条。
SELECT*FROMstudentWHEREage>18ANDnameLIKE'%张%'ORDERBYageDESCLIMIT0,10;5. 聚合函数与分组
常用的五个聚合函数:
MAX()最大值MIN()最小值SUM()求和COUNT()计数AVG()平均值
配合GROUP BY 字段做分组统计,再用HAVING对分组后的结果做筛选。这里要区分清楚:WHERE筛选的是分组前的行,HAVING筛选的是分组后的组。
SELECTclass_id,COUNT(*)AS人数,AVG(score)AS平均分FROMstudentGROUPBYclass_idHAVINGCOUNT(*)>10;6. 多表联查与子查询
多表联查主要用三种连接方式:
INNER JOIN:只保留两表都匹配上的数据LEFT JOIN:以左表为主,右表没匹配上的补 NULLRIGHT JOIN:以右表为主,左表没匹配上的补 NULL
子查询分为:
- 标量子查询:子查询返回单个值,可以放在
WHERE的比较条件里 - 列子查询:子查询返回一列多行,常配合
IN使用
7. 建表与数据类型
建表语法:
CREATETABLE表名(属性名 类型 约束,属性名 类型 约束);数值类型:
- 整数:
TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT - 小数:
FLOAT、DOUBLE、DECIMAL(存金额,精准,面试高频) - 布尔:
BOOL / BOOLEAN,本质就是TINYINT(1),0 为假,非 0 为真
字符串类型:
- 短字符:
CHAR(固定长度)、VARCHAR(可变长度,最常用) - 大文本:
TEXT、MEDIUMTEXT、LONGTEXT - 枚举:
ENUM,只能选给定的值,比如性别男/女 - 集合:
SET,可以多选 - 二进制:
BLOB,存文件、图片,一般项目很少用
日期时间类型:DATE日期、TIME时间、DATETIME日期+时间、TIMESTAMP时间戳、YEAR年份。
特殊类型:JSON存 JSON 格式数据,现在很常用;此外还有空间类型(POINT等)和新版本的VECTOR向量类型,专科考试基本不考。
约束:
- 非空约束
NOT NULL - 主键 / 外键约束
PRIMARY KEY/FOREIGN KEY - 唯一约束
UNIQUE
8. 事务与索引
事务的四大特性(ACID):
- A 原子性:要么全部执行成功,要么全部失败
- C 一致性:数据从一个合法状态转到另一个合法状态
- I 隔离性:并发事务之间互不干扰
- D 持久性:事务提交后数据永久保存
索引:索引能提高查询效率,但会降低增删改的效率,因为每次写操作都要同步维护索引结构。所以索引不是越多越好,要按查询场景有选择地建。
9. 项目设计:三层架构
项目设计上接触了三层架构:
- 表现层:负责输入输出,和用户交互
- 业务层:负责业务逻辑处理
- 数据层:负责 SQL 与数据库交互
分层的好处是职责清晰,改一层不影响其他层。
二、遇到的难题与困惑
1. 外键到底放在哪张表上容易搞混
一开始画 ER 图时,一对多关系里外键的位置总是记反。后来用「多的一方持有外键」这句话反复对照例子才理顺:一个学生只属于一个班级,学生是「多」,所以班级 id 放在学生表里。
2.WHERE和HAVING分不清
写分组统计时,经常把筛选条件写错位置。现在明确了:条件里涉及原始字段就用WHERE,涉及聚合函数结果就用HAVING。
3.AND和OR混用结果不对
多条件查询时,AND优先级高于OR,不加括号很容易得到意料之外的结果。目前的做法是只要混用就加括号,先保证逻辑正确。
4.LIMIT的起始值理解偏差
LIMIT 0, 10里的 0 是起始索引而不是「第几条」,一开始按第 1 条去理解,导致分页数据错位。现在记住:起始值从 0 开始,第二个参数是取多少条。
5. 索引为什么会让增删改变慢
知道结论但原理上还不够透。目前的理解是:索引本身是一份额外的有序结构,每次插入、更新、删除都要同步维护它,所以写操作变慢。至于「索引失效的情况」,还需要再系统整理一遍。
6. 多表联查时LEFT JOIN和INNER JOIN结果差异
同样的 SQL 换一种连接方式,结果行数就变了。现在明白是「以哪张表为主」的问题,但复杂多表场景下还是需要多练。
三、错题反思与总结
错题 1:金额字段用了FLOAT
错误做法:建表时金额字段用了FLOAT。
反思:FLOAT是浮点数,存在精度误差,金额这种要求精确的场景必须用DECIMAL。这也是面试高频考点,属于必须记住的常识。
错题 2:DELETE直接物理删除
错误做法:删除数据时直接DELETE FROM 表 WHERE 条件。
反思:实际项目一般不做物理删除,而是逻辑删除,用状态字段标记。物理删除后数据无法恢复,风险太大。
错题 3:分组统计把条件写进了WHERE
错误做法:WHERE COUNT(*) > 10。
反思:聚合函数不能出现在WHERE里,必须用HAVING。这是语法层面的硬性规则,写错直接报错。
错题 4:IS NULL写成了= NULL
错误做法:WHERE 字段 = NULL。
反思:NULL不能用=比较,任何值和NULL比较结果都是未知,必须用IS NULL/IS NOT NULL。
错题 5:多对多关系没有建中间表
错误做法:多对多关系里直接在一张表里塞另一个表的主键。
反思:多对多必须通过中间表实现,否则一条记录无法对应多个关联对象。ER 图阶段就应该把中间表画出来。
本周总结
- 先画图再建表:ER 图理清实体和关系,外键位置就不会错。
- 查询是重点:单条件、多条件、排序、分页、聚合、分组、联查、子查询,是一条完整的递进链路,需要反复练。
- 细节决定正确性:
DECIMAL存金额、IS NULL判空、HAVING筛分组、LIMIT从 0 开始,这些细节是错题的高发区。 - 索引和事务是进阶:ACID 要能背能解释,索引的收益与代价要能说清楚,索引失效的情况下周继续补齐。
- 三层架构建立工程视角:从「会写 SQL」到「知道 SQL 写在项目哪一层」,是本周最大的认知升级。
下周计划:系统整理索引失效的常见场景,补练多表联查与子查询的组合题,并把本周的建表语句在真实项目里跑一遍。