候选键的概念是否只存在于理论上?

ani*_*nir 6 rdbms primary-key relational-theory unique-constraint candidate-key

我知道 RDBMS 理论中候选键的概念,但是候选键真的存在于实际的 SQL 引擎中吗?我的意思是有什么方法可以在任何 SQL 数据库管理系统(例如 SQL Server、Postgres、MySQL、Oracle 等)中将特定列或列集指定为候选键?

是否有任何保留关键字用于将列指定为候选键,例如PRIMARY KEYUNIQUE在主键列和唯一列的情况下?

我觉得UNIQUE约束本身提供了候选键概念的实现。我认为拥有单独的CANDIDATE KEY关键字没有任何实际价值。是这样吗?

MDC*_*CCL 8

据我所知,没有 SQL 数据库管理系统 (DBMS) 提供这样的CANDIDATE KEY关键字,但是(我认为您在问题中建议)这并不意味着候选键的概念(或功能)不能在 SQL 表中配置。

如何表示候选键

例如,如果

  • 没有为正在考虑的表声明主要,并且
  • 一整套配置了 UNIQUE 约束的列(即一个或多个)也用相应的 NOT NULL 约束固定,

那么设计者就准确地表示了一个候选键。

例如,下表显示了三个不同的候选键:

CREATE TABLE Foo (
    FooId  INT      NOT NULL,
    Bar    CHAR(30) NOT NULL,
    Baz    DATETIME NOT NULL,
    Qux    INT      NOT NULL,
    Corge  CHAR(25) NOT NULL,
    Grault INT      NOT NULL,
    Garply BIT      NOT NULL,
    Plugh  TEXT     NOT NULL,
    CONSTRAINT Foo_CK1 UNIQUE (FooId),          -- Single-column CANDIDATE KEY
    CONSTRAINT Foo_CK2 UNIQUE (Bar),            -- Single-column CANDIDATE KEY
    CONSTRAINT Foo_CK3 UNIQUE (Baz, Qux, Corge) -- Multi-column  CANDIDATE KEY
);
Run Code Online (Sandbox Code Playgroud)

如您所知,以这种方式设置的候选键容易成为一个或多个外键约束的引用。

值得强调的是,由于 SQL 及其方言包含 NULL 标记的概念,因此单独的 UNIQUE 约束不足以代表候选键(如上面的 DDL 示例中所述)。这一点特别重要,因为被约束为候选键的列不能保留 NULL 标记,否则它不能被视为真正的候选键(此外,有理由认为一个表在其任何列中包含 NULL 标记不能被视为关系表,但是,是的,这是一个不同的主题)。

这与CANDIDATE KEY关键字方法有何不同?

这样,如果某个 SQL DBMS 的供应商/开发者想要提供CANDIDATE KEY关键字,那么这种约束,除了明显的唯一性强制之外,还必须确保拒绝任何在相关列中插入 NULL 标记的尝试),将使其与结合 UNIQUENOT NULL 约束的方法不同的因素。

如何描绘备用键

如果相反,

  • 选择了一组特定的列并将其定义为给定表的主键,并且
  • 另一组列被约束为 UNIQUE,并且该组的每个成员也固定为 NOT NULL 约束,

那么设计者就代表了一个备用键(如果某个表有一个或多个候选键,并且其中一个被授予主键的状态,则其余的键成为备用键)。

例如,下表显示了一个 PRIMARY KEY 和三个 ALTERNATE KEY:

CREATE TABLE Foo (
    FooId  INT,
    Bar    CHAR(30) NOT NULL,
    Baz    DATETIME NOT NULL,
    Qux    INT      NOT NULL,
    Corge  CHAR(25) NOT NULL,
    Grault INT      NOT NULL,
    Garply BIT      NOT NULL,
    Plugh  TEXT     NOT NULL,
    CONSTRAINT Foo_PK  PRIMARY KEY (FooId),           -- Single-column PRIMARY KEY
    CONSTRAINT Foo_AK1 UNIQUE      (Bar),             -- Single-column ALTERNATE KEY
    CONSTRAINT Foo_AK2 UNIQUE      (Baz, Qux, Corge), -- Multi-column  ALTERNATE KEY
    CONSTRAINT Foo_AK3 UNIQUE      (Grault)           -- Single-column ALTERNATE KEY
);
Run Code Online (Sandbox Code Playgroud)

显然,上面演示的备用键可以从一个或多个外键约束中引用。

CANDIDATE KEY当已经有 PRIMARY KEY 时使用关键字?

假设有一个DBMS确实提供了CANDIDATE KEY关键字,如果一个表有主键声明,那么候选键的创建应该被拒绝,并且该DBMSALTERNATE KEY在适用时也应该提供代表一个或多个备用键的关键字.

同一张表的图示 (i) 有一个候选键和 (ii) 有主键

是的,在数据​​库的逻辑抽象级别,通过表级 UNIQUE 约束结合适用的列级 NOT NULL 对应项建立的候选键,示例如下:

CREATE TABLE Foo (
    FooId  INT      NOT NULL, 
    Bar    CHAR(30) NOT NULL,
    Baz    DATETIME NOT NULL,
    CONSTRAINT Foo_CK UNIQUE (FooId)
);
Run Code Online (Sandbox Code Playgroud)

...将等效于如下所示设置的主键:

CREATE TABLE Foo (
    FooId  INT,
    Bar    CHAR(30) NOT NULL,
    Baz    DATETIME NOT NULL,
    CONSTRAINT Foo_PK PRIMARY KEY (FooId) -- Single-column PRIMARY KEY, constraint that implies the rejection of NULL marks.
);
Run Code Online (Sandbox Code Playgroud)

这是因为,如果给定表只有一个候选键(其如前所示,可以是复合材料,即,两个或更多个列的组成),那么它可以被认为是,自动地主键。

物理层面的支持

并且,是的,为了支持 UNIQUE 约束,一些 DBMS可能会使用一个索引,其类型与用于维持 PRIMARY KEY 对应项的索引不同(例如,非聚集聚集),但这是一个因素这是物理(或内部)抽象级别的一部分(顺便说一句,根据使用的 DBMS 可能适用也可能不适用),因此它完全超出了为表配置的逻辑级别约束的范围(只要 DBMS 保证所涉及的列中包含的值的唯一性)。