在任意数量的列上创建多个外键

时间:2014-08-08 17:57:28

标签: sql postgresql foreign-keys

我正在为客户创建一个表,其中有很多列表示他们可能拥有的合同(至少有一个)。可能的合同的列将具有一个整数,该整数对应于另一个表中的合同的ID。

CREATE TABLE "Customer"
(
    firstName    varchar(25),
    lastName     varchar(25),
    contract0    int NOT NULL,
    contract1    int,
       ...
    contract20   int
);

CREATE TABLE "Contracts"
(
     id          int NOT NULL PRIMARY KEY,
     svc_addr    varchar(50),
       ...
);

我的问题是:

1 - 在所有列上创建外键的最简单方法是什么,因为它们都可能“指向”合同表中的一行?我在postgres中遇到过这种语法:

...
contract16    integer references Contracts(id),
...

但似乎这会花费大量的时间进行打字,这是一个问题,我想,当使用这么多列时,这让我想到了下一个问题......

2 - 是否有更简单的方法来创建一个包含 n 这些“重复”列的表(然后可能将键全部放在它们上面)?制作python脚本之外的东西。

感谢

3 个答案:

答案 0 :(得分:1)

是的,有一种更简单的方法。

如果每个合同只与一个客户相关联,则需要将Customer_ID放入Contracts表,并在该列上放置外键。

您已经知道一个客户可以拥有多个合同。如果每个合同也可以拥有多个客户,那么您就拥有多对多的关系,并且需要在中间建立第三个表。例如,它可以被称为CustomerContracts,并且有两列,CustomerIDContractID。然后你将有两个外键(每个列一个)。

无论哪种方式,“任意”部分都会消失。

答案 1 :(得分:0)

尝试添加整数ContractType列,而不是使用多个contractN列。这将对应于示例中的0..20值。您可以将外键添加到ContractType表中,以确保该数字表示有效类型。

答案 2 :(得分:0)

您真的应该考虑更多地规范化数据库结构。换句话说,创建另一个这样的表:

CREATE TABLE "Customer"
(
    customerId   bigserial primary key,
    firstName    varchar(25),
    lastName     varchar(25)
);

CREATE TABLE "CustomerContract"
(
    customerContractId bigserial primary key,
    customerId     int references Customer(customerId),
    contractId     int references Contracts(id),
    contractNumber int
);


CREATE TABLE "Contracts"
(
    id          int not null primary key,
    svc_addr    varchar(50),
   ...
);

首先,您要创建您的客户。

然后,在创建合同时,您将插入合同行,然后通过CustomerContract表将其绑定到客户。

这允许客户拥有无限数量的合同,而不会为不存在的合同浪费空间。另一个好处是,给定contractId,您可以快速查找与其关联的客户,而无需索引Customer表中所有未使用的合同列。

旁注:我会考虑更改"合同"的名称。单数而不是复数(几乎总是让你的表名单数)。我也会改变" id" ContractId的合同列,以便在您在其他SQL语句中引用它时,将清楚它是什么类型的ID。