跳到主要内容

SQL PRIMARY KEY约束

以下是 SQL 中 PRIMARY KEY 约束的三个关键知识点的概括:

  1. PRIMARY KEY 约束的定义和作用:在 SQL 中,PRIMARY KEY 约束用于唯一地识别表中的每一行。它结合了 NOT NULLUNIQUE 约束,保证了列中的每个值都是唯一的,且不允许为空。

  2. PRIMARY KEY 约束的语法PRIMARY KEY 约束可以在创建表时直接定义,例如 CREATE TABLE Colleges (college_id INT, CONSTRAINT CollegePK PRIMARY KEY (college_id));。此外,也可以使用 ALTER TABLE 命令向现有表添加 PRIMARY KEY 约束。

  3. 主键错误和自动递增主键:尝试向主键列插入重复值或 NULL 时,会触发错误。许多数据库支持自动递增的主键,例如 SQL Server 的 IDENTITY、MySQL 的 AUTO_INCREMENT 和 PostgreSQL 的 SERIAL

在 SQL 中,PRIMARY KEY 约束用于唯一地识别行。它是 NOT NULLUNIQUE 约束的组合,即它不能包含重复或 NULL 值。

示例

CREATE TABLE Colleges (
college_id INT,
college_code VARCHAR(20) NOT NULL,
college_name VARCHAR(50),
CONSTRAINT CollegePK PRIMARY KEY (college_id)
);

这里,college_id 列是 PRIMARY KEY。这意味着这一列的值必须是唯一的,并且不能包含 NULL 值。

请注意,上述代码适用于所有主要数据库系统。但是,某些数据库可能有不同的语法。

SQL PRIMARY KEY 语法

SQL PRIMARY KEY 约束的语法是:

CREATE TABLE table_name (
column1 data_type,
...,
[CONSTRAINT constraint_name] PRIMARY KEY (column1)
);

这里,

  • table_name 是要创建的表的名称
  • column1 是要定义 PRIMARY KEY 约束的列的名称
  • constraint_name 是给约束指定的任意名称
  • [...] 表明其中的代码是可选的。

注意: 尽管使用 [CONSTRAINT constraint_name] 命名约束是可选的,但这样做会使对约束进行更改和删除变得更容易。

主键错误

在 SQL 中,如果我们尝试在主键列中插入 NULL 或重复值,我们将得到错误。

NOT NULL 约束错误

当我们为主键提供 NULL 值时会出现此错误。这是因为主键需要遵守 NOT NULL 约束。例如,

-- 主键(college_id)的值是 NULL
INSERT INTO Colleges(college_id, college_code, college_name)
VALUES ("ARD12", "Star Public School");

这里,SQL 命令给我们一个错误,因为我们为 Colleges 表中的主键 college_id 提供了 NULL 值。

修复 NOT NULL 约束错误

-- 主键(college_id)的值是 1
INSERT INTO Colleges(college_id, college_code, college_name)
VALUES (1, "ARD12", "Star Public School");

这里,SQL 命令没有错误,因为我们为主键即 college_id 提供了值 1

UNIQUE 约束错误

当我们为主键提供重复值时会出现此错误,这违反了它的 UNIQUE 约束。例如,

VALUES (1, "ARD12", "Star Public School");

-- UNIQUE 约束错误
-- college_id 的值不是唯一的
INSERT INTO Colleges(college_id, college_code, college_name)
VALUES (1, "ARD12", "Star Public School");

这里,SQL 命令给我们一个错误,因为我们向主键 college_id 中插入了重复的值 1

修复 UNIQUE 约束错误

VALUES (1, "ARD12", "Star Public School");

-- 插入成功
INSERT INTO Colleges(college_id, college_code, college_name)
VALUES (2, "ARD12", "Star Public School");

这里,SQL 命令因为我们为 college_id 提供了唯一值 12 而没有错误地运行。

注意: 一个表中只能有一个主键。然而,这一个主键可以包含多个列。

