2025年9月25日: PostgreSQL 18 发布!
支持版本:当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本:devel
不支持版本: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

CREATE TABLE

CREATE TABLE — 定义新表

概要

CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name ( [
  { column_name data_type [ STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } ] [ COMPRESSION compression_method ] [ COLLATE collation ] [ column_constraint [ ... ] ]
    | table_constraint
    | LIKE source_table [ like_option ... ] }
    [, ... ]
] )
[ INHERITS ( parent_table [, ... ] ) ]
[ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ]
[ USING method ]
[ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace_name ]

CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name
    OF type_name [ (
  { column_name [ WITH OPTIONS ] [ column_constraint [ ... ] ]
    | table_constraint }
    [, ... ]
) ]
[ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ]
[ USING method ]
[ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace_name ]

CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name
    PARTITION OF parent_table [ (
  { column_name [ WITH OPTIONS ] [ column_constraint [ ... ] ]
    | table_constraint }
    [, ... ]
) ] { FOR VALUES partition_bound_spec | DEFAULT }
[ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ]
[ USING method ]
[ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace_name ]

where column_constraint is:

[ CONSTRAINT constraint_name ]
{ NOT NULL [ NO INHERIT ]  |
  NULL |
  CHECK ( expression ) [ NO INHERIT ] |
  DEFAULT default_expr |
  GENERATED ALWAYS AS ( generation_expr ) [ STORED | VIRTUAL ] |
  GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] |
  UNIQUE [ NULLS [ NOT ] DISTINCT ] index_parameters |
  PRIMARY KEY index_parameters |
  REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
    [ ON DELETE referential_action ] [ ON UPDATE referential_action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ]

and table_constraint is:

[ CONSTRAINT constraint_name ]
{ CHECK ( expression ) [ NO INHERIT ] |
  NOT NULL column_name [ NO INHERIT ] |
  UNIQUE [ NULLS [ NOT ] DISTINCT ] ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters |
  PRIMARY KEY ( column_name [, ... ] [, column_name WITHOUT OVERLAPS ] ) index_parameters |
  EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] |
  FOREIGN KEY ( column_name [, ... ] [, PERIOD column_name ] ) REFERENCES reftable [ ( refcolumn [, ... ] [, PERIOD refcolumn ] ) ]
    [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ]

and like_option is:

{ INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL }

and partition_bound_spec is:

IN ( partition_bound_expr [, ...] ) |
FROM ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] )
  TO ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) |
WITH ( MODULUS numeric_literal, REMAINDER numeric_literal )

index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:

[ INCLUDE ( column_name [, ... ] ) ]
[ WITH ( storage_parameter [= value] [, ... ] ) ]
[ USING INDEX TABLESPACE tablespace_name ]

exclude_element in an EXCLUDE constraint is:

{ column_name | ( expression ) } [ COLLATE collation ] [ opclass [ ( opclass_parameter = value [, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ]

referential_action in a FOREIGN KEY/REFERENCES constraint is:

{ NO ACTION | RESTRICT | CASCADE | SET NULL [ ( column_name [, ... ] ) ] | SET DEFAULT [ ( column_name [, ... ] ) ] }

描述

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

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

CREATE TABLE 还会自动创建一个表示表一行对应的复合类型的类型。因此,表不能与同一模式中的任何现有数据类型具有相同的名称。

可选的约束子句指定了约束(测试),新行或更新后的行必须满足这些约束,才能使插入或更新操作成功。约束是 SQL 对象,它以各种方式帮助定义表中有效值的集合。

定义约束有两种方式:表约束和列约束。列约束是作为列定义的一部分定义的。表约束定义不与特定列绑定,它可以包含多列。每个列约束也可以写成表约束;列约束只是一个用于当约束仅影响一列时的符号方便。

要能够创建表,您必须对所有列类型或 OF 子句中的类型分别具有 USAGE 权限。

参数

TEMPORARYTEMP #

如果指定,表将作为临时表创建。临时表将在会话结束时自动删除,或者根据选择在当前事务结束时删除(参见下面的 ON COMMIT)。默认的 search_path 首先包含临时模式,因此当临时表存在时,除非使用带模式限定的名称引用,否则新计划不会选择同名现有永久表。在临时表上创建的任何索引也会自动是临时的。

自动清理守护进程无法访问临时表,因此也无法清理或分析临时表。因此,应通过会话 SQL 命令执行适当的清理和分析操作。例如,如果一个临时表将用于复杂查询,那么在填充临时表之后运行 ANALYZE 是明智的。

可选地,可以在 TEMPORARYTEMP 之前写入 GLOBALLOCAL。这在 PostgreSQL 中目前没有区别,并且已弃用;请参阅下面的 兼容性

UNLOGGED #

如果指定,表将作为未记录表创建。写入未记录表的数据不会写入预写日志(请参阅 第 28 章),这使得它们比普通表快得多。但是,它们不是崩溃安全的:在崩溃或非正常关机后,未记录表会自动截断。未记录表的内容也不会复制到备用服务器。在未记录表上创建的任何索引也会自动是未记录的。

如果指定了此项,与未记录表一起创建的任何序列(用于标识或串行列)也将创建为未记录。

此形式不支持分区表。

IF NOT EXISTS #

如果具有相同名称的关系已存在,则不抛出错误。在这种情况下会发出通知。请注意,不能保证现有关系与将要创建的关系有任何相似之处。

table_name #

要创建的表的名称(可以选择性地指定模式)。

OF type_name #

创建一个类型化表,它从指定的独立复合类型(即使用 CREATE TYPE 创建的类型)继承结构,尽管它仍然会生成一个新的复合类型。该表将对引用的类型具有依赖性,这意味着该类型的级联的 alter 和 drop 操作将传播到该表。

类型化表始终具有与它派生的类型相同的列名和数据类型,因此您不能指定其他列。但是 CREATE TABLE 命令可以为表添加默认值和约束,以及指定存储参数。

column_name #

新表中要创建的列名。

data_type #

列的数据类型。这可以包括数组说明符。有关 PostgreSQL 支持的数据类型的更多信息,请参阅 第 8 章

COLLATE collation #

COLLATE 子句为列分配排序规则(该列必须是可排序的数据类型)。如果未指定,则使用列数据类型的默认排序规则。

STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } #

此形式设置列的存储模式。这控制该列是存储在行内还是在辅助TOAST表中,以及数据是否应被压缩。 PLAIN 必须用于固定长度的值,例如 integer,它是行内、未压缩的。 MAIN 用于行内、可压缩的数据。 EXTERNAL 用于外部、未压缩的数据,而 EXTENDED 用于外部、压缩的数据。写入 DEFAULT 将存储模式设置为列数据类型的默认模式。 EXTENDED 是大多数支持非 PLAIN 存储的数据类型的默认值。使用 EXTERNAL 可以更快地处理非常大的 textbytea 值的子字符串操作,但会增加存储空间。有关更多信息,请参阅 第 66.2 节

COMPRESSION compression_method #

COMPRESSION 子句设置列的压缩方法。压缩仅支持可变宽度数据类型,并且仅在列的存储模式为 mainextended 时使用。(有关列存储模式的信息,请参阅 ALTER TABLE。)对分区表设置此属性没有直接影响,因为这样的表没有自己的存储,但配置的值将由新创建的分区继承。支持的压缩方法是 pglzlz4。(只有在构建 PostgreSQL 时使用了 --with-lz4 选项时,lz4 才可用。)此外,compression_method 可以是 default 来明确指定默认行为,即在插入数据时查阅 default_toast_compression 设置来确定要使用的方法。

INHERITS ( parent_table [, ...] ) #

可选的 INHERITS 子句指定了一个或多个表的列表,新表将自动从这些表中继承所有列。父表可以是普通表或外部表。

使用 INHERITS 会在新的子表与其父表之间创建持久关系。父表的模式修改通常也会传播到子表,并且默认情况下,子表的数据包含在父表的扫描中。

如果同一列名在多个父表中存在,除非各父表中的列数据类型匹配,否则会报告错误。如果没有冲突,则重复的列将被合并成新表中的一个列。如果新表的列名列表包含一个与继承的列同名的列,则数据类型也必须与继承的列匹配,并且列定义将被合并成一个。如果新表显式为该列指定了默认值,则此默认值将覆盖继承声明中该列的任何默认值。否则,指定了该列默认值的任何父表都必须指定相同的默认值,否则将报告错误。

CHECK 约束的合并方式与列基本相同:如果多个父表和/或新表定义包含同名的 CHECK 约束,则所有这些约束必须具有相同的检查表达式,否则将报告错误。具有相同名称和表达式的约束将被合并成一个副本。在父表中标记为 NO INHERIT 的约束将不被考虑。请注意,新表中的无名 CHECK 约束永远不会合并,因为总是会为其选择一个唯一的名称。

STORAGE 设置也从父表复制。

如果父表中的列是标识列,则该属性不会被继承。如果需要,子表中的列可以声明为标识列。

PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ opclass ] [, ...] ) #

