多个表之间的SQL映射

时间:2010-01-11 20:40:33

标签: sql database-design union foreign-key-relationship

这是一个SQL设计问题。首先,设置。我有三张桌子:

  1. A,根据对链接服务器的查询自动填充。无法更改此表中的数据;
  2. B,只有十几行,包含As;
  3. 的集合名称
  4. AtoB,它是将As组织成命名集合的映射表,两列都有外键;
  5. SQL Mapping Table

    例如,A包含:

    1. 长颈鹿
    2. 猫头鹰
    3. B包含:

      1. 西雅图动物园
      2. 圣何塞动物园
      3. AtoB包含:

        1,1(西雅图的长颈鹿)
         2,1(西雅图猫头鹰)
         3,1(西雅图老虎)
         2,2(圣何塞的猫头鹰)

        现在,问题是:

        我被要求在A中包含一些在A中找不到的项目。因此,我创建了一个表C,其中包含与A相同的标识和名称列,并填充它。与前面的例子一致,假设C包含:

        1. 问题是,如何在AtoB中包含C中的项目?如果我需要在西雅图动物园中加入一条龙怎么办?

          我的第一直觉是天真,就是创建一个包含A和C联合的视图V,并将AtoB修改为VtoB。这就是我的天真得到回报的地方:一个人无法为视图创建外键。

          我怀疑有一种标准的,正确的方法可以将一个或多个A OR C与B联系起来。

4 个答案:

答案 0 :(得分:10)

要扩展Arthur Thomas的解决方案,这里是一个union,在子选择中没有WHERE,以便您可以创建一个通用视图:

SELECT A.Name as Animal, B.Name as Zoo FROM A, AtoB, B
    WHERE AtoB.A_ID = A.ID && B.ID = AtoB.B_ID 
UNION
SELECT C.Name as Animal, B.Name as Zoo FROM C, CtoB, B
    WHERE CtoB.C_ID = C.ID && B.ID = CtoB.B_ID

然后,您可以执行以下查询:

SELECT Animal FROM zoo_animals WHERE Zoo="Seattle Zoo"

答案 1 :(得分:5)

如果你不能将龙放入A,那么你需要创建另一个表和另一个链表。问题是创建一个需要存储的唯一数据集(另一个表),它不能与A设置相同。因为它不是同一个集,所以你不能再使用具有外来的链接表(AtoB)确保链接是来自集合A的引用的键。因此,您可以创建如下表格:

imaginary_creatures

  • ID
  • 名称

imaginary_creatures_to_b

  • imaginary_creatures_id(链接到imaginary_creatures表)
  • b_id(链接到动物园表)

后来当你想要动物园中的所有生物时,你可以做一个UNION

SELECT A.Name FROM A where A.ID IN 
   (SELECT AB.A_ID FROM AtoB AB WHERE B_ID = 
      (SELECT B.ID FROM B WHERE B.Name = 'Zoo Name'))
UNION
SELECT i.name FROM imaginary_creatures i i.id IN 
   (SELECT ic.imaginary_creatures_id FROM imaginary_creatures_to_c ic 
    WHERE ic.b_id = (SELECT B.ID FROM B WHERE B.Name = 'Zoo Name'))

可能有更好的写作方式,但它应该适用于您的目的。

答案 2 :(得分:1)

Arthur Thomas有一个很好的解决方案,另一个可能的解决方案是在链接表中添加一个列,指示它与哪个表(A或C)相关。然后通过触发器而不是外键强制执行关系。但是Arthur的解决方案确实是做这种事情的首选方式。

答案 3 :(得分:0)

你想要做的是将龙放在A中,如果你想从A中选择所有记录而不管他们是否在AtoB中有匹配的记录,那么做一个LEFT OUTER JOIN。像这样:

SELECT * FROM A
LEFT OUTER JOIN AtoB
ON A.id = AtoB.A_ID

编辑:这只有在您可以将新记录添加到A时才有效。我错过了您无法做到的事实。我认为Arthur Thomas的解决方案就是你想要的。