我正在攻读“数据库”课程,我们在老师上传的示例考试中进行了这项练习,遗憾的是他没有给出完整的修正,只是提示了一些。 我无法理解为什么在下面的例子中他告诉我们使用触发器函数而不是简单的NOT NULL约束。
现在我会像这样实现B和C之间的关系:
CREATE TABLE B (
b1 int PRIMARY KEY,
b2 varchar(255)
);
CREATE TABLE C (
c1 varchar(255) PRIMARY KEY,
c2 int
);
CREATE TABLE BtoC (
b1 int REFERENCES B(b1) ON DELETE RESTRICT ON UPDATE CASCADE,
c1 varchar(255) NOT NULL REFERENCES C(c1) ON DELETE RESTRICT ON UPDATE CASCADE, -- This would ensure the same constraint, that C has to be at least once in the relation table?
PRIMARY KEY(b1,c1)
);
但他告诉我们表B和C之间的关系,我们需要一个触发函数来满足关系的基数,这是他的话:
“NOTHING上的NOT NULL不会产生任何影响(NOT NULL仅适用于现有行,而不适用于不存在的行),并且不能保证约束有效。因此,NOT NULL对于关系不起作用表,仅用于外键。“
我无法理解他的推理,也许有些人可以向我解释一下?我真的很感激。
答案 0 :(得分:1)
您的版本保证BtoC
中的任何记录都有有效C
引用。 不确保每个BtoC
值C
中至少有一行。这里棘手的部分是" 1"在这段关系中。
这是一种棘手的关系代表 - 我甚至不知道在SQL中是否值得这样做。
一种方法是突出显示其中一个值。例如,如果数据是家庭中的人,则突出显示的人可能是家庭主管"。你需要其中一个。因此,您可以将其实现为:
CREATE TABLE C (
c1 varchar(255) PRIMARY KEY,
c2 int,
b_special int not null references b(b1)
);
这在技术上解决了这个问题,但参考B值分为两个表而不是一个。
如果您希望特殊B位于BtoC
,那么它会变得棘手。你可以用反向引用来做到这一点:
alter table c add constraint fk_c_b_special
foreign key (b_special, c) references btoc(b1, c1);
然后您会发现插入数据变得棘手 - 两个表中都需要存在行才能将行插入到任一表中。
常见的解决方案可能是:
BtoC
中(尽管代码会一直插入它)。