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

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

CREATE TABLE

CREATE TABLE — Creates a new table

大纲

CREATE TABLE table (
    column type
    [ DEFAULT value]
    [, NOT NULL ] [ ,UNIQUE ]
    [column_constraint_clause | PRIMARY KEY } [ ... ] ]
    [, ... ]
    [, PRIMARY KEY ( column [, ...] ) ]
    [, CHECK ( condition ) ]
    [, table_constraint_clause ]
    ) [ INHERITS ( inherited_table [, ...] ) ]
  

输入

table

要创建的新表的名称。

column

列的名称。

type

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

DEFAULT value

列的默认值。详见 DEFAULT 子句。

column_constraint_clause

可选的列约束子句指定一组完整性约束(测试),要使插入或更新操作 成功,新条目或更新后的条目必须满足这些约束。每个约束都必须能求值 为布尔表达式。尽管 SQL92 要求 column_constraint_clause 只引用该列,Postgres 却允许在单个列约束中 引用多个列。详见列约束子句。

table_constraint_clause

可选的表 CONSTRAINT 子句指定一组完整性约束,要使插入或更新操作 成功,新条目或更新后的条目必须满足这些约束。每个约束都必须能求值 为布尔表达式。单个约束中可以引用多个列。一个表只能指定一个 PRIMARY KEY 子句;PRIMARY KEY column (表约束)与 PRIMARY KEY(列约束)互斥。详见表约束子句。

INHERITS inherited_table

可选的 INHERITS 子句指定一组表名,该表自动从中继承所有字段。 如果某个被继承的字段名出现多于一次, Postgres 会报错。 Postgres 会自动让新表继承其在继承层次 中上方表上的函数。

题外话

函数的继承按照 Common Lisp Object System(CLOS)的惯例进行。

输出

→ CREATE

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

→ ERROR

表创建失败时返回的消息。通常还伴随一些描述性文字,例如:

amcreate: "table" relation already exists
           

,如果指定的表在数据库中已存在,就会在运行时出现该错误。

→ ERROR: DEFAULT: type mismatched

如果默认值的数据类型与列定义的数据类型不匹配。

描述

CREATE TABLE 将向当前数据库中输入一个新表。 该表将由发出命令的用户“拥有”。

新表作为堆创建,不含初始数据。一个表最多可以有 1600 列(现实中,由于元组大小必须小于 8192 字节,这个上限还会更低),某些站点还可能把该上限配置得更低。表不能与系统目录表同名。

DEFAULT 子句

DEFAULT value
    

输入

value

默认值表达式可能的取值有:

  • 字面值
  • 用户函数
  • niladic 函数(无参函数)

输出

描述

DEFAULT 子句为一个列指定默认数据值(通过 CREATE TABLE 语句中的列定义)。默认值的数据类型必须与列定义的数据类型匹配。

如果一个 INSERT 操作涉及的列没有指定默认值,且没有为它提供显式数据值,那么将把 NULL 值赋给该列。Default literal 表示默认值就是指定的常量值。Default niladic-function 或 user-function 表示默认值是 INSERT 时该指定函数的值。

niladic 函数有两种类型:

niladic USER
CURRENT_USER / USER
见 CURRENT_USER 函数
SESSION_USER
尚不支持
SYSTEM_USER
尚不支持
niladic datetime
CURRENT_DATE
见 CURRENT_DATE 函数
CURRENT_TIME
见 CURRENT_TIME 函数
CURRENT_TIMESTAMP
见 CURRENT_TIMESTAMP 函数

在当前版本(v6.4)中,Postgres 会在定义表的时候求值所有默认表达式。因此,诸如 CURRENT_TIMESTAMP 这类“不可缓存”的函数可能不会产生 预期的效果。对于日期/时间类型这一特殊情况,可以用 “DEFAULT TEXT 'now'” 代替 “DEFAULT 'now'” 或 “DEFAULT CURRENT_TIMESTAMP”。 这会迫使 Postgres 把该常量当作字符串类型, 然后在运行时再把该值转换为 timestamp。

用法

为列 did 和 number 指定常量作为默认值, 并为列 did 指定一个字符串字面值:

CREATE TABLE video_sales (
    did      VARCHAR(40) DEFAULT 'luso films',
    number   INTEGER DEFAULT 0,
    total    CASH DEFAULT '$0.0'
);
  

为列 did 指定一个已存在的序列作为默认值, 并为列 name 指定一个字面值:

CREATE TABLE distributors (
    did      DECIMAL(3)  DEFAULT NEXTVAL('serial'),
    name     VARCHAR(40) DEFAULT 'luso films'
);
  