可选的 PARTITION BY 子句指定了表分区策略。因此创建的表称为分区表。括号中的列或表达式列表构成了表分区键。在使用范围或哈希分区时,分区键可以包含多个列或表达式(最多 32 个,但此限制在构建 PostgreSQL 时可以更改),但对于列表分区,分区键必须由单个列或表达式组成。

范围和列表分区需要 btree 操作符类,而哈希分区需要哈希操作符类。如果未显式指定操作符类,将使用相应类型的默认操作符类;如果不存在默认操作符类,将引发错误。在使用哈希分区时,使用的操作符类必须实现支持函数 2(有关详细信息,请参阅 第 36.16.3 节)。

分区表被划分为子表(称为分区),这些子表使用单独的 CREATE TABLE 命令创建。分区表本身是空的。插入表中的数据行将根据分区键中的列或表达式的值路由到某个分区。如果没有现有分区匹配新行中的值,将报告错误。

有关表分区的更多讨论,请参阅 第 5.12 节

PARTITION OF parent_table { FOR VALUES partition_bound_spec | DEFAULT } #

将表创建为指定父表的分区。可以使用 FOR VALUES 为特定值创建表作为分区,或使用 DEFAULT 创建为默认分区。父表中存在的任何索引、约束和用户定义的行级触发器都会克隆到新分区。

partition_bound_spec 必须对应于父表的分区方法和分区键,并且不得与该父表的任何现有分区重叠。带 IN 的形式用于列表分区,带 FROMTO 的形式用于范围分区,带 WITH 的形式用于哈希分区。

partition_bound_expr 是任何无变量的表达式(不允许子查询、窗口函数、聚合函数和集合返回函数)。其数据类型必须与相应分区键列的数据类型匹配。该表达式在表创建时求值一次,因此它甚至可以包含 CURRENT_TIMESTAMP 等易失性表达式。

创建列表分区时,可以指定 NULL 来表示该分区允许分区键列为 null。但是,对于给定的父表,最多只能有一个这样的列表分区。不能为范围分区指定 NULL

创建范围分区时,FROM 指定的下界是包含边界,而 TO 指定的上界是排除边界。也就是说,FROM 列表中指定的值是该分区中相应分区键列的有效值,而 TO 列表中的值则不是。请注意,此语句必须根据行式比较的规则来理解(第 9.25.5 节)。例如,给定 PARTITION BY RANGE (x,y),分区边界 FROM (1, 2) TO (3, 4) 允许 x=1 且任何 y>=2x=2 且任何非空 y,以及 x=3 且任何 y<4

特殊值 MINVALUEMAXVALUE 可以在创建范围分区时使用,以表示列的值没有下界或上界。例如,使用 FROM (MINVALUE) TO (10) 定义的分区允许任何小于 10 的值,而使用 FROM (10) TO (MAXVALUE) 定义的分区允许任何大于或等于 10 的值。

当创建涉及多个列的范围分区时,使用 MAXVALUE 作为下界的一部分,使用 MINVALUE 作为上界的一部分也可能是有意义的。例如,使用 FROM (0, MAXVALUE) TO (10, MAXVALUE) 定义的分区允许第一个分区键列大于 0 且小于或等于 10 的任何行。类似地,使用 FROM ('a', MINVALUE) TO ('b', MINVALUE) 定义的分区允许第一个分区键列以 "a" 开头的任何行。

请注意,如果在一个分区的边界中使用了一个列的 MINVALUEMAXVALUE,则所有后续列必须使用相同的值。例如,(10, MINVALUE, 0) 不是有效边界;您应该写成 (10, MINVALUE, MINVALUE)

另请注意,某些元素类型(例如 timestamp)具有“无穷大”的概念,这只是另一个可以存储的值。这与 MINVALUEMAXVALUE 不同,它们不是可以存储的实际值,而是表示值无界的说法。MAXVALUE 可以被认为是大于任何其他值(包括“无穷大”),而 MINVALUE 可以被认为是小于任何其他值(包括“负无穷大”)。因此,范围 FROM ('infinity') TO (MAXVALUE) 不是空范围;它允许精确存储一个值——“无穷大”。

如果指定了 DEFAULT,则表将作为父表的默认分区创建。此选项不适用于哈希分区表。不适合任何其他分区的分区键值将被路由到默认分区。

