是5NF关系的6NF relvar表中所需的主键。请考虑以下设置:
-- The 5NF table
CREATE TABLE party_address(
address_id int NOT NULL,
party_id int NOT NULL,
-- some other columns
PRIMARY KEY (address_id, party_id)
);
CREATE TABLE party_address_is_billing(
address_id int NOT NULL,
party_id int NOT NULL,
value boolean NOT NULL,
transaction_time tstzrange NOT NULL DEFAULT tstzrange(CURRENT_TIMESTAMP, NULL, '[)'),
EXCLUDE USING GIST (address_id WITH =, party_id WITH =, transaction_time WITH &&)
);
是否需要在PRIMARY KEY
表上明确声明party_address_is_billing
?由于排除约束指定了唯一标识符((address_id, party_id, transaction_time)
),因此显式指定PRIMARY KEY (address_id, party_id, transaction_time)
似乎是多余的。它还会创建一个额外的和不必要的索引。
PRIMARY KEY
会产生什么后果?答案 0 :(得分:2)
关系模型要求每个关系至少有一个密钥。它不要求您使用特定关键字。
在5NF表中,如果将密钥声明为not null unique (address_id, party_id)
,则根本不会更改底层依赖项。从关系的角度来看,这就是你必须要关注的 - 替代语法不会搞砸底层的依赖关系。 (这意味着关系模型不关心实现的“附加和不必要的索引”。)
因此,在“party_address_is_billing”中,如果排除约束的行为类似于键约束,我认为就关系模型而言,你是好的。
不在表格上指定PRIMARY KEY有什么后果?
如果将主键约束替换为行为相同的另一个声明性约束,则可能会让维护程序员感到惊讶。请参阅文章Principle of least astonishment。
您可能也会让框架程序员更加努力。许多框架不仅需要PRIMARY KEY约束,还要求约束为代理整数。 (这不是一个真正的关系问题。)
某些软件工程(CASE)工具可能会限制排除约束。
与违反排除约束的进程关联的错误消息可能不如关于违反主键约束的错误消息更清晰。 (这与上面的“1”有关。)
就关系模型而言,我认为没有任何后果。 (也就是说,只要使用行为相同的声明性约束替换主键约束。)