Skip to main content

SQLite主键:主键的终极指南

SQLite主键简介

主键是一列或一组列,用于标识表中行的唯一性。每个表只有一个主键。

SQLite允许您以两种方式定义主键:

首先,如果主键只有一列,则使用主键列约束定义主键,如下所示:

CREATE TABLE table_name(
column_1 INTEGER NOT NULL PRIMARY KEY,
...
);

其次,如果主键由两列或多列组成,则使用主键表约束来定义主键,如下面的语句所示。

CREATE TABLE table_name(
column_1 INTEGER NOT NULL,
column_2 INTEGER NOT NULL,
...
PRIMARY KEY(column_1,column_2,...)
);

在SQL标准中,主键列不能包含空值。这意味着主键列具有隐式NOT NULL约束。

然而,为了使SQLite的当前版本与早期版本兼容,SQLite允许主键列包含空值。

SQLite主键和rowid表

在创建表时,如果不指定“不使用ROWID”选项,SQLite会添加一个名为ROWID的隐式列,该列存储64位带符号整数。rowid列是唯一标识表中行的键。具有rowid列的表称为rowid表。

如果表的主键由一列组成,且该列定义为整数,则该主键列将成为rowid列的别名。

请注意,如果将另一个整数类型(如BIGINT和UNSIGNED INT)指定给主键列,则该列将不是rowid列的别名。

因为rowid表将其数据组织为B树,所以查询和排序rowid表的数据非常快。它比使用不是rowid别名的主键更快。

另一个重要注意事项是,如果使用INTEGER类型和主键DESC子句声明列,则此列不会成为rowid列的别名:

CREATE TABLE table(
pk INTEGER PRIMARY KEY DESC,
...
);

创建SQLite主键示例

下面的语句创建一个名为countries的表,该表的主键是country_id列。

CREATE TABLE countries (
country_id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);

试试看

因为countries表的主键只有一列,所以我们使用主键列约束定义主键。

可以使用主键表约束定义由一列组成的主键,如以下语句所示:

CREATE TABLE languages (
language_id INTEGER,
name TEXT NOT NULL,
PRIMARY KEY (language_id)
);

试试看

但是,对于主键由多个列组成的表,必须使用主键表约束来定义主键。

下面的语句创建country_languages表,其主键由两列组成。

CREATE TABLE country_languages (
country_id INTEGER NOT NULL,
language_id INTEGER NOT NULL,
PRIMARY KEY (country_id, language_id),
FOREIGN KEY (country_id) REFERENCES countries (country_id)
ON DELETE CASCADE ON UPDATE NO ACTION,
FOREIGN KEY (language_id) REFERENCES languages (language_id)
ON DELETE CASCADE ON UPDATE NO ACTION
);

试试看

添加SQLite主键示例

与sqlite和PostgreSQL等其他数据库系统不同,不能使用ALTER TABLE语句向现有表添加主键。

您需要遵循以下步骤来克服限制:

见以下声明:

PRAGMA foreign_keys=off;

BEGIN TRANSACTION;

ALTER TABLE table RENAME TO old_table;

-- define the primary key constraint here
CREATE TABLE table ( ... );

INSERT INTO table SELECT * FROM old_table;

COMMIT;

PRAGMA foreign_keys=on;

试试看

BEGIN事务启动一个新事务。它确保所有后续语句成功执行,或者根本不执行任何语句。

COMMIT语句提交所有语句。

让我们创建一个没有主键的表名cities。

CREATE TABLE cities (
id INTEGER NOT NULL,
name text NOT NULL
);

INSERT INTO cities (id, name)
VALUES(1, 'San Jose');

试试看

要将主键添加到cities表,请执行以下步骤:

PRAGMA foreign_keys=off;

BEGIN TRANSACTION;

ALTER TABLE cities RENAME TO old_cities;

CREATE TABLE cities (
id INTEGER NOT NULL PRIMARY KEY,
name TEXT NOT NULL
);

INSERT INTO cities
SELECT * FROM old_cities;

DROP TABLE old_cities;

COMMIT;

PRAGMA foreign_keys=on;

试试看

如果使用SQLite GUI工具,可以使用以下语句显示表的信息。

PRAGMA table_info([cities]);

试试看

SQLite Primary Key Example

在本教程中,您学习了使用SQLite主键约束来定义表的主键。