🥰个人主页:会编程的土豆(欢迎来访)
💎作者简介:后端学习者 
✨那些你一个人走过的夜路 ,终将化作照亮未来的光



🌿 笔记|今天把几个老是混的点捋清了
🍵 后端 + 一点 MySQL,边刷题边问
✨ 走得慢没关系,走到了就算数。
**今天大概记了啥:**外键约束、IN / EXISTS、四种 JOIN、脏读 / 不可重复读 / 幻读。都是我之前听着耳熟、一细问又说不清的东西。
说实话我学 MySQL 的方式挺野的:牛客 SQL 刷了一圈,DDL DML 问了一点,八股看小林 coding,没怎么正经跟视频课。好处是下手快,坏处也明显------事务、锁、外键这些词一出来,脑子就空。
今天就专门把几个空补上,写成笔记免得明天又忘。
一、外键约束(终于分清"字段"和"规矩")
以前我以为表里有个 student_id 就是外键了。今天搞明白:
- 外键:这张表里指向别人主键的那个字段
- 外键约束:数据库强制规定------你填的值,对面表里必须真有
比如成绩表写 student_id = 999,学生表根本没这个人。没约束时能存进去,数据就脏了;有约束时直接报错,插不进去。
一句话我自己的理解:
外键约束 = 保证和自己关联的那张表里,对应数据真实存在。
后面查的时候 JOIN ON u.id = p.user_id,其实就是在用这个挂钩。约束管"能不能存",JOIN 管"怎么拼着查"。
二、IN 和 EXISTS(用学生成绩表才看懂)
文章里老说这两个都能配子查询,我一直分不清思路。后来拿三张学生、几条成绩走了一遍,清楚多了。
学生: 小明 1、小红 2、小刚 3
**成绩:**只有小明、小红有;小刚没有。
IN:在不在名单里
SELECT * FROM students
WHERE student_id IN (SELECT student_id FROM scores);
脑子里可以想成两步:
- 先从成绩表捞出学号名单,大概是 (1, 2)
- 再看学生:学号在不在名单里
小刚 3 不在,就被丢掉。
EXISTS:对当前这行,对面有没有货
SELECT * FROM students s
WHERE EXISTS (
SELECT 1 FROM scores sc
WHERE sc.student_id = s.student_id
);
不是先做大名单,而是盯着每个学生问:成绩表里有你吗?有就留,没有就滚。小刚还是没。
结果可以一样,想问题的方式不一样。我现在的记法:
- IN → 名单
- EXISTS → 存在不存在
找没成绩的学生,用 NOT EXISTS 很好懂。听说 NOT IN 遇到 NULL 容易怪,以后能写 EXISTS 我就优先 EXISTS。
三、四种 JOIN(差在"对不上的还要不要")
今天才把这句话刻进脑子:
对得上的都会拼出来;区别是落单的行还留不留。
- INNER:只要两边都有的
- LEFT:左表全留,右边没有就 NULL
- RIGHT:右表全留,左边没有就 NULL
- FULL:两边落单的都留(MySQL 常常不直接支持)
小例子我是这么记的:小刚没成绩、成绩表里还有个对不上学生的脏数据。
- INNER:小刚没了,脏成绩也没了
- LEFT:小刚还在,成绩是空
- RIGHT:脏成绩还在,姓名是空
以前写用户表 JOIN 做题表,用的其实是内连接------没做过题的人直接消失。以后如果要"所有人都在",得想清楚要不要 LEFT。
四、脏读、不可重复读、幻读(卡最久的一块)
我一开始很不服气:事务不是隔离的吗?为什么 B 开着事务,A 还能改数据,还能把 B 误导了?
后来想通了:
"有事务"不是玻璃罩。隔离是挡位,不是物理隔绝。
B 可以长时间待在一个事务里(BEGIN 到 COMMIT 之间)。这段时间 A 完全可以改、可以提交。B 第二次读会不会变,取决于隔离级别松不松。
三个现象其实时间线很像,都是 B 没结束、中间 A 动手了。差别在结果长什么样:
- 脏读:读到别人还没提交的。对方一回滚,你拿的就是假的。
- 不可重复读:同一行,读两次值变了(别人 UPDATE 并提交了)。
- 幻读:同一个条件,查两次行数变了(别人 INSERT/DELETE 并提交了)。
我自己的对照:
- 小明年龄 18→20 → 不可重复读
- 名单里突然多了一个人 → 幻读
过程像,结果不像。一个是老行变了,一个是名单变了。
五、顺手记的一点别的
今天还零碎问了这些,先撂一嘴免得散掉:
- 401 / 403:401 是没认清你(没登录/凭证坏了);403 是认清了但不让你碰(没权限)。
- O(1) / O(n) :数组
arr[i]按下标访问一般是 O(1);从头扫到尾找某个值是 O(n)。 - SQL 和 NoSQL:关系型重规矩和关联(MySQL);NoSQL 更灵活好扩展(Redis、Mongo 这类)。项目里经常一起用,不是非黑即白。
写在最后
今天最大的收获不是背下了多少名词,而是承认了一件事:我基础是差了一截,直接上引擎对比、行锁表锁会懵,很正常。得先把外键、事务、JOIN、这三种"读问题"用人话钉住,再回头看小林那些八股,才接得上。
反正刷题还得继续,概念也得一块补。先把今天这几个写明白,明天自己还能讲出来,就算没白学。
------ 记于又一个把"好像懂了"变成"能讲清楚"的晚上