mysql - 关于桥接表的外键设置
问题描述
我对桥接表的外键设置有疑问。我仍然不确定删除过程是如何工作的。我的外键目前都设置为 On Delete: No Action,这是否意味着在桥接表的情况下,为了删除一个或两个父表中的记录,我必须删除它们具有的记录首先在桥接表中,还是在多对多关系中的工作方式不同?如果这是一个简单、愚蠢的问题,我们深表歉意,但对于数据库新手来说,在任何地方都很难找到清晰、简单、易于理解的文档来解释这些事情。
解决方案
规则非常简单:
如果存在引用要删除的行的其他行,则无法删除行。
courses
示例:大学摄影课程在表格中创建为一行。
INSERT INTO courses SET course_id = 1234, title = 'Photography';
参加课程的人:
INSERT INTO enrollments SET course_id = 1234, student_id = 9877;
INSERT INTO enrollments SET course_id = 1234, student_id = 9876;
INSERT INTO enrollments SET course_id = 1234, student_id = 9875;
然后讲师想取消课程。
DELETE FROM courses WHERE course_id = 1234;
这被阻止了,因为该行中enrollments
的行引用了courses
.
同样,学生可能想在本学期退学。他们试图删除他们的记录:
DELETE FROM students WHERE student_id = 9877;
这被阻止了,因为该学生仍在摄影课上注册。
该类enrollments
是一个桥接表(我称这些交叉表,但这些类型的表没有官方术语)。它基本上是一对外键列,它们引用各自的表courses
和students
.
中的外键约束enrollments
要求其他两个表中的每个引用行都存在。当存在引用它的注册时,您不能删除该courses
行或该行。students
处理此问题的方法是在删除引用行之前删除相关行(具有外键约束的行)。
可选ON DELETE CASCADE
语法使外键约束自动处理此问题。也就是说,删除一行courses
将自动删除引用该课程的所有行。如果您不使用此选项,则尝试删除课程会返回错误。
推荐阅读
- android - 对边距的影响?
- python - 使用带有多个分隔符的 numpy 数组导入
- kotlin - 尝试将常量或变量传递给 kotlin 中的 rem() 方法是否存在问题?
- c++ - 使用原始输入处理聚焦点击
- javascript - 带触摸屏的 Three.js 位置模型?
- android - google mapView 样式在具有 maptype=TERRAIN 的 Android 上不起作用
- java - 了解运行“mvn clean install”时的日志记录错误
- visual-studio-2017 - 调试/运行测试选项在 Visual Studio 2017 中一直禁用
- python - 将异常/自定义时间格式转换为日期时间对象
- r - 当列名等于行值时,结合两个数据框来计算变量