代码之家  ›  专栏  ›  技术社区  ›  Aaron Powell

单个列的多个外键

  •  23
  • Aaron Powell  · 技术社区  · 15 年前

    我正在为客户/订单系统定义一个数据库,其中有两种截然不同的客户类型。因为拥有一个客户表是如此的不同,所以非常难看(因为对于一种类型来说,空列是毫无意义的)。

    但他们的订单格式相同。有没有可能 CustomerId “我的订单”表中的哪一列具有两种客户类型的外键?我在SQL Server中设置了它,它没有给我带来任何问题 创建 关系,但我还没有尝试插入任何数据。

    另外,我正计划使用NHibernate作为ORM,这样的关系会带来什么问题吗?

    7 回复  |  直到 10 年前
        1
  •  24
  •   Guffa    15 年前

    不,不能将单个字段作为两个不同表的外键。你怎么知道在哪里找钥匙?

    您至少需要一个字段来告诉它是哪种用户,或者两个单独的外键。

    您还可以将所有用户通用的信息放在一个表中,并为特定于用户类型的信息提供单独的表,这样您就有了一个以用户ID为主键的表。

        2
  •  4
  •   Marc Gravell    15 年前

    外键只能引用单个主键,因此不能。但是,可以使用桥接表:

    CustomerA <---- CustomerA_Orders ----> Order
    CustomerB <---- CustomerB_Orders ----> Order
    

    所以命令根本就没有 一把外键;不过,这是否可取…

        3
  •  1
  •   Raj    15 年前

    可以创建引用多个表的外键。这个特性允许表的垂直分割,并且仍然保持引用完整性。但是,在您的情况下,这不适用。

    最好是有一个可能有列的customertype表-customertypeid、customerid,其中customerid是pk,然后将orderid表引用到customerid。

    拉吉

        4
  •  1
  •   Dave G.    10 年前

    我继承了一个执行此操作的SQL Server数据库(在具有四个不相关表的四个外键关系中使用了一列),所以是的,这是可能的。我的前任已经走了,所以我不能问他为什么认为这是个好主意。

    他使用了一个guid列(“uniqueidentifier”类型)来避免歧义问题,并且关闭了对外键的约束检查,因为它保证只有一个匹配。但我能想到很多你不应该想到的理由,我也没有想到任何你应该想到的理由。

    您的问题听起来确实像经典的“专门化”问题,通常通过创建一个包含共享客户数据的父表,然后创建两个包含每个客户类唯一数据的子表来解决。然后,您的外键将与父客户表相对,并且您将根据哪个子表具有匹配条目来确定哪种类型的客户。

        5
  •  0
  •   Jay    15 年前

    如前所述,如果键是12345,您如何知道要在哪个表中查找它?我想,您可以做一些事情来确保两个表的键值永远不会重叠,但是这太难看了,而且难以思考。您可以有第二个字段来说明它是哪种客户类型。但是,如果要有两个字段,为什么不为客户类型1 ID提供一个字段,为客户类型2 ID提供另一个字段。

    在不了解更多关于您的应用程序的信息的情况下,我的第一个想法是,您真的应该有一个通用的客户表,其中包含两个通用的数据,然后有两个额外的表,其中包含特定于每个客户类型的数据。我认为这两者之间一定有很多共同的数据——至少是像姓名、地址和客户编号之类的基本数据——而且跨表重复列是很糟糕的。然后,其他表可以引用回基表。因为基表只有一个键,所以外键的问题必须知道引用哪个表就消失了。

        6
  •  0
  •   Community CDub    7 年前

    两种不同类型的客户是典型的类型和子类型,或者,如果您愿意,是类和子类。 Here 是另一个问题的答案。

    本质上,类表继承技术类似于Arnand的答案。共享主键技术的使用允许您在一列中绕过两种类型的外键所造成的问题。外键将是CUSTOMER-ID。它将标识CUSTOMER表中的一行,以及相应类型的CUSTOMER类型表中的一行(视情况而定)。

        7
  •  -1
  •   Anand    10 年前
    1. 创建一个“customer”表,包括所有对这两种类型的客户具有相同数据的列。
    2. 创建表“customer_a”和“customer_b”
    3. 将“consumer”表中的“customer_id”用作“customer_a”和“customer_b”中的外键

                      customer
                          |
           ---------------------------------
           |                               |
      cusomter_a                      customer_b