我有两个表:
铅笔:
ID(PK): 0,1,2,3
Pencil: Type1, Type2, Type3, Type4
Color_ID(FK, references Colors(ID)): 0,0,0,0
颜色:
ID(PK):0,1,2
Color:Red, Blue, Green
Availability:Yes, No, No
我想在Pencil表中创建约束,以便用户无法输入其可用性为No的颜色的Color_ID值。这样做的最佳方法是什么?谢谢。
答案 0 :(得分:1)
您可以在包含可用性信息的颜色表中添加superkey,然后将外键与计算列一起使用以确保其受约束:
create table Colors (
ID int not null,
Name varchar(30) not null,
Available bit not null,
constraint PK_Colors PRIMARY KEY (ID),
constraint UQ_Color_Names UNIQUE (Name),
constraint UQ_Color_AvailabilityXRef UNIQUE (ID,Available)
)
go
create table Pencils (
ID int not null,
Pencil varchar(20) not null,
ColorID int not null,
_Available as CAST(1 as bit) persisted,
constraint PK_Pencils PRIMARY KEY (ID),
constraint FK_Pencil_Colors FOREIGN KEY (ColorID) references Colors (ID),
constraint FK_PenciL_Color_AvailabilityXRef FOREIGN KEY (ColorID,_Available)
references Colors (ID,Available)
)
您会注意到,严格来说,FK_Pencil_Colors
现在是多余的。我更喜欢保留它,因为它是“真实”的FK,但其他人可能会选择放弃它。
还请注意,这可以防止在仍然有铅笔引用该颜色的情况下使该颜色不可用,这是在此处增加的限制条件。 1
最后,根据我的惯例,当名称不打算由“其他人”使用时,我会在名称前加上_
。他们在那里是为了帮助我构建DRI。
1 如Jeroen所述,这实际上可能不是您想要的行为。请记住,约束通常会陈述“永恒的真理”。如果这是一个约束,那么应该可以删除并重新插入数据而不会违反约束。如果您有一个 temporal 要求,例如“在插入行的时间点X和Y应该为true ”,那么通常最好处理这个问题使用触发器。