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主键约束来定义表的主键。