列 CONSTRAINT 子句

[ CONSTRAINT name ] { NOT NULL | UNIQUE | PRIMARY KEY | CHECK constraint } [, ...]
   

输入

name

赋予完整性约束的一个任意名称。如果未指定 name,它将由表名和列名 生成,这应当能保证 name 的唯一性。

NOT NULL

该列不允许包含 NULL 值。这等价于列约束 CHECK (column NOT NULL)。

UNIQUE

该列必须具有唯一值。在 Postgres 中,这是通过在表上隐式创建一个唯一索引来强制实现的。

PRIMARY KEY

该列是一个主键,这蕴含着唯一性由系统强制,并且其他表可以把该列 当作行的唯一标识符来依赖。详见 PRIMARY KEY。

constraint

约束的定义。

描述

约束是一条命名的规则:一个通过对在基表上执行的 INSERT、UPDATE 或 DELETE 操作的结果加以限制,来帮助定义有效值集合的 SQL 对象。

定义完整性约束有两种方式:稍后讲述的表约束,以及这里讲述的列约束。

列约束是作为列定义的一部分定义的完整性约束,一旦创建,在逻辑上就成为表约束。可用的列约束有:

PRIMARY KEY
REFERENCES
UNIQUE
CHECK
NOT NULL

注意

Postgres 在 6.4 版中尚不支持 REFERENCES 完整性约束。解析器接受 REFERENCES 语法,但忽略该子句。

NOT NULL 约束

[ CONSTRAINT name ] NOT NULL 
   

NOT NULL 约束指定一条规则:一列只能包含非空值。

NOT NULL 约束只是列约束,不允许作为表约束。

输出

status
→ ERROR: ExecAppend: Fail to add null value in not null attribute "column".

如果试图向一个带 NOT NULL 约束的列插入空值,就会在运行时 出现该错误。

描述

用法

在表 distributors 上定义两个 NOT NULL 列约束,其中一个是命名约束:

CREATE TABLE distributors (
    did      DECIMAL(3) CONSTRAINT no_null NOT NULL,
    name     VARCHAR(40) NOT NULL
);
  

UNIQUE 约束

[ CONSTRAINT name ] UNIQUE
   

输入

CONSTRAINT name

赋予约束的一个任意标签。

输出

status
→ ERROR: Cannot insert a duplicate key into a unique index.

如果试图向一个列插入重复值,就会在运行时出现该错误。

描述

UNIQUE 约束指定一条规则:表中一个或多个不同列组成的一组只能包含唯一值。

被指定列的列定义不必包含 NOT NULL 约束就可以纳入 UNIQUE 约束。一个不带 NOT NULL 约束的列中有多个空值并不违反 UNIQUE 约束。(这偏离了 SQL92 的定义,但是一个更合乎常理的约定。详见兼容性一节。)

每个 UNIQUE 列约束所命名的列,必须与为该表定义的任何其他 UNIQUE 或 PRIMARY KEY 约束所命名的列集合不同。

注意

Postgres 会自动为每个 UNIQUE 约束创建一个唯一索引,以确保数据完整性。详见 CREATE INDEX。

用法

为表 distributors 定义一个 UNIQUE 列约束。UNIQUE 列约束只能定义在表的一列上:

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

它等价于把以下内容指定为表约束:

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

CHECK 约束

[ CONSTRAINT name ] CHECK ( condition [, ...] ) 
  

输入

→ name

赋予约束的一个任意名称。

condition

任何产生布尔结果的合法条件表达式。

输出

status
→ ERROR: ExecAppend: rejected due to CHECK constraint "table_column".

如果试图向一个受 CHECK 约束约束的列插入非法值,就会在运行时 出现该错误。

描述

CHECK 约束对列中允许的值指定一个限制。CHECK 约束也允许作为表约束。

SQL92 的 CHECK 列约束只能定义在表的一列上并只引用该列。Postgres 没有这一限制。

PRIMARY KEY 约束

[ CONSTRAINT name ] PRIMARY KEY 
   

输入

CONSTRAINT → name

约束的一个任意名称。

输出

→ ERROR: Cannot insert a duplicate key into a unique index.

如果试图向一个受 PRIMARY KEY 约束约束的列插入重复值,就会在 运行时出现该错误。

描述

PRIMARY KEY 列约束指定一个表的某一列只能包含唯一(非重复)的非 NULL 值。被指定列的定义不必包含显式的 NOT NULL 约束就可以纳入 PRIMARY KEY 约束。

一个表只能指定一个 PRIMARY KEY。

注解

