ani*_*nir 6 rdbms primary-key relational-theory unique-constraint candidate-key
我知道 RDBMS 理论中候选键的概念,但是候选键真的存在于实际的 SQL 引擎中吗?我的意思是有什么方法可以在任何 SQL 数据库管理系统(例如 SQL Server、Postgres、MySQL、Oracle 等)中将特定列或列集指定为候选键?
是否有任何保留关键字用于将列指定为候选键,例如PRIMARY KEY
或UNIQUE
在主键列和唯一列的情况下?
我觉得UNIQUE
约束本身提供了候选键概念的实现。我认为拥有单独的CANDIDATE KEY
关键字没有任何实际价值。是这样吗?
据我所知,没有 SQL 数据库管理系统 (DBMS) 提供这样的CANDIDATE KEY
关键字,但是(我认为您在问题中建议)这并不意味着候选键的概念(或功能)不能在 SQL 表中配置。
例如,如果
那么设计者就准确地表示了一个候选键。
例如,下表显示了三个不同的候选键:
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 标记的尝试),将使其与结合 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
在适用时也应该提供代表一个或多个备用键的关键字.
是的,在数据库的逻辑抽象级别,通过表级 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 保证所涉及的列中包含的值的唯一性)。