↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1 / 7.0 / 6.5 / 6.4
历史版本PostgreSQL 7.4 已于 2010 年 10 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

CREATE TABLE

CREATE TABLE — 定义一个新表

大纲

CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name (
  { column_name data_type [ DEFAULT default_expr ] [ column_constraint [ ... ] ]
    | table_constraint
    | LIKE parent_table [ { INCLUDING | EXCLUDING } DEFAULTS ] }  [, ... ]
)
[ INHERITS ( parent_table [, ... ] ) ]
[ WITH OIDS | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]

where column_constraint is:

[ CONSTRAINT constraint_name ]
{ NOT NULL | NULL | UNIQUE | PRIMARY KEY |
  CHECK (expression) |
  REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
    [ ON DELETE action ] [ ON UPDATE action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]

and table_constraint is:

[ CONSTRAINT constraint_name ]
{ UNIQUE ( column_name [, ... ] ) |
  PRIMARY KEY ( column_name [, ... ] ) |
  CHECK ( expression ) |
  FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]
    [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]

描述

CREATE TABLE 将在当前数据库中创建一个新的、初始为空的表。该表归发出该命令的用户所有。

如果给出了模式名(例如 CREATE TABLE myschema.mytable ...),则表将在指定模式中创建。 否则,它将在当前模式中创建。临时表存在于一个特殊模式中,因此创建临时表时不能给出模式名。 表名必须与同一模式中任何其他表、序列、索引、视图的名称不同。

CREATE TABLE 还会自动创建一种数据类型,用以表示与该表一行对应的复合类型。因此,表名不能与同一模式中任何已有数据类型同名。

一个表不能有超过 1600 列。(实际上,由于元组长度限制,有效的限制通常更低。)

可选的约束子句指定插入或更新要成功时,新行或更新后的行必须满足的约束(测试)。约束是一种 SQL 对象,可用多种方式帮助定义表中允许的值集合。

定义约束有两种方式:表约束和列约束。列约束作为列定义的一部分定义。表约束则不绑定到特定列,并且可以涵盖多个列。每个列约束也都可以写成表约束;当约束只影响一列时,列约束只是一种书写上的方便。

参数

TEMPORARY or TEMP

如果指定该选项,表将创建为临时表。 临时表会在会话结束时自动删除,或者也可在当前事务结束时删除(见下文 ON COMMIT)。 在临时表存在期间,同名的现有永久表对当前会话不可见,除非使用带模式限定的名称引用它们。 在临时表上创建的任何索引也都会自动成为临时索引。

可以选择在 TEMPORARY 或 TEMP 前写上 GLOBAL 或 LOCAL。这在 PostgreSQL 中没有任何区别,但参见 兼容性。

table_name

要创建的表名(可选地带模式限定)。

column_name

要在新表中创建的列名。

data_type

列的数据类型。这可以包括数组说明符。

DEFAULT default_expr

DEFAULT子句为其所在列定义的列指定默认数据值。该值可以是任何不含变量的表达式(不允许子查询,也不允许交叉引用当前表中的其他列)。默认表达式的数据类型必须与该列的数据类型匹配。

默认值表达式会用于任何未为该列指定值的插入操作。如果一列没有默认值,则默认值为 null。

LIKE parent_table [ { INCLUDING | EXCLUDING } DEFAULTS ]

LIKE 子句指定一个表,新表会自动从中继承所有列名、它们的数据类型以及非空约束。

与 INHERITS 不同,新表与被继承表在创建完成之后完全脱钩。向新表中插入的数据不会反映到父表中。

只有指定 INCLUDING DEFAULTS 时,才会包含被复制列定义的默认表达式。默认行为是不包含默认表达式。

INHERITS ( parent_table [, ... ] )

可选的 INHERITS 子句指定一组表,新表将自动从中继承所有列。如果同一列名出现在多个父表中,除非这些父表中该列的数据类型全部匹配,否则会报错。如果没有冲突,这些重复列会合并为新表中的单个列。如果新表的列名列表中包含一个同时也是继承来的列,其数据类型也必须与继承列匹配,并且列定义会合并为一个。不过,同名的继承列声明和新列声明不必指定相同的约束:来自任何声明的所有约束都会合并在一起,并全部应用于新表。如果新表为该列显式指定了默认值,该默认值将覆盖列的继承声明中的任何默认值。否则,为该列指定默认值的所有父表必须指定相同的默认值,否则将报错。

WITH OIDS
WITHOUT OIDS

这个可选子句指定新表的行是否应被分配 OID(对象标识符)。默认是有 OID。(如果新表继承自任何有 OID 的表,那么即使命令写的是 WITHOUT OIDS,也会强制 WITH OIDS。)

指定 WITHOUT OIDS 允许用户抑制表行 OID 的生成。对于大表这可能值得一做,因为它可以减少 OID 消耗,从而推迟 32 位 OID 计数器的回卷。一旦计数器回卷,OID 的唯一性就无法再保证,这会大大降低其用处。指定 WITHOUT OIDS 还会使表的磁盘存储每行减少 4 字节,从而提高性能。

CONSTRAINT constraint_name

列约束或表约束的可选名称。如果未指定,系统会生成一个名称。

NOT NULL

该列不允许包含空值。

NULL

该列允许包含空值。这是默认情况。

该子句仅为兼容非标准 SQL 数据库而提供,不建议在新应用中使用。

UNIQUE (column constraint)
UNIQUE ( column_name [, ... ] ) (table constraint)

UNIQUE 约束指定表中一列或多列组成的一组只能包含唯一值。 表级唯一约束的行为与列级唯一约束相同,只是它还能跨越多列。

对于唯一约束,空值不被视为相等。

每个唯一表约束必须命名一组列,这组列须不同于为该表定义的任何其他唯一约束 或主键约束所命名的列集合。(否则它就只是把同一个约束列出了两次。)

PRIMARY KEY (column constraint)
PRIMARY KEY ( column_name [, ... ] ) (table constraint)

主键约束指定表的一个或多个列只能包含唯一(不重复)的非空值。从技术上讲,PRIMARY KEY只是UNIQUE和NOT NULL的组合,但把一组列标识为主键还为模式设计提供了元数据,因为主键意味着其他表可以依赖这组列作为行的唯一标识符。

一个表只能指定一个主键,无论是作为列约束还是表约束。

主键约束所命名的列集合应当不同于为同一表定义的任何唯一约束所命名的其他列集合。

CHECK (expression)

CHECK 子句指定一个产生布尔结果的表达式,要使插入或更新操作成功,新行或更新后的行必须满足该表达式。作为列约束指定的检查约束只应引用该列的值,而出现在表约束中的表达式可以引用多个列。

当前,CHECK 表达式不能包含子查询,也不能引用当前行的列之外的变量。

REFERENCES reftable [ ( refcolumn ) ] [ MATCH matchtype ] [ ON DELETE action ] [ ON UPDATE action ] (column constraint)
FOREIGN KEY ( column [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] [ MATCH matchtype ] [ ON DELETE action ] [ ON UPDATE action ] (table constraint)

这些子句指定外键约束,要求新表的一个或多个列组成的列组只能包含与被引用表 reftable 中被引用列 refcolumn 的值相匹配的值。如果省略refcolumn列表,则使用reftable的主键。被引用列必须是被引用表中某个唯一约束或主键约束的列。

插入到引用列中的值会按照给定的匹配类型,与被引用表及其被引用列中的值进行匹配。共有三种匹配类型:MATCH FULL、MATCH PARTIAL 和 MATCH SIMPLE(默认值)。MATCH FULL 不允许多列外键中的某一列为空,除非所有外键列都为空。MATCH SIMPLE 允许某些外键列为空而外键的其他部分不为空。MATCH PARTIAL 目前尚未实现。

此外,当被引用列中的数据发生变化时,会对本表列中的数据执行某些操作。ON DELETE子句指定删除被引用表中的被引用行时要执行的操作。同样,ON UPDATE子句指定将被引用表中的被引用列更新为新值时要执行的操作。如果行被更新,但被引用列实际上没有变化,则不执行任何操作。每个子句可以指定以下操作:

NO ACTION

产生错误,指出删除或更新会违反外键约束。这是默认操作。

RESTRICT

与 NO ACTION 相同,但即使该约束的其余部分是可延迟的且已被延迟,此操作也不会被延迟。

CASCADE

分别删除任何引用已删除行的行,或将引用列的值更新为被引用列的新值。

SET NULL

将引用列设置为空值。

SET DEFAULT

将引用列设置为其默认值。

如果主键列经常更新,可以考虑在外键列上添加索引,使与该外键列关联的 NO ACTION 和 CASCADE 操作能够更高效地执行。

DEFERRABLE
NOT DEFERRABLE

这控制约束是否可以延迟。不可延迟的约束会在每条命令之后立即检查。可延迟约束的检查可以推迟到事务结束(使用 SET CONSTRAINTS 命令)。NOT DEFERRABLE 是默认值。目前只有外键约束接受此子句。所有其他类型的约束都不可延迟。

INITIALLY IMMEDIATE
INITIALLY DEFERRED

如果约束可延迟,则此子句指定检查约束的默认时间。如果约束为INITIALLY IMMEDIATE,则在每条语句之后检查。这是默认值。如果约束为INITIALLY DEFERRED,则仅在事务结束时检查。可以使用 SET CONSTRAINTS 命令更改约束检查时间。

ON COMMIT

可以使用 ON COMMIT 控制临时表在事务块结束时的行为。三种 选项如下:

PRESERVE ROWS

在事务结束时不执行任何特殊操作。这是默认行为。

DELETE ROWS

临时表中的所有行都会在每个事务块结束时删除。实际上,每次提交时都会自动执行一次TRUNCATE。

DROP

在当前事务块结束时删除临时表。

注解

  • 每当应用使用 OID 来标识表中的特定行时,建议在该表的 oid 列上创建唯一约束,以确保即使计数器回卷之后,表中的 OID 也确实能唯一标识行。不要假定 OID 在不同表之间是唯一的;如果需要数据库范围的唯一标识符,请组合使用 tableoid 和行 OID 来达到目的。(未来的 PostgreSQL 版本很可能会为每个表使用单独的 OID 计数器,因此把 tableoid 包含进来以获得数据库范围的唯一标识符,将成为必要而非可选。)

    提示

    对于没有主键的表,不建议使用 WITHOUT OIDS,因为既没有 OID 也没有唯一数据键时,很难标识特定行。

  • PostgreSQL 会为每一个唯一约束和主键约束自动创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建索引(更多信息见 CREATE INDEX)。

  • 在当前的实现中,唯一约束和主键不会被继承。这使得继承与唯一约束的组合相当不实用。

示例

创建表 films 和表 distributors:

CREATE TABLE films (
    code        char(5) CONSTRAINT firstkey PRIMARY KEY,
    title       varchar(40) NOT NULL,
    did         integer NOT NULL,
    date_prod   date,
    kind        varchar(10),
    len         interval hour to minute
);
CREATE TABLE distributors (
     did    integer PRIMARY KEY DEFAULT nextval('serial'),
     name   varchar(40) NOT NULL CHECK (name <> '')
);

创建一个带二维数组列的表:

CREATE TABLE array (
    vector  int[][]
);

为表films定义一个唯一表约束。唯一表约束可以定义在表的一列或多列上:

CREATE TABLE films (
    code        char(5),
    title       varchar(40),
    did         integer,
    date_prod   date,
    kind        varchar(10),
    len         interval hour to minute,
    CONSTRAINT production UNIQUE(date_prod)
);

定义一个列检查约束:

CREATE TABLE distributors (
    did     integer CHECK (did > 100),
    name    varchar(40)
);

定义一个表检查约束:

CREATE TABLE distributors (
    did     integer,
    name    varchar(40),
    CONSTRAINT con1 CHECK (did > 100 AND name <> '')
);

为表films定义一个主键表约束:

CREATE TABLE films (
    code        char(5),
    title       varchar(40),
    did         integer,
    date_prod   date,
    kind        varchar(10),
    len         interval hour to minute,
    CONSTRAINT code_title PRIMARY KEY(code,title)
);

为表distributors定义一个主键约束。下面两个示例是等价的,第一个使用表约束语法,第二个使用列约束语法:

CREATE TABLE distributors (
    did     integer,
    name    varchar(40),
    PRIMARY KEY(did)
);
CREATE TABLE distributors (
    did     integer PRIMARY KEY,
    name    varchar(40)
);

为列name指定一个字面常量默认值,将列did的默认值设为从某个序列对象中取下一个值,并让modtime的默认值为插入该行的时间:

CREATE TABLE distributors (
    name      varchar(40) DEFAULT 'Luso Films',
    did       integer DEFAULT nextval('distributors_serial'),
    modtime   timestamp DEFAULT current_timestamp
);

在表distributors上定义两个NOT NULL列约束,其中一个显式指定了名称:

CREATE TABLE distributors (
    did     integer CONSTRAINT no_null NOT NULL,
    name    varchar(40) NOT NULL
);

为name列定义一个唯一约束:

CREATE TABLE distributors (
    did     integer,
    name    varchar(40) UNIQUE
);

同样的唯一约束用表约束指定:

CREATE TABLE distributors (
    did     integer,
    name    varchar(40),
    UNIQUE(name)
);

兼容性

CREATE TABLE 命令符合 SQL92 以及 SQL99 的一个子集,但有以下例外。

临时表

尽管 CREATE TEMPORARY TABLE 的语法看起来类似于 SQL 标 准,但其效果并不相同。按标准,临时表只需定义一次,并会自动存在于每个需 要它的会话中(内容初始为空)。而 PostgreSQL 要求 每个会话都为每个要使用的临时表发出自己的 CREATE TEMPORARY TABLE 命令。这使不同会话可以出于不同目 的使用相同的临时表名;而标准做法则要求给定临时表名的所有实例都必须具有 相同的表结构。

标准对临时表行为的定义在实践中被广泛忽略。PostgreSQL 在这一点上的行为与多种其他 SQL 数据库相似。

标准中全局临时表和局部临时表的区分在 PostgreSQL 中并不存在,因为这一区分依赖于模块的概念,而 PostgreSQL 没有这一概念。出于兼容性考虑,PostgreSQL 会接受在临时表声明中使用 GLOBAL 和 LOCAL 关键字,但它们没有效果。

临时表的 ON COMMIT 子句也与 SQL 标准相似,但存在一些差 异。如果省略 ON COMMIT 子句,SQL 规定默认行为是 ON COMMIT DELETE ROWS。然而, PostgreSQL 中的默认行为是 ON COMMIT PRESERVE ROWS。SQL 中不存在 ON COMMIT DROP 选项。

列检查约束

SQL 标准规定,CHECK 列约束只能引用其所作用的列;只有 CHECK 表约束才能引用多列。 PostgreSQL 并不强制这一限制;它对列检查约束和表 检查约束一视同仁。

NULL “约束”

NULL “约束”(实际上并不是约束)是 PostgreSQL 对 SQL 标准的扩展;提供它是为了 与其他一些数据库系统兼容(以及与 NOT NULL 约束保持 对称)。由于它本来就是任意列的默认情况,所以它的存在只是噪声。

继承

通过 INHERITS 子句实现的多重继承是 PostgreSQL 的语言扩展。SQL99(但 SQL92 不)使用不同的语法和语义定义了单继承。PostgreSQL 尚不支持 SQL99 风格的继承。

对象 ID

PostgreSQL 的 OID 概念不是标准的一部分。

零列表

PostgreSQL 允许创建没有列的表(例如 CREATE TABLE foo();)。这是对 SQL 标准的扩展,标准不允许 零列的表。零列的表本身并不十分有用,但若禁止它们,就会让 ALTER TABLE DROP COLUMN 出现奇怪的特殊情况,因此忽略这 一规范限制看起来更整洁。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。