当表具有现有的 DEFAULT 分区且向其添加新分区时,必须扫描默认分区以验证它不包含任何应属于新分区的行。如果默认分区包含大量行,这可能会很慢。如果默认分区是外部表,或者它有一个约束证明它不可能包含应放置在新分区中的行,则将跳过扫描。

创建哈希分区时,必须指定模数和余数。模数必须是正整数,余数必须是小于模数的非负整数。通常,在最初设置哈希分区表时,应选择一个等于分区数的模数,并为每个表分配相同的模数和不同的余数(参见下面的示例)。但是,并非要求每个分区都有相同的模数,只要求哈希分区表中出现的每个模数都是下一个较大模数的因子。这使得分区数可以逐步增加,而无需一次性移动所有数据。例如,假设您有一个具有 8 个分区的哈希分区表,每个分区都具有模数 8,但发现有必要将分区数增加到 16。您可以分离一个模数 8 的分区,创建两个新的模数 16 的分区,它们覆盖相同的键空间部分(一个余数等于分离分区的余数,另一个余数等于该值加上 8),然后用数据重新填充它们。之后,您可以对每个模数 8 的分区重复此操作——也许稍后——直到它们全部消失。虽然这可能仍然涉及每个步骤的大量数据移动,但这仍然比需要创建一个全新的表并移动所有数据要好。

分区必须具有与它所属的分区表相同的列名和类型。对分区表的列名或类型的修改将自动传播到所有分区。CHECK 约束将由每个分区自动继承,但单个分区可以指定额外的 CHECK 约束;具有与父项相同名称和条件的附加约束将与父约束合并。默认值可以为每个分区单独指定。但请注意,当通过分区表插入元组时,分区的默认值不会被应用。

插入到分区表的行将自动路由到正确的分区。如果不存在合适的分区,将发生错误。

通常影响表及其所有继承子项的操作(如 TRUNCATE)将级联到所有分区,但也可以对单个分区执行。

请注意,使用 PARTITION OF 创建分区需要对父分区表获取 ACCESS EXCLUSIVE 锁。同样,使用 DROP TABLE 删除分区也需要对父表获取 ACCESS EXCLUSIVE 锁。可以使用 ALTER TABLE ATTACH/DETACH PARTITION 以更弱的锁执行这些操作,从而减少与分区表上的并发操作的干扰。

LIKE source_table [ like_option ... ] #

LIKE 子句指定一个表,新表将自动从该表中复制所有列名、数据类型和非空约束。

INHERITS 不同,新表和原始表在创建完成后是完全解耦的。对原始表的更改不会应用于新表,并且不可能在原始表的扫描中包含新表的数据。

INHERITS 不同,通过 LIKE 复制的列和约束不会与同名的列和约束合并。如果显式指定了相同的名称或在另一个 LIKE 子句中指定,将发出错误。

可选的 like_option 子句指定要从原始表中复制哪些附加属性。指定 INCLUDING 会复制属性,指定 EXCLUDING 会忽略属性。EXCLUDING 是默认的。如果对同一种对象进行了多个指定,则使用最后一个指定。可用的选项是

INCLUDING COMMENTS #

复制的列、约束和索引的注释将被复制。默认行为是排除注释,导致新表中复制的列和约束没有注释。

INCLUDING COMPRESSION #

列的压缩方法将被复制。默认行为是排除压缩方法,导致列具有默认的压缩方法。

INCLUDING CONSTRAINTS #

CHECK 约束将被复制。列约束和表约束之间不做区分。非空约束始终被复制到新表中。

INCLUDING DEFAULTS #

复制的列定义的默认表达式将被复制。否则,默认表达式不被复制,导致新表中复制的列具有 null 默认值。请注意,复制调用数据库修改函数的默认值(如 nextval)可能会在原始表和新表之间创建函数链接。

INCLUDING GENERATED #

任何生成表达式以及复制的列定义的存储/虚拟选择都将被复制。默认情况下,新列将是常规的基数列。

INCLUDING IDENTITY #

复制的列定义的任何标识规范都将被复制。为新表的每个标识列创建一个新的序列,与旧表关联的序列分开。

INCLUDING INDEXES #

原始表上的索引、PRIMARY KEYUNIQUEEXCLUDE 约束将在新表上创建。新索引和约束的名称将根据默认规则选择,无论原始名称如何。(此行为避免了新索引可能出现的名称重复失败。)

INCLUDING STATISTICS #

扩展统计信息将被复制到新表中。

INCLUDING STORAGE #

复制的列定义的 STORAGE 设置将被复制。默认行为是排除 STORAGE 设置,导致新表中复制的列具有特定类型的默认设置。有关 STORAGE 设置的更多信息,请参阅 第 66.2 节

INCLUDING ALL #

INCLUDING ALL 是一个简写形式,选择了所有可用的单独选项。(在 INCLUDING ALL 之后写单独的 EXCLUDING 子句以选择除某些特定选项之外的所有选项可能会很有用。)

LIKE 子句还可以用于从视图、外部表或复合类型复制列定义。不适用的选项(例如,来自视图的 INCLUDING INDEXES)将被忽略。

CONSTRAINT constraint_name #

列或表约束的可选名称。如果违反约束,错误消息中将包含约束名称,因此可以使用 col must be positive 这样的约束名称向客户端应用程序传达有用的约束信息。(需要双引号才能指定包含空格的约束名称。)如果未指定约束名称,系统将生成一个名称。

NOT NULL [ NO INHERIT ] #

该列不允许包含 null 值。

标记为 NO INHERIT 的约束不会传播到子表。

NULL #

该列允许包含 null 值。这是默认行为。

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

CHECK ( 表达式 ) [ NO INHERIT ] #

CHECK 子句指定了一个生成布尔结果的表达式,新行或更新后的行必须满足此表达式,插入或更新操作才能成功。计算结果为 TRUE 或 UNKNOWN 的表达式会成功。如果插入或更新操作的任何行生成 FALSE 结果,则会引发错误异常,并且插入或更新不会更改数据库。作为列约束指定的检查约束应仅引用该列的值,而表约束中出现的表达式可以引用多个列。

当前,CHECK 表达式不能包含子查询,也不能引用除当前行列之外的任何变量(请参见 第 5.5.1 节)。可以引用系统列 tableoid,但不能引用任何其他系统列。

标记为 NO INHERIT 的约束不会传播到子表。

当一个表有多个 CHECK 约束时,它们将在检查 NOT NULL 约束后,按名称的字母顺序对每一行进行测试。(PostgreSQL 9.5 之前的版本不遵循任何特定的 CHECK 约束的执行顺序。)

DEFAULT 默认表达式 #

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

