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

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.3 已于 2007 年 11 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

CREATE TABLE

CREATE TABLE — 定义一个新表

大纲

CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name (
    { column_name data_type [ DEFAULT default_expr ] [ column_constraint [, ... ] ]
    | table_constraint }  [, ... ]
)
[ INHERITS ( parent_table [, ... ] ) ]
[ WITH OIDS | WITHOUT OIDS ]

where column_constraint is:

[ CONSTRAINT constraint_name ]
{ NOT NULL | NULL | UNIQUE | PRIMARY KEY |
  CHECK (expression) |
  REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL ]
    [ 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 ] [ ON DELETE action ] [ ON UPDATE action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]

描述

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

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

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

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

可选的约束子句指定插入或更新要成功时,新行或更新后的行必须满足的约束(测试)。约束是一条命名的规则:一个通过对在表上执行的插入、更新或删除操作的结果加以限制,来帮助定义有效值集合的 SQL 对象。

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

参数

[LOCAL] TEMPORARY or [LOCAL] TEMP

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

LOCAL 一词是可选的。但参见 兼容性。

table_name

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

column_name

要在新表中创建的列名。

data_type

列的数据类型。这可以包括数组说明符。有关数据类型和数组的更多信息,请参阅用户指南。

DEFAULT default_expr

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

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

INHERITS ( parent_table [, ... ] )

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

WITH OIDS or WITHOUT OIDS

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

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

CONSTRAINT constraint_name

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

NOT NULL

该列不允许包含 NULL 值。

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)

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

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

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

NO ACTION

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

RESTRICT

与 NO ACTION 相同。

CASCADE

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

SET NULL

将引用列设置为空值。

SET DEFAULT

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

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

DEFERRABLE or NOT DEFERRABLE

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

INITIALLY IMMEDIATE or INITIALLY DEFERRED

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

诊断

CREATE TABLE

表创建成功时返回的消息。

ERROR

表创建失败时返回的消息。通常还伴随一些描述性文字,例如: ERROR: Relation 'table' already exists,如果指定的表在数据库中已存在,就会在运行时出现该错误。

注解

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

    提示

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

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

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

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

示例

创建表 films 和表 distributors:

CREATE TABLE films (
    code        CHARACTER(5) CONSTRAINT firstkey PRIMARY KEY,
    title       CHARACTER VARYING(40) NOT NULL,
    did         DECIMAL(3) NOT NULL,
    date_prod   DATE,
    kind        CHAR(10),
    len         INTERVAL HOUR TO MINUTE
);
CREATE TABLE distributors (
     did    DECIMAL(3) 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         DECIMAL(3),
    date_prod   DATE,
    kind        VARCHAR(10),
    len         INTERVAL HOUR TO MINUTE,
    CONSTRAINT production UNIQUE(date_prod)
);

定义一个列检查约束:

CREATE TABLE distributors (
    did     DECIMAL(3) CHECK (did > 100),
    name    VARCHAR(40)
);

定义一个表检查约束:

CREATE TABLE distributors (
    did     DECIMAL(3),
    name    VARCHAR(40),
    CONSTRAINT con1 CHECK (did > 100 AND name <> '')
);

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

CREATE TABLE films (
    code        CHAR(5),
    title       VARCHAR(40),
    did         DECIMAL(3),
    date_prod   DATE,
    kind        VARCHAR(10),
    len         INTERVAL HOUR TO MINUTE,
    CONSTRAINT code_title PRIMARY KEY(code,title)
);

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

CREATE TABLE distributors (
    did     DECIMAL(3),
    name    VARCHAR(40),
    PRIMARY KEY(did)
);
CREATE TABLE distributors (
    did     DECIMAL(3) 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     DECIMAL(3) CONSTRAINT no_null NOT NULL,
    name    VARCHAR(40) NOT NULL
);

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

CREATE TABLE distributors (
    did     DECIMAL(3),
    name    VARCHAR(40) UNIQUE
);

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

CREATE TABLE distributors (
    did     DECIMAL(3),
    name    VARCHAR(40),
    UNIQUE(name)
);

兼容性

CREATE TABLE 遵循 SQL92 Intermediate 以及 SQL99 的一个 子集,例外情况见下文以及上文的描述。

临时表

除本地临时表外,SQL92 还定义了 CREATE GLOBAL TEMPORARY TABLE 语句。全局临时表对其他会话也是可见的。

对于临时表,有一个可选的 ON COMMIT 子句:

CREATE { GLOBAL | LOCAL } TEMPORARY TABLE table ( ... ) [ ON COMMIT { DELETE | PRESERVE } ROWS ]

ON COMMIT 子句指定每当执行 COMMIT 时是否清空临时表中的行。如果省略 ON COMMIT 子句,SQL92 规定 默认为 ON COMMIT DELETE ROWS。但 PostgreSQL 的行为总是类似于 ON COMMIT PRESERVE ROWS。

NULL “约束”

NULL “约束”(实际上是一个非约束)是 PostgreSQL 对 SQL92 的扩展,加入它是为了 与某些其他 RDBMS 兼容(并与 NOT NULL 约束对称)。 由于它是任何列的默认情况,它的出现只是噪音。

断言

断言是一种特殊类型的完整性约束,与其他约束共享同一名字空间。不过,断言 不一定像约束那样依赖于某个特定的表,因此 SQL92 提供了 CREATE ASSERTION 语句作为定义约束的另一种方法:

CREATE ASSERTION name CHECK ( condition )

PostgreSQL 目前没有实现断言。

继承

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

对象 ID

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

提交更正

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