一、为什么大厂开发不建物理外键?
虽然课本强调物理外键(外键),但在高并发、大规模互联网开发中,通常选择**“逻辑外键”**。
1. 核心原因
性能瓶颈:每次读取触发都会数据库层面的校验,产生额外的锁,高并发下容易导致死锁或队列。
扩展困难:物理外键无法跨库使用。在分库分表架构下,外键会失效。
运维风险:级联删除(级联)可能导致误删“全家桶”;在数据恢复或批量导入时,外键会严格限制操作顺序。
解耦合需求:将约束从数据库层转移到应用层(代码逻辑),系统更加灵活,方便业务快速迭代。
二、数据库关联的“实战写法”
不建物理外键不代表没有关联,而是改用“逻辑关联”。
1.建表对比
物理外键(不推荐):使用
FOREIGN KEY ... REFERENCES ...。逻辑外键(推荐):只保留字段,不加约束。
SQL-- 订单表:仅保留 user_id 字段作为逻辑关联 CREATE TABLE orders ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT NOT NULL, -- 逻辑外键 order_no VARCHAR(64) );
2. 操作差异
查询 (SELECT):写法一样,同样使用
JOIN或分两次查询。插入(INSERT):数据库不再自动检查。需要在业务代码中先查询用户是否存在,再执行插入。
删除 (DELETE):数据库不再拦截建议。使用逻辑删除(
is_deleted=1)替代物理删除。
三、索引(Index):数据库的“导航目录”
没有外键,必须手动为逻辑外键字段添加索引,否则查询会因“全表扫描”而卡死。
1.为什么加索引查得快?
无索引:像翻书一样,从第一页翻到最后一页找内容(全表扫描)。
有索引:像查字典开头的目录,直接定位到目标所在的页面码。
2. 指数的代价
空间:索引文件需要占用硬盘。
时间:每次
INSERT或UPDATE时,数据库都需要同步维护索引目录,导致写入变慢。
原则:只在经常出现在
WHERE和JOIN条件后面的字段上加索引。
四、 底层逻辑:B+ 树与二分查找
数据库是如何在毫秒内从千万条数据中锁定目标的?
1.数据结构:B+树(B+ Tree)
特征:
矮胖型结构:有上千万个数据,通常树也只有3~4层,意味着最多只有3~4次磁盘读写器。
叶子非节点:只存“路标”,不存具体数据,提高索引密度。
叶子节点:存放真实数据,且连接(每个链表),方便范围查找(如查某段时间的订单)。
2. 核心算法:二分查找
原理:在数组的索引中,每次对比中间值,直接更换另一半数据。
效率:在100万个数据中找到一个数,最多只需比约20次。
五、新手建表黄金基准
必须有主键:建议用
id BIGINT AUTO_INCREMENT。必备字段:(
create_time创建时间)、update_time(更新时间)、is_deleted(逻辑删除)。手动加索引:给所有逻辑外键字段加上
INDEX。禁止NULL:字段首先设为
NOT NULL默认值,避免程序空指针异常。存储引擎:统一使用
InnoDB(支持事务,安全可靠)。