如果插入操作未为该列指定值,则将使用默认表达式。如果某列没有默认值,则默认值为 null。

GENERATED ALWAYS AS ( 生成表达式 ) [ STORED | VIRTUAL ] #

此子句将该列创建为生成列。该列不能被写入,读取时将返回指定表达式的结果。

指定 VIRTUAL 时,该列将在读取时计算,并且不占用任何存储空间。指定 STORED 时,该列将在写入时计算并存储在磁盘上。VIRTUAL 是默认值。

生成表达式可以引用表中的其他列,但不能引用其他生成列。使用的任何函数和运算符都必须是不可变的。不允许引用其他表。

虚拟生成列不能具有用户定义的类型,并且虚拟生成列的生成表达式不得引用用户定义的函数或类型,即,它只能使用内置函数或类型。这也适用于间接情况,例如用于运算符或转换的基础函数或类型。(对于存储的生成列,此限制不存在。)

GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( 序列选项 ) ] #

此子句将该列创建为标识列。它将具有一个隐式序列与之关联,在新插入的行中,该列将自动获得序列的值。这样的列隐式地为 NOT NULL

ALWAYSBY DEFAULT 子句确定在 INSERTUPDATE 命令中如何处理用户指定的显式值。

INSERT 命令中,如果选择了 ALWAYS,则只有当 INSERT 语句指定了 OVERRIDING SYSTEM VALUE 时,才接受用户指定的值。如果选择了 BY DEFAULT,则用户指定的值优先。有关详细信息,请参见 INSERT。(在 COPY 命令中,无论此设置如何,始终使用用户指定的值。)

UPDATE 命令中,如果选择了 ALWAYS,则任何将该列更新为除 DEFAULT 以外的值都将被拒绝。如果选择了 BY DEFAULT,则可以正常更新该列。(UPDATE 命令没有 OVERRIDING 子句。)

可选的 序列选项 子句可用于覆盖序列的参数。可用选项包括 CREATE SEQUENCE 中显示的选项,外加 SEQUENCE NAME 名称LOGGEDUNLOGGED,这些选项允许选择序列的名称和持久性级别。没有 SEQUENCE NAME 时,系统会选择一个未使用的名称作为序列的名称。没有 LOGGEDUNLOGGED 时,序列将具有与表相同的持久性级别。

UNIQUE [ NULLS [ NOT ] DISTINCT ](列约束)
UNIQUE [ NULLS [ NOT ] DISTINCT ] ( 列名 [, ... ] [, 列名 WITHOUT OVERLAPS ] ) [ INCLUDE ( 列名 [, ...]) ](表约束) #

UNIQUE 约束指定表中一组一个或多个列只能包含唯一值。唯一表约束的行为与唯一列约束相同,并增加了跨越多个列的能力。因此,该约束强制要求任何两行在这些列中的至少一个列上必须不同。

如果为最后一列指定了 WITHOUT OVERLAPS 选项,则该列将检查重叠而不是相等。在这种情况下,只要重复项在 WITHOUT OVERLAPS 列中不重叠,其他约束列就允许重复。(如果该列是日期或时间戳的范围,这有时被称为时间范围键,但 PostgreSQL 允许任何基本类型的范围。)实际上,这种约束是通过 EXCLUDE 约束而不是 UNIQUE 约束强制执行的。例如,UNIQUE (id, valid_at WITHOUT OVERLAPS) 的行为类似于 EXCLUDE USING GIST (id WITH =, valid_at WITH &&)WITHOUT OVERLAPS 列必须是范围或多范围类型。不允许空范围/多范围。约束的非 WITHOUT OVERLAPS 列可以是任何可以在 GiST 索引中进行相等比较的类型。默认情况下,仅支持范围类型,但您可以通过添加 btree_gist 扩展来使用其他类型(这是使用此功能的预期方式)。

就唯一约束而言,空值不被视为相等,除非指定了 NULLS NOT DISTINCT

每个唯一约束应命名一组列,该组列应不同于为该表定义的任何其他唯一约束或主键约束所命名的列集。(否则,重复的唯一约束将被丢弃。)

在为多级分区层次结构建立唯一约束时,目标分区表及其所有后代分区表的分区键中的所有列都必须包含在约束定义中。

添加唯一约束将自动在该约束使用的列或列组上创建一个唯一的 btree 索引。但如果约束包含 WITHOUT OVERLAPS 子句,它将使用 GiST 索引。创建的索引与唯一约束具有相同的名称。

可选的 INCLUDE 子句将一个或多个列添加到该索引中,这些列仅是有效负载:不强制对它们执行唯一性,并且无法基于这些列来搜索索引。但是,它们可以通过仅索引扫描进行检索。请注意,尽管不强制对包含的列执行约束,但它仍然依赖于它们。因此,对这些列的某些操作(例如 DROP COLUMN)可能会导致级联约束和索引删除。

PRIMARY KEY(列约束)
PRIMARY KEY ( 列名 [, ... ] [, 列名 WITHOUT OVERLAPS ] ) [ INCLUDE ( 列名 [, ...]) ](表约束) #

PRIMARY KEY 约束指定表的一列或多列只能包含唯一(非重复)的非空值。对于一个表,无论是以列约束还是表约束的形式,都只能指定一个主键。

主键约束应命名一组列,该组列应不同于为同一表定义的任何唯一约束所命名的列集。(否则,唯一约束将是冗余的并将被丢弃。)

PRIMARY KEY 强制执行与 UNIQUENOT NULL 的组合相同的 数据约束。但是,将一组列标识为主键还可以提供有关架构设计的元数据,因为主键意味着其他表可以依赖于这组列作为行的唯一标识符。

当应用于分区表时,PRIMARY KEY 约束共享之前为 UNIQUE 约束描述的限制。

添加 PRIMARY KEY 约束将自动在该约束使用的列或列组上创建一个唯一的 btree 索引,如果指定了 WITHOUT OVERLAPS,则使用 GiST 索引。

可选的 INCLUDE 子句将一个或多个列添加到该索引中,这些列仅是有效负载:不强制对它们执行唯一性,并且无法基于这些列来搜索索引。但是,它们可以通过仅索引扫描进行检索。请注意,尽管不强制对包含的列执行约束,但它仍然依赖于它们。因此,对这些列的某些操作(例如 DROP COLUMN)可能会导致级联约束和索引删除。

EXCLUDE [ USING 索引方法 ] ( 排除元素 WITH 运算符 [, ... ] ) 索引参数 [ WHERE ( 谓词 ) ] #

