数据库设计 - NULL外键

时间:2010-02-01 17:02:20

标签: sql database-design foreign-keys data-modeling

感谢阅读。

我正在为一家小狗店制作数据库。我有一张小狗桌子和一张桌子供业主使用。一只小狗可以有一个主人,主人可以拥有一只以上的小狗,但不是所有的小狗都拥有。处理这种情况的好方法是什么?

  • 如果小狗没有拥有者,我是否会在小狗表中使用FK?
  • 我是否创建了一个关联表,该关联表是所有者与小狗的一对多映射,并且如果小狗是非拥有的,小狗上会有标记?
  • 我创建两个表吗?一个表可以用于拥有的小狗,它对所有者表有一个NON-NULL FK,另一个表用来保存不归属的小狗?

感谢您的帮助。

这个问题的确是针对,如何将行标记为全局,并允许任何用户查看?

7 个答案:

答案 0 :(得分:11)

解决方案1)是正确的。小狗可以没有所有者或单个所有者,因此该列可以填充现有所有者或NULL。

答案 1 :(得分:5)

我会有以下表格:

Dog
Owner
DogOwner (contains non-nullable DogID and OwnerID FKs that together make up the PK)

然后,你会这样做:

select *
from Dog d
left outer join DogOwner do on d.DogID = do.DogID
left outer join Owner o on do.OwnerID = o.OwnerID

此查询检索所有狗,即使是没有所有者的狗。

这比您的设计有一些改进:

  • 将表Dog命名为因为狗不会长时间停留小狗(嗅探)
  • 使用交集表DogOwner,因为Dogs可以拥有多个所有者。我知道我的确如此!

答案 2 :(得分:3)

如果每只小狗真的只能由一个人拥有,那么当然,如果它还没有,则将fk留空/ NULL。

否则,我建议3个表

  • 小狗信息
  • 所有者信息
  • 小狗所有者

puppy owner行将包含两列:puppy-id,owner-id。即使你说一只小狗只能拥有一个主人,事实是它很可能被所有成年人“拥有”。如果它是表演犬,它很可能由饲养员和一个或多个其他人共同拥有。

答案 3 :(得分:2)

这是一个有趣的建模问题,因为可以说小狗商店拥有所有不属于其他人的小狗。毕竟,如果Li'l Cujo继续横冲直撞并扼杀一些顾客的脚踝,小狗店老板将承担所有破伤风刺戳的费用。当Patti Page为她的爱人购买那只小狗时,交易是一种所有权的变化,而不是它的创造。

这个论点的逻辑是OwnerId是一个NOT NULL列。

答案 4 :(得分:0)

你现在拥有的桌子(小狗和老板)应该没问题。在Puppy表中,您将有一个名为OwnerID的列,它是Owner表的FK。允许它为NULL是很好的。当它为空时,没有人拥有这只小狗。

答案 5 :(得分:-1)

Create table owner (ownerid int PRIMARY KEY, ownername varchar(50) not null)

Create table dog(ownerid int, dogid int, dogname varchar(50), CONSTRAINT pk_col PRIMARY KEY (ownerid, dogid), constraint fk_col foreign key (ownerid) references owner(ownerid) );

这是您可以拥有的最佳解决方案。表设计传达的是您拥有所有者表中的所有者列表,而表狗只有所有者存在于所有者表中的那些条目,即父表,并且他有一只狗。只有那些拥有主人的小狗才能进入狗桌。

支持您的要求的查询。

SELECT owner.ownerid, dog.dogid, dog.dogname FROM owner, dog
WHERE owner.ownerid = dog.ownerid

答案 6 :(得分:-3)

您可以创建一个特殊的所有者“Nobody”并让所有无主的小狗引用它,而不是拥有一个空的所有者。如果您的数据库无法索引空FK并且您开始寻找无主小狗的性能问题,这可能是有意义的。

这使设计复杂化了一些;如果有疑问,请先尝试使用null owner方法。