同时到多个表的外键

时间:2018-09-19 17:21:12

标签: sql foreign-keys firebird

我正在将Firebird数据库用于软件,发现问题

我有2张桌子,可用于2种不同类型的客户:

clientM(

    rfcM varchar(12) primary key

    some other data  

)

clientF(

    rfcF varchar(13) primary key

    some other data

)

(长度是固定的,因为它是墨西哥人希望用户输入的数据的标准)

问题来了,我需要创建第三个表:

clientPayment(

    rfcClient varchar(13)

    some other data

)

并且该字段必须具有同时引用clientM.rfcM和clientF.rfcF的外键,因此我可以使用同一张表来存储来自两种类型客户的付款

我可以只留下第三个表而没有外键,但是希望添加一个并避免用户输入不正确的数据

2 个答案:

答案 0 :(得分:3)

在这种情况下,您有两个(推荐)选项:

  • 就像Impaler所说的那样,在第三张表上使用两列,每列引用一个表并且可以为空(因为理想情况下,一列始终为空)

  • 或者您可以在表之间使用层次结构,在那里您将创建一个名为Client的表,其中包含ClientFClientM之间的所有公用数据,以及表{{1 }}和ClientF将具有每种类型的客户端的特定数据,并有一个ClientM / ClientF.ID引用其父表。并且您的ClientM.ID表将有一个列引用父表clientPayment

答案 1 :(得分:1)

我强烈建议您使用两列,每个外键使用一列。您可能希望这些列可以为空,因此一行可能会“指向”一个相关表或另一个相关表(甚至两者)。

从技术上讲,可以使用单列为两个相关表存储外键。但是,您将无法随意指向一个,因为foreign key约束将强制一个非null值始终存在于两个相关表中。您将需要删除外键约束,这是一个很大的禁忌。

简而言之,这就是我的看法:

clientPayment(
  rfcM varchar(12) references clientM, -- nullable by default
  rfcF varchar(13) references clientF, -- nullable by default
  constraint one_and_only_one_fk check (
    clientM is null and clientF is not null or
    clientM is not null and clientF is null
  ),
  some other data
)

该约束可防止两个fks同时为null或同时不为null。