EXCLUDE 子句定义了一个排斥约束,它保证如果在使用指定的运算符将任何两行与指定的列(或表达式)进行比较时,并非所有这些比较都返回 TRUE。如果所有指定的运算符都测试相等性,那么这等同于 UNIQUE 约束,尽管普通唯一约束会更快。但是,排斥约束可以指定比简单相等性更通用的约束。例如,您可以使用 && 运算符指定一个约束,即表中没有两行包含重叠的圆(参见 第 8.8 节)。指定的运算符必须是可交换的。

排斥约束是通过与约束同名的索引实现的,因此每个指定的运算符都必须与索引访问方法 索引方法 的适当算子类(参见 第 11.10 节)相关联。每个 排除元素 定义了一个索引列,因此它可以选择性地指定排序规则、算子类、算子类参数和/或排序选项;这些在 CREATE INDEX 中有完整描述。

访问方法必须支持 amgettuple(参见 第 63 章);目前这意味着GIN不能使用。虽然允许使用 B-tree 或 hash 索引进行排斥约束,但这并不能做普通唯一约束做不到的任何事情。因此,实际上访问方法将始终是GiSTSP-GiST.

谓词 允许您为表的子集指定排斥约束;在内部,这会创建一个部分索引。请注意,谓词周围必须有括号。

为多级分区层次结构建立排斥约束时,目标分区表及其所有后代分区表的分区键中的所有列都必须包含在约束定义中。此外,这些列必须使用相等运算符进行比较。这些限制确保可能冲突的行将存在于同一分区中。该约束还可以引用不是任何分区键一部分的其他列,这些列可以使用任何适当的运算符进行比较。

REFERENCES 引用表 [ ( 引用列 ) ] [ MATCH 匹配类型 ] [ ON DELETE 引用操作 ] [ ON UPDATE 引用操作 ](列约束)
FOREIGN KEY ( 列名 [, ... ] [, PERIOD 列名 ] ) REFERENCES 引用表 [ ( 引用列 [, ... ] [, PERIOD 引用列 ] ) ] [ MATCH 匹配类型 ] [ ON DELETE 引用操作 ] [ ON UPDATE 引用操作 ](表约束) #

这些子句指定了外键约束,该约束要求新表的一列或多列中的值必须匹配引用表中某行的引用列(或列)中的值。如果省略 引用列 列表,则使用 引用表 的主键。否则,引用列 列表必须引用非延迟唯一约束或主键约束的列,或者是一些非部分唯一索引的列。

如果最后一列标记为 PERIOD,则它被特殊处理。虽然非 PERIOD 列是按相等性比较的(并且至少必须有一个),但 PERIOD 列不是。相反,如果引用表具有匹配的记录(基于键的非 PERIOD 部分),并且这些记录的 PERIOD 值完全覆盖了引用记录的 PERIOD 值,则认为约束满足。换句话说,引用必须在其整个持续时间内都有一个被引用项。此列必须是范围或多范围类型。此外,引用表必须具有使用 WITHOUT OVERLAPS 声明的主键或唯一约束。最后,如果外键具有 PERIOD 列名 规范,则相应的 引用列(如果存在)也必须标记为 PERIOD。如果省略 引用列 子句,从而选择了引用表的PRIMARY KEY 约束,则 PRIMARY KEY 的最后一列必须标记为 WITHOUT OVERLAPS

对于每一对引用列和被引用列,如果它们是可排序的数据类型,则它们的排序规则必须都是确定性的,或者两者都相同。这确保了这两列具有一致的相等性概念。

用户必须对引用表具有 REFERENCES 权限(可以是整个表,也可以是特定的引用列)。添加外键约束需要对引用表进行 SHARE ROW EXCLUSIVE 锁。请注意,外键约束不能在临时表和永久表之间定义。

插入到引用列(或列)中的值将使用指定的匹配类型与引用表和引用列的值进行匹配。有三种匹配类型:MATCH FULLMATCH PARTIALMATCH SIMPLE(这是默认值)。MATCH FULL 不允许多列外键的其中一列为 null,除非所有外键列都为 null;如果它们都为 null,则不要求该行在引用表中具有匹配项。MATCH SIMPLE 允许外键中的任何一列为 null;如果其中任何一列为 null,则不要求该行在引用表中具有匹配项。MATCH PARTIAL 尚未实现。(当然,NOT NULL 约束可以应用于引用列(或列)以防止这种情况发生。)

此外,当引用列中的数据发生更改时,会对本表列中的数据执行某些操作。ON DELETE 子句指定在删除引用表中的引用行时要执行的操作。类似地,ON UPDATE 子句指定在引用表中的引用列更新为新值时要执行的操作。如果行被更新,但引用列实际上未更改,则不执行任何操作。引用操作作为数据更改命令的一部分执行,即使约束是延迟的。对于每个子句,有以下可能的动作:

NO ACTION #

如果删除或更新会违反外键约束,则会产生错误。如果约束是延迟的,则在约束检查时会产生此错误,前提是仍然存在任何引用行。这是默认操作。

RESTRICT #

如果被删除或更新的行与引用表中的行匹配,则会产生错误。这会阻止该操作,即使操作后的状态不会违反外键约束。特别是,它会阻止对引用行的更新为与原值不同但比较相等的更新。(但它不会阻止将列更新为相同值的“无操作”更新。)

在时间外键中,不支持此选项。

CASCADE #

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

在时间外键中,不支持此选项。

SET NULL [ ( 列名 [, ... ] ) ] #

将所有引用列(或指定子集)设置为 null。仅可在 ON DELETE 操作中指定列的子集。

在时间外键中,不支持此选项。

SET DEFAULT [ ( 列名 [, ... ] ) ] #

将所有引用列(或指定子集)设置为其默认值。仅可在 ON DELETE 操作中指定列的子集。(如果默认值不为 null,则必须在引用表中存在与默认值匹配的行,否则操作将失败。)

在时间外键中,不支持此选项。

如果引用列(或列)频繁更改,则最好在引用列(或列)上添加索引,以便更有效地执行与外键约束相关的引用操作。

DEFERRABLE
NOT DEFERRABLE #

这控制约束是否可以延迟。不可延迟的约束将在每个命令之后立即检查。可延迟约束的检查可以推迟到事务结束(使用 SET CONSTRAINTS 命令)。NOT DEFERRABLE 是默认值。目前,只有 UNIQUEPRIMARY KEYEXCLUDEREFERENCES(外键)约束接受此子句。NOT NULLCHECK 约束不可延迟。请注意,在包含 ON CONFLICT DO UPDATE 子句的 INSERT 语句中,可延迟约束不能用作冲突仲裁者。

INITIALLY IMMEDIATE
INITIALLY DEFERRED #

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

ENFORCED
NOT ENFORCED #

