【问题标题】:Is a primary key required? (6NF implementation)是否需要主键? (6NF 实施)
【发布时间】:2013-05-13 11:42:39
【问题描述】:

是 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 &&)
);

是否需要在party_address_is_billing 表上显式声明PRIMARY KEY?由于排除约束指定了唯一标识符 ((address_id, party_id, transaction_time)),因此显式指定 PRIMARY KEY (address_id, party_id, transaction_time) 似乎是多余的。它还会创建一个额外且不必要的索引。

  • 未在表上指定PRIMARY KEY 的后果是什么?

【问题讨论】:

    标签: database postgresql normalization


    【解决方案1】:

    关系模型要求每个关系至少有一个键。它不需要您使用特定的关键字。

    在您的 5NF 表中,如果您将键声明为 not null unique (address_id, party_id),则根本不会更改底层依赖项。从关系的角度来看,这就是您必须关注的问题——替代语法不会破坏底层的依赖关系。 (这意味着关系模型不关心实现的“额外和不必要的索引”。)

    所以,在“party_address_is_billing”中,如果排除约束表现得像一个关键约束,我认为就关系模型而言你没问题。

    未在表上指定 PRIMARY KEY 的后果是什么?

    1. 如果您将主键约束替换为另一个行为相同的声明性约束,您可能会让维护程序员感到惊讶。请参阅文章Principle of least astonishment

    2. 您还可以让框架程序员更加努力地工作。许多框架不仅需要 PRIMARY KEY 约束,还要求约束是代理整数。 (这不是一个真正的关系问题。)

    3. 某些软件工程 (CASE) 工具可能会因排除约束而窒息。

    4. 与违反排除约束的进程相关的错误消息可能不如关于违反主键约束的错误消息那么清楚。 (这与上面的“1”有关。)

    就关系模型而言,我认为没有任何后果。 (也就是说,只要您用行为相同的声明性约束替换主键约束。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-22
      • 1970-01-01
      • 2012-02-07
      • 2011-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多