第三个表中的一对零或多个关联和FK用法

时间:2012-05-16 09:40:20

标签: sql database-design

我有两张桌子 - 第一张是地方,第二张是位置。地方可以有零个或多个地点。放置PK是id,位置PK是两个组件键place_id + id。

enter image description here

在第三张表(例如发票)中我可以找到没有任何位置的地方。

问题是:如何在发票表中设置FK?

  1. 我不能只使用place.id作为FK因为我想知道位置。
  2. 如果我使用包含place_id + id列的位置PK - 那么与表位置的关系不一致 - 某些地方可以有0位置。
  3. 因此,主要问题是某个地方可能有0个地点。

    是的,我可能在位置表中设置代理PK,并设置place_id FK,location_id FK NULL。但是,要求是地点和位置键是自然的(基于公司组织结构)。第二个想法是具有一对一/多个关联,并将位置id值0放入具有零位置的位置并在用户界面中隐藏该位置。实际上,我需要为每个地点放置0(没有位置)。

    感谢。

1 个答案:

答案 0 :(得分:2)

您应该能够简单地将这两个FK“合并”在一起:

enter image description here

CREATE TABLE invoice (
    id INT PRIMARY KEY,
    place_id INT NOT NULL,
    location_id INT NULL,
    FOREIGN KEY (place_id) REFERENCES place (id),
    FOREIGN KEY (place_id, location_id) REFERENCES location (place_id, id)
);

DBMS将忽略至少有一个NULL的FK:

  • place_id不是NULL,因此第一个FK将始终有效。
  • 如果location_id为NULL,则只会忽略第二个FK。

您可以在此SQL Fiddle中使用它。

(事实上,自然键的存在使你能够做到这一点 - 如果location有一个代理键,你不能保证两个FK指向同一个{{1 }}。)


在不太可能的情况下,您的DBMS以有趣的方式处理NULL,因此不会忽略具有NULL的FK,您可以完全分离这两个FK,并使用CHECK确保它们属于同一位置:

place