news 2026/5/28 1:10:04

OpenTenBase的外键(Foreign Key)和外键级联

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenTenBase的外键(Foreign Key)和外键级联

外键(Foreign Key)

  • 作用:外键是用来在两个表之间建立连接的一种约束。它指向另一个表的主键,确保数据之间的引用完整性。其目的是为了杜绝孤儿记录(例如:一条选课记录指向一个不存在的学生ID)

  • 语法格式:

-- 1.列级约束(直接写在字段后面)CREATETABLE子表名(列名 数据类型REFERENCES父表名(父表列),其他列...);-- 2. 表级约束(写在所有字段后面)CREATETABLE子表名(列名1数据类型,列名2数据类型,FOREIGNKEY(子表列名)REFERENCES父表名(父表列名));-- 3. 自定义约束名sqlCREATETABLE子表名(列名1数据类型,列名2数据类型,CONSTRAINT约束名FOREIGNKEY(子表列名)REFERENCES父表名(父表列名)
  • 举个例子(父表为学生表,子表为选课表)

    • 列级约束(直接写在字段后面)
    -- 父表:学生表CREATETABLEstudent(student_id BIGSERIALPRIMARYKEY,student_noVARCHAR(20)UNIQUE,student_nameVARCHAR(50)NOTNULL);-- 子表:选课表(列级外键约束)CREATETABLEenrollment(enrollment_id BIGSERIALPRIMARYKEY,student_idBIGINTNOTNULLREFERENCESstudent(student_id),-- 列级外键section_idBIGINTNOTNULL,scoreNUMERIC(5,2));
    • 表级约束(写在所有字段后面)
    -- 子表:选课表(表级外键约束)CREATETABLEenrollment(enrollment_id BIGSERIALPRIMARYKEY,student_idBIGINTNOTNULL,section_idBIGINTNOTNULL,scoreNUMERIC(5,2),FOREIGNKEY(student_id)REFERENCESstudent(student_id)-- 表级外键);
    • 自定义约束名(表级 + CONSTRAINT)
    -子表:选课表(自定义约束名)CREATETABLEenrollment(enrollment_id BIGSERIALPRIMARYKEY,student_idBIGINTNOTNULL,section_idBIGINTNOTNULL,scoreNUMERIC(5,2),CONSTRAINTfk_enrollment_studentFOREIGNKEY(student_id)REFERENCESstudent(student_id)-- 自定义名称);

    外键REFERENCES student(student_id),其核心作用是:确保enrollment表中的每条选课记录,都必须对应一个在student表中真实存在的学生。简单来说:不能给不存在的学生记录选课成绩。


外键级联

  • 作用:当父表(被引用表)的数据发生删除更新时,子表(包含外键的表)中的数据可以自动执行相应的操作

  • 级联的两种类型:

  • ON DELETE(删除时的级联)

    选项行为学生表示例
    CASCADE删父表,自动删子表删除张三 → 自动删除张三的所有选课成绩
    SET NULL删父表,子表外键变NULL删除李四 → 李四的选课记录还在,但student_id变成NULL
    SET DEFAULT删父表,子表外键变默认值删除王五 → 王五的选课记录student_id变成0
    RESTRICT有子表引用就禁止删除(默认)赵六有选课成绩 → 不让删赵六
    NO ACTION同RESTRICT同上
  • ON UPDATE(更新时的级联)

    选项行为学生表示例
    CASCADE改父表主键,自动改子表外键学生ID从1改成100 → 选课表中的student_id也自动从1变成100
    RESTRICT有子表引用就禁止更新(默认)赵六有选课成绩 → 不让改赵六的ID
  • 举个例子:

-- 父表:学生表CREATETABLEstudent(student_id BIGSERIALPRIMARYKEY,student_noVARCHAR(20)UNIQUE,student_nameVARCHAR(50)NOTNULL);-- 1. ON DELETE CASCADE(级联删除)-- 作用:删除学生时,自动删除该学生的所有选课记录-- 业务场景:学生退学,成绩也不需要保留了CREATETABLEenrollment_cascade(enrollment_id BIGSERIALPRIMARYKEY,student_idBIGINTNOTNULL,section_idBIGINTNOTNULL,scoreNUMERIC(5,2),FOREIGNKEY(student_id)REFERENCESstudent(student_id)ONDELETECASCADE);-- 2. ON DELETE SET NULL(设为空值)-- 作用:删除学生时,保留选课记录,但 student_id 变为 NULL-- 业务场景:学生毕业后匿名化,保留成绩用于统计分析-- 注意:student_id 字段不能有 NOT NULL 约束CREATETABLEenrollment_set_null(enrollment_id BIGSERIALPRIMARYKEY,student_idBIGINT,-- 必须允许 NULLsection_idBIGINTNOTNULL,scoreNUMERIC(5,2),FOREIGNKEY(student_id)REFERENCESstudent(student_id)ONDELETESETNULL);-- 3. ON DELETE SET DEFAULT(设为默认值)-- 作用:删除学生时,保留选课记录,但 student_id 变为默认值(0)-- 业务场景:需要占位符,不能为 NULL,且能关联到"已删除学生"记录-- 前提:必须存在 student_id=0 的记录,且字段有 DEFAULT 0CREATETABLEenrollment_set_default(enrollment_id BIGSERIALPRIMARYKEY,student_idBIGINTDEFAULT0,-- 设置默认值section_idBIGINTNOTNULL,scoreNUMERIC(5,2),FOREIGNKEY(student_id)REFERENCESstudent(student_id)ONDELETESETDEFAULT);-- 4. ON DELETE RESTRICT(限制删除,默认行为)-- 作用:如果学生有选课记录,禁止删除该学生-- 业务场景:保护重要数据,防止误删有成绩的学生CREATETABLEenrollment_restrict(enrollment_id BIGSERIALPRIMARYKEY,student_idBIGINTNOTNULL,section_idBIGINTNOTNULL,scoreNUMERIC(5,2),FOREIGNKEY(student_id)REFERENCESstudent(student_id)ONDELETERESTRICT);-- 5. ON UPDATE CASCADE(级联更新)-- 作用:更新学生的 student_id 时,自动更新选课表中的 student_id-- 业务场景:学生ID需要重新编号时,自动同步所有关联表CREATETABLEenrollment_update(enrollment_id BIGSERIALPRIMARYKEY,student_idBIGINTNOTNULL,section_idBIGINTNOTNULL,scoreNUMERIC(5,2),FOREIGNKEY(student_id)REFERENCESstudent(student_id)ONUPDATECASCADE);
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/28 1:07:21

企业级 AI Agent: MCP、CLI、Skills,如何定位、该怎么选、最佳实践。

当一个 Agent 真正进入企业生产环境后,问题很快就不再是有没有工具,而是如何扩展 Agent 的能力 — 将 Agent 连接到各类企业 IT 设施,以实现更复杂的自动化工作流。 MCP、CLI、Skills 看起来都能让 Agent 更强大,但它们解决的是三…

作者头像 李华
网站建设 2026/5/28 1:04:13

Java零基础入门

前言很多刚学 Java 的同学,代码能跑但是不懂底层规则,经常遇到: 文件名报错、大小写报错、主类找不到、分号漏写、运行异常等各种玄学问题。其实 90% 的新手报错,都是基础语法与项目结构不熟练导致的。本文从零梳理 Java 必须掌握…

作者头像 李华
网站建设 2026/5/28 1:03:28

【Redis实战篇】缓存-穿透/雪崩/击穿问题的解决方案

温馨提示:建议在PC端浏览~ 以商户查询缓存为例什么是缓存 缓存就是数据交换的缓冲区(称作Cache),是存贮数据的临时地方,一般读写性能较高。缓存的作用 降低后端负载提高读写效率,降低响应时间 缓存的成本 数…

作者头像 李华
网站建设 2026/5/28 1:03:19

ROS2坐标变换实战指南:从TF2核心到可视化调试

1. ROS2坐标变换基础:从TF2核心概念说起 第一次接触ROS2的坐标变换系统时,我被那一堆frame_id和transform搞得晕头转向。直到在项目里真正用起来才发现,TF2这套机制简直是机器人开发的"隐形骨架"。想象一下,当你的机器人…

作者头像 李华
网站建设 2026/5/28 1:02:14

伺服控制入门 第一章——伺服控制的硬件/物理基础(二)

参考教程:https://www.bilibili.com/video/BV14q4y147PU?spm_id_from333.788.videopod.episodes&vd_source8f8a7bd7765d52551c498d7eaed8acd5 二、编码器知识及分类 1、编码器的分类与理论基础 (1)根据编码器的原理及检测产生的信号类…

作者头像 李华