请查看下表,了解我的问题的简化版本:
表男孩
BoyId
BoyName
...
表女孩
GirlId
GirlName
桌上玩具
ToyId
ToyName
ToyOwnerBoyOrGirl ( The toy could be owned by a boy or a girl)
ToyOwnerId
我创建了两个约束:
1)ToyOwnerId
是主键Boys.BoyId
2)ToyOwnerId
是主键Girls.GirlId
我的目的是告诉数据库ToyOwnerId
将永远是这些ID之一
我的问题:
当我尝试插入一个名为Boy的新玩具时,我得到一个错误,即在Girls约束中有foreign key conflict
。
这是袋子设计还是我仍然可以使用相同的设计和修复?
答案 0 :(得分:2)
我认为你应该把男孩和女孩的桌子放在一张叫做儿童的桌子上。它会有性别列,有M或F.这将简化事情。
答案 1 :(得分:2)
你应该只在玩具表中加上两个ID加上一个检查约束,以确保男孩或女孩永远是主人。
桌上玩具
CONSTRAINT chkToyOwner CHECK ( (ToyOwnerBoyId is null and ToyOwnerGirlId is not null) OR (ToyOwnerBoyId is not null and ToyOwnerGirlId is null) )
关于选择数据,请使用外连接:
select ...
from toys
left join boys on boys.boyid = toys.toyownerboyid
left join girls on girls.girlid = toys.toyownergirlid;
寻找男孩拥有的玩具:
select ...
from toys
where toyownerboyid is not null;
答案 2 :(得分:1)
它看起来像一个糟糕的设计。为什么不给所有孩子准备一张桌子和一些标记 - 是男孩还是女孩?此外,我真的怀疑你需要ToyOwnerBoyOrGirl
字段 - 因为它可以通过从玩具到业主的加入轻松获得。
考虑以下方案:
Table Children
ID
Name
Is_Boy
Table Toys
ID
Name
Owner_ID
在这种情况下,您只需要从玩具到业主的外键,您可能遇到的其他任务将更加简单易用。
编辑:根据OP的评论 - 男孩和女孩表完全不同。
因此,在这种情况下,您仍然可以将表Children
(让我们使用以前的术语)作为" common" Boys
和Girls
的表格。
类似的东西:
Table Children
ID
Table_Name ('Boys' or 'Girls' here)
Record_ID (ID from Boys or Girls respectively)
...maybe some common fields from boys and girls tables here...
Table Boys
ID
Child_ID
...the rest of fields
Table Girls
ID
Child_ID
...the rest of fields
答案 3 :(得分:0)
这是一个糟糕的设计,因为一个列集(一列,即ToyOwnerId)被引用到不同的表,两者都是一列FK到一列PK。那么显而易见的问题是:你怎么会有类似PK的不同表?而且我看到你已经回答了,通过回复各个表的数据列是不同的。这是拥有不同表格的一个很好的理由。但是,那么,如何解决FK问题呢? (我知道这些"男孩"和女孩"不是真正的实体)。你可以做的是做一个BoyToy和一个GirlToy表。如果您的数据列很少(数据=非PK和非FK),那么这是一个完美的解决方案。不是吗?