Postgres 会自动创建一个唯一索引来确保数据完整性。(见 CREATE INDEX 语句)

PRIMARY KEY 约束所命名的列集合应当与为同一表定义的任何 UNIQUE 约束所命名的列集合不同,否则会导致等价索引的重复和不必要的额外运行时开销。不过,Postgres 并不特别禁止这样做。

表 CONSTRAINT 子句

[ CONSTRAINT name ] { PRIMARY KEY |  UNIQUE } ( column [, ...] )
[ CONSTRAINT name ] CHECK ( constraint )
   

输入

CONSTRAINT name

赋予完整性约束的一个任意名称。

column [, ...]

要为其定义唯一索引的列名,对于 PRIMARY KEY 还要加 NOT NULL 约束。

CHECK ( constraint )

一个将被作为约束求值的布尔表达式。

输出

表约束子句可能的输出与列约束子句相应部分的输出相同。

描述

表约束是定义在一个基表的一列或多列上的完整性约束。“表约束”的四种变体是:

UNIQUE
CHECK
PRIMARY KEY
FOREIGN KEY

注意

Postgres 在 6.4 版中尚不支持 FOREIGN KEY 完整性约束。解析器理解 FOREIGN KEY 语法,但只打印一条提示,此外便忽略该子句。外键可以用触发器部分模拟(见 CREATE TRIGGER 语句)。

UNIQUE 约束

[ CONSTRAINT name ] UNIQUE ( column [, ...] )
   

输入

CONSTRAINT name

赋予完整性约束的一个任意名称。

column

表中某一列的名称。

输出

status
ERROR: Cannot insert a duplicate key into a unique index.

如果试图向一个受 PRIMARY KEY 约束约束的列插入重复值,就会在 运行时出现该错误。

描述

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

更多细节见 UNIQUE 列约束一节。

用法

为表 distributors 定义一个 UNIQUE 表约束:

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

PRIMARY KEY 约束

    [ CONSTRAINT name ] PRIMARY KEY ( column [, ...] ) 
   

输入

CONSTRAINT name

约束的一个任意名称。

column [, ...]

要为其定义唯一索引的列名,对于 PRIMARY KEY 还要加 NOT NULL 约束。

输出

status
ERROR: Cannot insert a duplicate key into a unique index.

如果试图向一个受 PRIMARY KEY 约束约束的列插入重复值,就会在运行时出现该错误。

描述

PRIMARY KEY 约束指定一条规则:表中一个或多个不同列组成的一组只能包含唯一(非重复)的非空值。被指定列的列定义不必包含 NOT NULL 约束就可以纳入 PRIMARY KEY 约束。 PRIMARY KEY 表约束与相应的列约束类似,只是它还能涵盖多列。

更多信息见 PRIMARY KEY 列约束一节。

用法

创建表 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(03) PRIMARY KEY DEFAULT NEXTVAL('serial'),
          name     VARCHAR(40) NOT NULL CHECK (name <> '')
          );
  

创建一个带二维数组的表

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

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

   CREATE TABLE films (
       code      CHAR(5),
       title     VARCHAR(40),
       did       DECIMAL(03),
       date_prod DATE,
       kind      CHAR(10),
       len       INTERVAL HOUR TO MINUTE,
       CONSTRAINT production UNIQUE(date_prod)
       );
  

定义一个 CHECK 列约束。

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

定义一个 CHECK 表约束:

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

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

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

为表 distributors 定义一个 PRIMARY KEY 列约束。PRIMARY KEY 列约束只能定义在表的一列上(下面两个示例是等价的)

   CREATE TABLE distributors (
        did      DECIMAL(03),
        name     CHAR VARYING(40),
        PRIMARY KEY(did)
        ); 

   CREATE TABLE distributors (
        did      DECIMAL(03) PRIMARY KEY,
        name     VARCHAR(40)
        );
  

注解

CREATE TABLE/INHERITS 是 Postgres 的语言扩展。

兼容性

SQL92

除普通的 CREATE TABLE 外,SQL92 还定义了 CREATE TEMPORARY TABLE 语句:

   CREATE [ {GLOBAL | LOCAL} ] TEMPORARY TABLE table (
        column type [DEFAULT value] [CONSTRAINT column_constraint] [, ...] )
        [CONSTRAINT table_constraint ]
        [ ON COMMIT {DELETE | PRESERVE} ROWS ] 
   

对于临时表,CREATE TEMPORARY TABLE 语句命名一个新表,并定义该表的列和约束。

CREATE TEMPORARY TABLE 的可选 ON COMMIT 子句指定每当执行 COMMIT 时是否清空临时表中的行。如果省略 ON COMMIT 子句,则假定使用默认 选项 ON COMMIT DELETE ROWS。

