先写数据规则
关系表组织行与列,主键标识记录,外键表达引用,唯一约束防止重复,检查约束保护取值范围。应用校验改善反馈,数据库约束则在多个写入者之间维护底线。
例如库存表需要保证编号唯一、库存非负;订单需要关联合法商品。把这些条件只写在某一个页面里,不能约束后台任务或另一套客户端。
原子操作与事务
事务把一组数据库操作作为一个提交单元。原子性使其全部生效或不生效;一致性依赖正确的约束与业务操作;隔离控制并发可观察到的效果;持久性依赖数据库和存储配置。
UPDATE inventory
SET quantity = quantity - 3
WHERE product_id = 42 AND quantity >= 3;
在支持相应事务语义的数据库中,条件更新让检查与修改发生在同一条语句中。调用方必须检查受影响行数:零行可能表示商品不存在或库存不足。若还要创建订单,应在同一个事务中执行,并正确处理回滚。
隔离级别需要结合引擎
隔离并不是“所有请求必定串行运行”。快照、锁和冲突检测决定不同事务能看到什么。相同隔离级别名称在不同数据库中的具体行为仍需查文档与实验。死锁或序列化失败可能要求重试整个事务,而不是只重试其中一条语句。
索引提升特定查询的访问效率,也增加写入和空间成本。先看查询条件、排序、数据分布与执行计划,再决定索引,不能仅凭某列出现在 SQL 里就建立索引。
练习与面试自查
在练习数据库中建立带检查约束的库存表,用两个连接并发尝试超额扣减,观察返回行数与最终库存。把查询、预期和实际隔离级别写下来。
解释为什么 ACID 不能自动保证业务逻辑正确,以及一次数据库事务为什么不能直接回滚已经发出的外部邮件或设备动作。