当约束为 ENFORCED 时,数据库系统将确保约束得到满足,方法是在适当的时候(根据情况,在每个语句之后或在事务结束时)检查约束。这是默认行为。如果约束为 NOT ENFORCED,数据库系统将不检查约束。然后由应用程序代码负责确保约束得到满足。数据库系统仍可能出于优化目的假设数据实际满足约束,因为这不会影响结果的正确性。

NOT ENFORCED 约束可作为文档,如果运行时检查约束过于昂贵。

目前仅支持外键和 CHECK 约束。

USING 方法 #

此可选子句指定用于存储新表内容的表访问方法;该方法必须是类型为 TABLE 的访问方法。有关更多信息,请参见 第 62 章。如果未指定此选项,则为新表选择默认表访问方法。有关更多信息,请参见 default_table_access_method

创建分区时,表访问方法是其分区表的访问方法(如果已设置)。

WITH ( 存储参数 [= ] [, ... ] ) #

此子句指定表的存储参数或索引的存储参数;有关更多信息,请参见下面的 存储参数。为了向后兼容,表的 WITH 子句还可以包含 OIDS=FALSE 来指定新表的行不应包含 OID(对象标识符),OIDS=TRUE 不再支持。

WITHOUT OIDS #

这是声明表 WITHOUT OIDS 的兼容语法,创建表 WITH OIDS 已不再支持。

ON COMMIT #

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

PRESERVE ROWS #

在事务结束时,不采取特殊操作。这是默认行为。

DELETE ROWS #

临时表中的所有行将在每个事务块结束时被删除。本质上,每次提交都会自动执行 TRUNCATE。在分区表上使用时,不会级联到其分区。

DROP #

临时表将在当前事务块结束时被删除。在分区表上使用时,此操作会删除其分区;在具有继承子表的表上使用时,会删除依赖的子表。

TABLESPACE 表空间名称 #

表空间名称 是创建新表所在的表空间的名称。如果未指定,则查阅 default_tablespace,如果表是临时的,则查阅 temp_tablespaces。对于分区表,由于表本身不需要存储,因此指定的表空间会覆盖 default_tablespace,作为创建新分区时的默认表空间,如果未显式指定其他表空间。

USING INDEX TABLESPACE 表空间名称 #

此子句允许选择与 UNIQUEPRIMARY KEYEXCLUDE 约束关联的索引将要创建的表空间。如果未指定,则查阅 default_tablespace,如果表是临时的,则查阅 temp_tablespaces

存储参数

WITH 子句可以为表和与 UNIQUEPRIMARY KEYEXCLUDE 约束关联的索引指定存储参数。索引的存储参数在 CREATE INDEX 中有文档说明。下面列出了当前可用于表的存储参数。其中许多参数(如所示)都有一个同名但带有 toast. 前缀的附加参数,该参数控制表(如果有)的二次TOAST表(TOAST 表)的行为(有关 TOAST 的更多信息,请参见 第 66.2 节)。如果设置了表参数值,而未设置等效的 toast. 参数,则 TOAST 表将使用表参数值。不支持为分区表指定这些参数,但您可以为单个叶子分区指定它们。

fillfactorinteger #

表的 fillfactor 是一个介于 10 和 100 之间的百分比。默认值为 100(完全打包)。当指定较小的 fillfactor 时,INSERT 操作仅将表页填充到指示的百分比;每个页上剩余的空间用于更新该页上的行。这使得 UPDATE 有机会将行的更新副本放置在与原始副本相同的页面上,这比将其放置在不同页面上更有效,并且使堆仅元组更新更有可能发生。对于从未更新的条目,完全打包是最佳选择,但在大量更新的表中,较小的 fillfactor 是合适的。无法为 TOAST 表设置此参数。

toast_tuple_targetinteger #

toast_tuple_target 指定在尝试压缩和/或将长列值移至 TOAST 表所需的最小元组长度,并且也是一旦开始分 toast 的目标长度。这会影响标记为 External(用于移动)、Main(用于压缩)或 Extended(用于两者)的列,并且仅适用于新元组。对现有行没有影响。默认情况下,此参数设置为允许每个块至少有 4 个元组,这将是 2040 字节(默认块大小)。有效值介于 128 字节和(块大小 - 头部)之间,默认为 8160 字节。更改此值对于非常短或非常长的行可能没有用。请注意,默认设置通常接近最优,并且在这种情况下,设置此参数可能会产生负面影响。无法为 TOAST 表设置此参数。

parallel_workersinteger #

这设置了用于辅助并行扫描此表的 worker 数量。如果未设置,系统将根据关系大小确定一个值。计划程序或使用并行扫描的实用程序语句实际选择的 worker 数量可能会少一些,例如由于 max_worker_processes 的设置。

autovacuum_enabled, toast.autovacuum_enabledboolean #

启用或禁用特定表的 autovacuum 守护进程。如果为 true,autovacuum 守护进程将按照 第 24.1.6 节 中讨论的规则,对该表执行自动 VACUUM 和/或 ANALYZE 操作。如果为 false,此表将不会被 autovacuum,除非是为了防止事务 ID 溢出。有关溢出预防的更多信息,请参见 第 24.1.5 节。请注意,如果 autovacuum 参数为 false,则 autovacuum 守护进程根本不会运行(除非是为了防止事务 ID 溢出);设置单个表的存储参数不会覆盖该设置。因此,显式将此存储参数设置为 true 通常没有多大意义,只应设置为 false

vacuum_index_cleanup, toast.vacuum_index_cleanupenum #

当在该表上运行 VACUUM 时,强制或禁用索引清理。默认值为 AUTO。设置为 OFF 时,禁用索引清理;设置为 ON 时,启用索引清理;设置为 AUTO 时,每次运行 VACUUM 时都会动态决定。动态行为允许 VACUUM 避免不必要地扫描索引以删除非常少的死元组。强制禁用所有索引清理可以非常显著地加快 VACUUM 的速度,但如果表修改频繁,也可能导致索引严重膨胀。VACUUMINDEX_CLEANUP 参数(如果指定)将覆盖此选项的值。

vacuum_truncate, toast.vacuum_truncate (boolean) #

每个表 vacuum_truncate 参数的值。如果指定了 VACUUMTRUNCATE 参数,它将覆盖此选项的值。

autovacuum_vacuum_threshold, toast.autovacuum_vacuum_threshold (integer) #

autovacuum_vacuum_threshold 参数的每个表值。

autovacuum_vacuum_max_threshold, toast.autovacuum_vacuum_max_threshold (integer) #

autovacuum_vacuum_max_threshold 参数的每个表值。

autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (floating point) #

autovacuum_vacuum_scale_factor 参数的每个表值。