创建一个临时表:

      CREATE TEMPORARY TABLE actors (
             id      DECIMAL(03),
             name    VARCHAR(40),
             CONSTRAINT actor_id CHECK (id < 150)
             ) ON COMMIT DELETE ROWS
   

临时表目前在 Postgres 中尚不可用。

提示

在 Postgres 的当前版本(v6.4)中,要使用临时表,必须用显式命令创建和删除表。

UNIQUE 子句

SQL92 为 UNIQUE 指定了一些额外的能力:

表约束定义

      [ CONSTRAINT name ]
      UNIQUE ( column [, ...] )
      [ {INITIALLY DEFERRED | INITIALLY IMMEDIATE} ]
      [ [ NOT ] DEFERRABLE ]
    

列约束定义

      [ CONSTRAINT name ]
      UNIQUE
      [ {INITIALLY DEFERRED | INITIALLY IMMEDIATE} ]
      [ [ NOT ] DEFERRABLE ]
    

NOT NULL 子句

SQL92 为 NOT NULL 指定了一些额外的能力:

      [ CONSTRAINT name ] NOT NULL 
      [ {INITIALLY DEFERRED | INITIALLY IMMEDIATE} ]
      [ [ NOT ] DEFERRABLE ]
    

CONSTRAINT 子句

SQL92 为约束指定了一些额外的能力,并且还定义了断言和域约束。

注意

Postgres 尚不支持域和断言。

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

     CREATE ASSERTION name CHECK ( condition )
    

域约束由 CREATE DOMAIN 或 ALTER DOMAIN 语句定义:

域约束:

      [ CONSTRAINT name ] 
          CHECK constraint 
          [ {INITIALLY DEFERRED | INITIALLY IMMEDIATE} ]
          [ [ NOT ] DEFERRABLE ]
    

表约束定义:

      [ CONSTRAINT name ] 
        { PRIMARY KEY constraint | 
          FOREIGN KEY constraint | 
          UNIQUE constraint | 
          CHECK constraint }
          [ {INITIALLY DEFERRED | INITIALLY IMMEDIATE} ]
          [ [ NOT ] DEFERRABLE ]

列约束定义:

     [ CONSTRAINT name ] 
        { NOT NULL constraint |
          PRIMARY KEY constraint | 
          FOREIGN KEY constraint | 
          UNIQUE constraint | 
          CHECK constraint }  
          [ {INITIALLY DEFERRED | INITIALLY IMMEDIATE} ]
          [ [ NOT ] DEFERRABLE ]
    

一个 CONSTRAINT 定义可以按任意顺序包含一个可推迟性属性子句和/或一个初始约束模式子句。

NOT DEFERRABLE

表示该约束必须在每条 SQL 语句执行之后就检查是否违反其规则。

DEFERRABLE

这控制约束是否可以推迟到事务结束检查。如果使用了 SET CONSTRAINTS ALL DEFERRED,或者约束被设置为 INITIALLY DEFERRED,这将使外键 只在事务结束时才被检查。

每个约束的约束模式总是有一个初始默认值,它在事务开始时为该约束设置。

INITIALLY IMMEDIATE

表示从事务开始起,该约束必须在每条 SQL 语句执行之后就检查 是否违反其规则。

INITIALLY DEFERRED

每条语句之后检查约束。

CHECK 子句

SQL92 为表约束或列约束中的 CHECK 指定了一些额外的能力。

表约束定义:

     [ CONSTRAINT name ] 
      CHECK ( VALUE condition ) 
      [ {INITIALLY DEFERRED | INITIALLY IMMEDIATE} ]
      [ [ NOT ] DEFERRABLE ]
    

列约束定义:

      [ CONSTRAINT name ] 
      CHECK ( VALUE condition ) 
      [ {INITIALLY DEFERRED | INITIALLY IMMEDIATE} ]
      [ [ NOT ] DEFERRABLE ]
    

PRIMARY KEY 子句

SQL92 为 PRIMARY KEY 指定了一些额外的能力:

表约束定义:

      [ CONSTRAINT name ] 
      PRIMARY KEY ( column [, ...] ) 
      [ {INITIALLY DEFERRED | INITIALLY IMMEDIATE} ]
      [ [ NOT ] DEFERRABLE ]
    

列约束定义:

      [ CONSTRAINT name ] 
      PRIMARY KEY 
      [ {INITIALLY DEFERRED | INITIALLY IMMEDIATE} ]
      [ [ NOT ] DEFERRABLE ]
    

提交更正

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