如果表A具有表B所需的外键(表A中包含所需的外键),则向表A添加一行

时间:2018-04-17 23:14:05

标签: sql sql-server

这可能听起来很复杂,所以我举一个例子。

说,我有两个表教师和班级。

教师有一个名为PreferredClassID的必填字段,该字段具有针对Class的外键。

Class有一个名为CurrentInstructorID的必填字段,它是一个针对教师的外键

是否可以在这些表中插入一行?

因为如果我向教师插入一行,我将无法提供一个PreferredClassID,但我无法创建一个Class行,因为它需要一个CurrentInstructorID。

如果我不能这样做,我该如何解决这个问题呢?我是否只需要使其中一个字段不需要(即使业务要求指定它确实应该是必需的?)

3 个答案:

答案 0 :(得分:1)

如果您发现自己,请重新评估您的数据关系模型。

在这种情况下,您可以使用一个名为PreferredCourse的查找表,其中包含courseId和instructorId。

这将强制在将行添加到PreferredCourse查找之前存在课程和讲师。在不影响数据库模型要求规则的情况下维护业务模型需求。

虽然拥有另一个表似乎过多,但它会阻止数据库过程和作业以及应用程序代码中的大量维护开销。循环引用只会产生令人头疼的问题,并且可以通过小型查找表和JOIN轻松解决。

Impaler举例说明了如何使用当前的数据结构来实现这一目标。请注意,您必须1:在至少一个表中使密钥可为空,然后2:按指定顺序执行INSERT。或者,3:禁用约束,4:执行INSERTS,5:重新启用约束,6:如果约束现在被破坏则回滚事务。

有很多可能出错,只需在事情失控之前修复关系模型。

答案 1 :(得分:0)

只要其中一个外键允许空值,你就会很好。所以你:

  1. 首先插入接受空值的行(比如讲师),在FK上插入空值。获取插入行的ID。

  2. 插入另一个表(比如Class)。在FK中,您使用从步骤#1获得的ID。插入后,您将获得此新行的ID。

  3. 使用从步骤2获得的ID更新第一行(讲师)上的FK。

  4. 提交。

  5. 或者,如果两个FK都是NOT NULL,那么你有点问题。我在最后一个案例中看到的选项是:

    • 使用可延迟的FK完整性检查。有些数据库允许您在COMMIT发生之前插入而不检查完整性。这真的很棘手,并且正在寻找麻烦。

    • 短时间禁用FK。某些数据库允许您启用/禁用约束。您没有删除它们,只是暂时禁用它们。如果您这样做,请勿忘记启用它们

    • 在执行插入操作时暂时删除约束,然后再次添加。这真的是最后的工作。添加/删除约束是DML语句,通常不能参与事务。这样做是为了你自己的危险。

答案 2 :(得分:0)

需要考虑的事项(根据用户7396598的回答)正在查看正常表单如何应用于您的数据,因为它适合您的关系模型。

在这种情况下,可能值得查看以下内容:

使用Instructor表,PreferredClassID是必要的组件吗?教师是否需要有一个首选课程,或者可以说“嘿,我正在为新教师创建一个条目,我不知道他们喜欢的课程。”

(如果他们是新的,他们可能没有你学校提供的优先课程)

这是一个你绝对想拥有外键的情况,但是可以说“我不一定知道我想要放在那里的价值。”

同样地,Class在创建教师时是否需要教师?是否可以创建尚未分配教师的Class

同样,这两点都是“我不知道我想把它放在这里的情况”,但是当我这样做时,它应该是另一个表中存在的特定实例。'