autovacuum_vacuum_insert_threshold, toast.autovacuum_vacuum_insert_threshold (integer) #

Per-table value for autovacuum_vacuum_insert_threshold parameter. The special value of -1 may be used to disable insert vacuums on the table.

autovacuum_vacuum_insert_scale_factor, toast.autovacuum_vacuum_insert_scale_factor (floating point) #

autovacuum_vacuum_insert_scale_factor 参数的每个表值。

autovacuum_analyze_threshold (integer) #

autovacuum_analyze_threshold 参数的每个表值。

autovacuum_analyze_scale_factor (floating point) #

autovacuum_analyze_scale_factor 参数的每个表值。

autovacuum_vacuum_cost_delay, toast.autovacuum_vacuum_cost_delay (floating point) #

autovacuum_vacuum_cost_delay 参数的每个表值。

autovacuum_vacuum_cost_limit, toast.autovacuum_vacuum_cost_limit (integer) #

autovacuum_vacuum_cost_limit 参数的每个表值。

autovacuum_freeze_min_age, toast.autovacuum_freeze_min_age (integer) #

Per-table value for vacuum_freeze_min_age parameter. Note that autovacuum will ignore per-table autovacuum_freeze_min_age parameters that are larger than half the system-wide autovacuum_freeze_max_age setting.

autovacuum_freeze_max_age, toast.autovacuum_freeze_max_age (integer) #

Per-table value for autovacuum_freeze_max_age parameter. Note that autovacuum will ignore per-table autovacuum_freeze_max_age parameters that are larger than the system-wide setting (it can only be set smaller).

autovacuum_freeze_table_age, toast.autovacuum_freeze_table_age (integer) #

vacuum_freeze_table_age 参数的每个表值。

autovacuum_multixact_freeze_min_age, toast.autovacuum_multixact_freeze_min_age (integer) #

Per-table value for vacuum_multixact_freeze_min_age parameter. Note that autovacuum will ignore per-table autovacuum_multixact_freeze_min_age parameters that are larger than half the system-wide autovacuum_multixact_freeze_max_age setting.

autovacuum_multixact_freeze_max_age, toast.autovacuum_multixact_freeze_max_age (integer) #

Per-table value for autovacuum_multixact_freeze_max_age parameter. Note that autovacuum will ignore per-table autovacuum_multixact_freeze_max_age parameters that are larger than the system-wide setting (it can only be set smaller).

autovacuum_multixact_freeze_table_age, toast.autovacuum_multixact_freeze_table_age (integer) #

vacuum_multixact_freeze_table_age 参数的每个表值。

log_autovacuum_min_duration, toast.log_autovacuum_min_duration (integer) #

log_autovacuum_min_duration 参数的每个表值。

vacuum_max_eager_freeze_failure_rate, toast.vacuum_max_eager_freeze_failure_rate (floating point) #

vacuum_max_eager_freeze_failure_rate 参数的每个表值。

user_catalog_table (boolean) #

Declare the table as an additional catalog table for purposes of logical replication. See Section 47.6.2 for details. This parameter cannot be set for TOAST tables.

注释

PostgreSQL automatically creates an index for each unique constraint and primary key constraint to enforce uniqueness. Thus, it is not necessary to create an index explicitly for primary key columns. (See CREATE INDEX for more information.)

Unique constraints and primary keys are not inherited in the current implementation. This makes the combination of inheritance and unique constraints rather dysfunctional.

A table cannot have more than 1600 columns. (In practice, the effective limit is usually lower because of tuple-length constraints.)

示例

Create table films and table 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 GENERATED BY DEFAULT AS IDENTITY,
     name   varchar(40) NOT NULL CHECK (name <> '')
);

Create a table with a 2-dimensional array

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

Define a unique table constraint for the table films. Unique table constraints can be defined on one or more columns of the table

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)
);

Define a check column constraint

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

Define a check table constraint

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

Define a primary key table constraint for the table 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)
);

Define a primary key constraint for table distributors. The following two examples are equivalent, the first using the table constraint syntax, the second the column constraint syntax

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

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

Assign a literal constant default value for the column name, arrange for the default value of column did to be generated by selecting the next value of a sequence object, and make the default value of modtime be the time at which the row is inserted

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

Define two NOT NULL column constraints on the table distributors, one of which is explicitly given a name

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

Define a unique constraint for the name column

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

The same, specified as a table constraint

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

Create the same table, specifying 70% fill factor for both the table and its unique index

CREATE TABLE distributors (
    did     integer,
    name    varchar(40),
    UNIQUE(name) WITH (fillfactor=70)
)
WITH (fillfactor=70);

Create table circles with an exclusion constraint that prevents any two circles from overlapping

CREATE TABLE circles (
    c circle,
    EXCLUDE USING gist (c WITH &&)
);

Create table cinemas in tablespace diskvol1

CREATE TABLE cinemas (
        id serial,
        name text,
        location text
) TABLESPACE diskvol1;

Create a composite type and a typed table

CREATE TYPE employee_type AS (name text, salary numeric);

CREATE TABLE employees OF employee_type (
    PRIMARY KEY (name),
    salary WITH OPTIONS DEFAULT 1000
);

Create a range partitioned table

CREATE TABLE measurement (
    logdate         date not null,
    peaktemp        int,
    unitsales       int
) PARTITION BY RANGE (logdate);

Create a range partitioned table with multiple columns in the partition key

CREATE TABLE measurement_year_month (
    logdate         date not null,
    peaktemp        int,
    unitsales       int
) PARTITION BY RANGE (EXTRACT(YEAR FROM logdate), EXTRACT(MONTH FROM logdate));

Create a list partitioned table

CREATE TABLE cities (
    city_id      bigserial not null,
    name         text not null,
    population   bigint
) PARTITION BY LIST (left(lower(name), 1));

Create a hash partitioned table

CREATE TABLE orders (
    order_id     bigint not null,
    cust_id      bigint not null,
    status       text
) PARTITION BY HASH (order_id);

Create partition of a range partitioned table

CREATE TABLE measurement_y2016m07
    PARTITION OF measurement (
    unitsales DEFAULT 0
) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01');

Create a few partitions of a range partitioned table with multiple columns in the partition key

CREATE TABLE measurement_ym_older
    PARTITION OF measurement_year_month
    FOR VALUES FROM (MINVALUE, MINVALUE) TO (2016, 11);

CREATE TABLE measurement_ym_y2016m11
    PARTITION OF measurement_year_month
    FOR VALUES FROM (2016, 11) TO (2016, 12);

CREATE TABLE measurement_ym_y2016m12
    PARTITION OF measurement_year_month
    FOR VALUES FROM (2016, 12) TO (2017, 01);

