主要观点:使用关系型数据库时往往未充分利用约束,本文提供了设计模式时应考虑的有用数据库约束清单,包括标量约束、多列约束、前后约束等,并强调了在不同层次(前端、API、后端模型、数据库)强制实施不变量(invariants)的重要性,以及通过触发器实现前后约束等。
关键信息:
- 不变量可按强制难度排序,标量不变量易在数据库和编程语言中强制,前后不变量较难但可在 SQL 中用触发器实现,跨多个数据库表的关系不变量在 SQL 中极难强制。
- 应从最严格的数据模型开始,添加约束不耗时,可通过创建迁移和编写 DDL 实现,GitHub Copilot 有助于编写约束。
- 强制实施不变量可采用深度防御策略,数据库是最后防线,若代码中出现数据库约束违反则是代码错误。
- 标量约束清单:非空、唯一性、非空字符串、字符串规范化、数值范围、允许值等。
- 多列约束清单:联合唯一、条件空值、蕴含、多个布尔列、时间戳关系等。
- 前后约束清单:不可变列、状态转换、数值变化等,可通过触发器实现。
重要细节: - 以用户名为例说明不变量,如用户名通常非空、全局唯一(不区分大小写)、单行文本、限于特定字母表、无空格、不允许特殊字符等,但这些不变量常未被强制实施。
- 给出各种约束的具体 SQL 示例,如添加非空字符串约束、唯一性约束、数值范围约束等。
- 以用户表和章节表为例说明联合唯一约束,以用户表为例说明条件空值约束等。
- 解释了 SQL 中如何利用逻辑实现蕴含约束,以及多个布尔列的反模式及解决方法。
- 强调通过触发器实现不可变列和状态转换等前后约束的方式。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。