我正在将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的外键,因此我可以使用同一张表来存储来自两种类型客户的付款
我可以只留下第三个表而没有外键,但是希望添加一个并避免用户输入不正确的数据
答案 0 :(得分:3)
在这种情况下,您有两个(推荐)选项:
就像Impaler所说的那样,在第三张表上使用两列,每列引用一个表并且可以为空(因为理想情况下,一列始终为空)
或者您可以在表之间使用层次结构,在那里您将创建一个名为Client
的表,其中包含ClientF
和ClientM
之间的所有公用数据,以及表{{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。