CREATE TABLE measurement_ym_y2017m01
    PARTITION OF measurement_year_month
    FOR VALUES FROM (2017, 01) TO (2017, 02);

Create partition of a list partitioned table

CREATE TABLE cities_ab
    PARTITION OF cities (
    CONSTRAINT city_id_nonzero CHECK (city_id != 0)
) FOR VALUES IN ('a', 'b');

Create partition of a list partitioned table that is itself further partitioned and then add a partition to it

CREATE TABLE cities_ab
    PARTITION OF cities (
    CONSTRAINT city_id_nonzero CHECK (city_id != 0)
) FOR VALUES IN ('a', 'b') PARTITION BY RANGE (population);

CREATE TABLE cities_ab_10000_to_100000
    PARTITION OF cities_ab FOR VALUES FROM (10000) TO (100000);

Create partitions of a hash partitioned table

CREATE TABLE orders_p1 PARTITION OF orders
    FOR VALUES WITH (MODULUS 4, REMAINDER 0);
CREATE TABLE orders_p2 PARTITION OF orders
    FOR VALUES WITH (MODULUS 4, REMAINDER 1);
CREATE TABLE orders_p3 PARTITION OF orders
    FOR VALUES WITH (MODULUS 4, REMAINDER 2);
CREATE TABLE orders_p4 PARTITION OF orders
    FOR VALUES WITH (MODULUS 4, REMAINDER 3);

Create a default partition

CREATE TABLE cities_partdef
    PARTITION OF cities DEFAULT;

兼容性

The CREATE TABLE command conforms to theSQLstandard, with exceptions listed below.

Temporary Tables

Although the syntax of CREATE TEMPORARY TABLE resembles that of the SQL standard, the effect is not the same. In the standard, temporary tables are defined just once and automatically exist (starting with empty contents) in every session that needs them. PostgreSQL instead requires each session to issue its own CREATE TEMPORARY TABLE command for each temporary table to be used. This allows different sessions to use the same temporary table name for different purposes, whereas the standard's approach constrains all instances of a given temporary table name to have the same table structure.

The standard's definition of the behavior of temporary tables is widely ignored. PostgreSQL's behavior on this point is similar to that of several other SQL databases.

The SQL standard also distinguishes between global and local temporary tables, where a local temporary table has a separate set of contents for each SQL module within each session, though its definition is still shared across sessions. Since PostgreSQL does not support SQL modules, this distinction is not relevant in PostgreSQL.

For compatibility's sake, PostgreSQL will accept the GLOBAL and LOCAL keywords in a temporary table declaration, but they currently have no effect. Use of these keywords is discouraged, since future versions of PostgreSQL might adopt a more standard-compliant interpretation of their meaning.

The ON COMMIT clause for temporary tables also resembles the SQL standard, but has some differences. If the ON COMMIT clause is omitted, SQL specifies that the default behavior is ON COMMIT DELETE ROWS. However, the default behavior in PostgreSQL is ON COMMIT PRESERVE ROWS. The ON COMMIT DROP option does not exist in SQL.

Non-Deferred Uniqueness Constraints

When a UNIQUE or PRIMARY KEY constraint is not deferrable, PostgreSQL checks for uniqueness immediately whenever a row is inserted or modified. The SQL standard says that uniqueness should be enforced only at the end of the statement; this makes a difference when, for example, a single command updates multiple key values. To obtain standard-compliant behavior, declare the constraint as DEFERRABLE but not deferred (i.e., INITIALLY IMMEDIATE). Be aware that this can be significantly slower than immediate uniqueness checking.

Column Check Constraints

The SQL standard says that CHECK column constraints can only refer to the column they apply to; only CHECK table constraints can refer to multiple columns. PostgreSQL does not enforce this restriction; it treats column and table check constraints alike.

EXCLUDE Constraint

The EXCLUDE constraint type is a PostgreSQL extension.

Foreign Key Constraints

The ability to specify column lists in the foreign key actions SET DEFAULT and SET NULL is a PostgreSQL extension.

It is a PostgreSQL extension that a foreign key constraint may reference columns of a unique index instead of columns of a primary key or unique constraint.

NULL Constraint

The NULL constraint (actually a non-constraint) is a PostgreSQL extension to the SQL standard that is included for compatibility with some other database systems (and for symmetry with the NOT NULL constraint). Since it is the default for any column, its presence is simply noise.

Constraint Naming

The SQL standard says that table and domain constraints must have names that are unique across the schema containing the table or domain. PostgreSQL is laxer: it only requires constraint names to be unique across the constraints attached to a particular table or domain. However, this extra freedom does not exist for index-based constraints (UNIQUE, PRIMARY KEY, and EXCLUDE constraints), because the associated index is named the same as the constraint, and index names must be unique across all relations within the same schema.

Inheritance

Multiple inheritance via the INHERITS clause is a PostgreSQL language extension. SQL:1999 and later define single inheritance using a different syntax and different semantics. SQL:1999-style inheritance is not yet supported by PostgreSQL.

Zero-Column Tables

PostgreSQL allows a table of no columns to be created (for example, CREATE TABLE foo();). This is an extension from the SQL standard, which does not allow zero-column tables. Zero-column tables are not in themselves very useful, but disallowing them creates odd special cases for ALTER TABLE DROP COLUMN, so it seems cleaner to ignore this spec restriction.

Multiple Identity Columns

PostgreSQL allows a table to have more than one identity column. The standard specifies that a table can have at most one identity column. This is relaxed mainly to give more flexibility for doing schema changes or migrations. Note that the INSERT command supports only one override clause that applies to the entire statement, so having multiple identity columns with different behaviors is not well supported.

Generated Columns

The options STORED and VIRTUAL are not standard but are also used by other SQL implementations. The SQL standard does not specify the storage of generated columns.

LIKE Clause

While a LIKE clause exists in the SQL standard, many of the options that PostgreSQL accepts for it are not in the standard, and some of the standard's options are not implemented by PostgreSQL.

WITH Clause

The WITH clause is a PostgreSQL extension; storage parameters are not in the standard.

表空间

The PostgreSQL concept of tablespaces is not part of the standard. Hence, the clauses TABLESPACE and USING INDEX TABLESPACE are extensions.

Typed Tables

Typed tables implement a subset of the SQL standard. According to the standard, a typed table has columns corresponding to the underlying composite type as well as one other column that is the self-referencing column. PostgreSQL does not support self-referencing columns explicitly.

PARTITION BY Clause

The PARTITION BY clause is a PostgreSQL extension.

PARTITION OF Clause

The PARTITION OF clause is a PostgreSQL extension.

提交更正

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.