多列的主键

主键也可以由多个列组成。例如,

CREATE TABLE Colleges (
college_id INT,
college_code VARCHAR(20),
college_name VARCHAR(50),
CONSTRAINT CollegePK PRIMARY KEY (college_id, college_code)
);

这里,名为 CollegePKPRIMARY KEY 约束由 college_idcollege_code 列组成。

这意味着 college_idcollege_code 的组合必须是唯一的,并且这两列不能包含 NULL 值。

使用 ALTER TABLE 添加主键约束

我们还可以使用 ALTER TABLE 命令向现有表中的列添加 PRIMARY KEY 约束。例如,

对单列

ALTER TABLE Colleges
ADD PRIMARY KEY (college_id);

这里,SQL 命令向现有的 Colleges 表中的 college_id 列添加了 PRIMARY KEY 约束。

对多列

ALTER TABLE Colleges
ADD CONSTRAINT CollegePK PRIMARY KEY (college_id, college_code);

这里,SQL 命令向现有的 Colleges 表中的 college_idcollege_code 列添加了 PRIMARY KEY 约束。

注意: 这个命令不被我们的在线 SQL 编辑器支持,因为它基于 SQLite。

自动递增主键

通常的做法是在插入新行时自动增加主键的值。例如,

SQL Server

-- 使用 IDENTITY(x, y) 来自动递增值
-- x -> 起始值,y -> 增加的步长
CREATE TABLE Colleges (
college_id INT IDENTITY(1,1),
college_code VARCHAR(20) NOT NULL,
college_name VARCHAR(50),
CONSTRAINT CollegePK PRIMARY KEY (college_id)
);

-- 插入记录时不需要 college_id
INSERT INTO Colleges(college_code, college_name)
VALUES ("ARD13", "Star Public School");

Oracle

-- 创建数字序列
CREATE SEQUENCE auto_inc
MINVALUE 1
START WITH 1
INCREMENT BY 1
CACHE 10;

CREATE TABLE Colleges (
college_id INT,
college_code VARCHAR(20) NOT NULL,
college_name VARCHAR(50),
CONSTRAINT CollegePK PRIMARY KEY (college_id)
);

-- 创建触发器以在插入前
-- 添加自动递增的值
CREATE TRIGGER auto_inc_trigger
BEFORE INSERT ON Colleges
FOR EACH ROW
BEGIN
SELECT auto_inc.nextval INTO :new.college_id FROM dual
END;

-- 插入记录时不需要 college_id
INSERT INTO Colleges(college_code, college_name)
VALUES ("ARD13", "Star Public School");

MySQL

-- AUTO_INCREMENT 关键字自动递增值
CREATE TABLE Colleges (
college_id INT AUTO_INCREMENT,
college_code VARCHAR(20) NOT NULL,
college_name VARCHAR(50),
CONSTRAINT CollegePK PRIMARY KEY (college_id)
);

-- 插入不包含 college_id 的记录
INSERT INTO Colleges(college_code, college_name)
VALUES ("ARD13", "Star Public School");

PostgreSQL

-- SERIAL 关键字自动递增值
CREATE TABLE Colleges (
college_id INT SERIAL,
college_code VARCHAR(20) NOT NULL,
college_name VARCHAR(50),
CONSTRAINT CollegePK PRIMARY KEY (college_id)
);

-- 插入不包含 college_id 的记录
INSERT INTO Colleges(college_code, college_name)
VALUES ("ARD13", "Star Public School");

移除 PRIMARY KEY 约束

我们可以使用 DROP 子句移除表中的 PRIMARY KEY 约束。例如,

SQL Server, Oracle

ALTER TABLE Colleges
DROP CONSTRAINT CollegePK;

MySQL

ALTER TABLE Colleges
DROP PRIMARY KEY;

这里,SQL 命令从 Colleges 表中移除了 PRIMARY KEY 约束。

推荐阅读: