CREATE TABLE — 定义一个新表
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ]table_name
( [ {column_name
data_type
[ COMPRESSIONcompression_method
] [ COLLATEcollation
] [column_constraint
[ ... ] ] |table_constraint
| LIKEsource_table
[like_option
... ] } [, ... ] ] ) [ INHERITS (parent_table
[, ... ] ) ] [ PARTITION BY { RANGE | LIST | HASH } ( {column_name
| (expression
) } [ COLLATEcollation
] [opclass
] [, ... ] ) ] [ USINGmethod
] [ WITH (storage_parameter
[=value
] [, ... ] ) | WITHOUT OIDS ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACEtablespace_name
] CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ]table_name
OFtype_name
[ ( {column_name
[ WITH OPTIONS ] [column_constraint
[ ... ] ] |table_constraint
} [, ... ] ) ] [ PARTITION BY { RANGE | LIST | HASH } ( {column_name
| (expression
) } [ COLLATEcollation
] [opclass
] [, ... ] ) ] [ USINGmethod
] [ WITH (storage_parameter
[=value
] [, ... ] ) | WITHOUT OIDS ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACEtablespace_name
] CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ]table_name
PARTITION OFparent_table
[ ( {column_name
[ WITH OPTIONS ] [column_constraint
[ ... ] ] |table_constraint
} [, ... ] ) ] { FOR VALUESpartition_bound_spec
| DEFAULT } [ PARTITION BY { RANGE | LIST | HASH } ( {column_name
| (expression
) } [ COLLATEcollation
] [opclass
] [, ... ] ) ] [ USINGmethod
] [ WITH (storage_parameter
[=value
] [, ... ] ) | WITHOUT OIDS ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACEtablespace_name
] 其中column_constraint
是: [ CONSTRAINTconstraint_name
] { NOT NULL | NULL | CHECK (expression
) [ NO INHERIT ] | DEFAULTdefault_expr
| GENERATED ALWAYS AS (generation_expr
) STORED | GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ (sequence_options
) ] | UNIQUEindex_parameters
| PRIMARY KEYindex_parameters
| REFERENCESreftable
[ (refcolumn
) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETEreferential_action
] [ ON UPDATEreferential_action
] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] andtable_constraint
是: [ CONSTRAINTconstraint_name
] { CHECK (expression
) [ NO INHERIT ] | UNIQUE (column_name
[, ... ] )index_parameters
| PRIMARY KEY (column_name
[, ... ] )index_parameters
| EXCLUDE [ USINGindex_method
] (exclude_element
WITHoperator
[, ... ] )index_parameters
[ WHERE (predicate
) ] | FOREIGN KEY (column_name
[, ... ] ) REFERENCESreftable
[ (refcolumn
[, ... ] ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETEreferential_action
] [ ON UPDATEreferential_action
] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] andlike_option
是: { INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL } andpartition_bound_spec
is: IN (partition_bound_expr
[, ...] ) | FROM ( {partition_bound_expr
| MINVALUE | MAXVALUE } [, ...] ) TO ( {partition_bound_expr
| MINVALUE | MAXVALUE } [, ...] ) | WITH ( MODULUSnumeric_literal
, REMAINDERnumeric_literal
)UNIQUE
、PRIMARY KEY
以及EXCLUDE
约束中的index_parameters
是: [ INCLUDE (column_name
[, ... ] ) ] [ WITH (storage_parameter
[=value
] [, ... ] ) ] [ USING INDEX TABLESPACEtablespace_name
] 一个EXCLUDE
约束中的exclude_element
是: {column_name
| (expression
) } [opclass
] [ ASC | DESC ] [ NULLS { FIRST | LAST } ]
CREATE TABLE
将在当前数据库中创建一个新的、初始为空的表。该表将由发出该命令的用户所拥有。
如果给定了一个模式名(例如CREATE TABLE myschema.mytable ...
),那么该表被创建在指定的模式中。否则它被创建在当前模式中。临时表存在于一个特殊的模式中,因此在创建一个临时表时不能给定一个模式名。该表的名称必须与同一个模式中的任何其他表、序列、索引、视图或外部表的名称区分开。
CREATE TABLE
也会自动地创建一个数据类型来表示对应于该表一行的组合类型。因此,表不能用同一个模式中任何已有数据类型的名称。
可选的约束子句指定一个插入或更新操作要成功,新的或更新过的行必须满足的约束(测试)。一个约束是一个 SQL 对象,它帮助以多种方式定义表中的合法值集合。
有两种方式来定义约束:表约束和列约束。一个列约束会作为列定义的一部分定义。一个表约束定义不与一个特定列绑定,并且它可以包含多于一个列。每一个列约束也可以被写作一个表约束,列约束只是一种当约束只影响一列时方便书写的记号习惯。
要能创建一个表,你必须分别具有所有列类型或OF
子句中类型的USAGE
特权。
TEMPORARY
or TEMP
如果指定,该表被创建为一个临时表。
临时表会被在会话结束时自动被删除,或者也可以选择在当前事务结束时删除(见下文的ON COMMIT
)。
默认搜索路径首先包括临时模式,因此当临时表存在时,不会为新计划选择同名的已有的永久表,除非它们使用模式限定的名称进行引用。
在一个临时表上创建的任何索引也自动地变为临时的。
自动清理守护进程不能访问并且因此也不能清理或分析临时表。由于这个原因,应该通过会话的 SQL 命令执行合适的清理和分析操作。例如,如果一个临时表将要被用于复杂的查询,最好在把它填充完毕后在其上运行ANALYZE
。
可以选择将GLOBAL
或LOCAL
写在TEMPORARY
或TEMP
的前面。这当前在PostgreSQL中没有区别并且已被废弃,见Compatibility。
UNLOGGED
如果指定,该表被创建为一个不受日志记录的表。被写入到不做日志的表中的数据不会被写到预写式日志中(见第 30 章),这让它们比普通表快非常多。不过,它们在崩溃时是不安全的:一个不做日志的表在一次崩溃或非干净关闭之后会被自动地截断。一个不做日志的表中的内容也不会被复制到后备服务器中。在一个不做日志的表上创建的任何索引也会自动地不被日志记录。
IF NOT EXISTS
如果一个同名关系已经存在,不要抛出一个错误。在这种情况下会发出一个提示。注意这不保证现有的关系是和将要被创建的表相似的东西。
table_name
要被创建的表名(可以选择用模式限定)。
OF type_name
创建一个类型化的表,它的结构取自于指定的组合类型(名字可以选择用模式限定)。一个类型化的表和它的类型绑定在一起,例如如果类型被删除,该表也将被删除(用DROP TYPE ... CASCADE
)。
当一个类型化的表被创建时,列的数据类型由底层的组合类型决定而没有在CREATE TABLE
命令中直接指定。但是CREATE TABLE
命令可以对表增加默认值和约束,并且可以指定存储参数。
column_name
列的名称会在新表中被建立.
data_type
列的数据类型. 这可以包括数组 规格. 有关PostgreSQL支持数据类型的详细信息, 请参考第 8 章.
COLLATE collation
COLLATE
子句为该列(必须是一种可排序数据类型)赋予一个排序规则。
如果没有指定,将使用该列数据类型的默认排序规则。
COMPRESSION compression_method
COMPRESSION
子句设置列的压缩方法。
压缩仅支持变宽数据类型,并且仅可在列的存储模式为main
或 extended
的时候使用。
(列存储模式的信息请参见ALTER TABLE。)
为分区表设置此属性没有直接影响,因为该表没有自己的存储空间,但是配置值将由新创建的分区继承。
支持的压缩方法为pglz
和lz4
。
(仅在构建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(详情请参阅第 38.16.3 节)。
分区表被分成多个子表(称为分区),它们是使用单独的CREATE TABLE
命令创建的。
分区表本身是空的。插入到表中的数据行将根据分区键中的列或表达式的值路由到分区。
如果没有现有的分区与新行中的值匹配,则会报告错误。
分区表不支持EXCLUDE
约束;
但是,你可以在各个分区上定义这些约束。
有关表分区的更多讨论,请参阅第 5.11 节
PARTITION OF parent_table
{ FOR VALUES partition_bound_spec
| DEFAULT }
将表创建为指定父表的分区。
该表建立时,可以使用FOR VALUES
创建为特定值的分区,
也可以使用DEFAULT
创建默认分区。父表中存在的任何索引、
约束和用户定义的行级触发器都将克隆到新分区上。
partition_bound_spec
必须对应于父表的分区方法和分区键,并且必须不能与该父表的任何现有分区重叠。
具有IN
的形式用于列表分区,
具有FROM
和TO
的形式用于范围分区,
具有WITH
的形式用于哈希分区。
partition_bound_expr
是任何无变量表达式(不允许子查询、窗口函数、聚合函数和集返回函数)。
它的数据类型必须与相应分区键列的数据类型相匹配。
表达式在表创建时只计算一次,因此它甚至可以包含易失性表达式,如
。
CURRENT_TIMESTAMP
在创建列表分区时,可以指定NULL
来表示分区允许分区键列为空。
但是,给定父表不能有多于一个这样的列表分区。无法为范围分区指定
NULL
。
创建范围分区时,由FROM
指定的下限是一个包含范围,
而用TO
指定的上限是排除范围。也就是说,
在FROM
列表中指定的值是该分区的相应分区键列的有效值,
而TO
列表中的值不是。请注意,
必须根据按行比较的规则来理解此语句(第 9.24.5 节)。
例如,给定PARTITION BY RANGE (x,y)
,分区范围
FROM (1, 2) TO (3, 4)
允许x=1
与任何y>=2
,
x=2
与任何非空y
,和x=3
与任何y<4
。
在创建范围分区以指示列值没有下限或上限时,可以使用特殊值MINVALUE
和MAXVALUE
。例如,使用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"开头的任何行。
请注意,如果MINVALUE
或MAXVALUE
用于分区边界的一列,
则必须为所有后续列使用相同的值。例如,(10, MINVALUE, 0)
不是有效的边界;你应该写(10, MINVALUE, MINVALUE)
。
还要注意,某些元素类型,如timestamp
,具有“无穷”的概念,
这只是另一个可以存储的值。这与MINVALUE
和MAXVALUE
不同,
它们不是可以存储的实际值,而是它们表示值无界的方式。MAXVALUE
可以被认为比任何其他值(包括“无穷”)都大的值,MINVALUE
可以被认为是比任何其他值(包括“负无穷”)都小的值。因此,
范围FROM ('infinity') TO (MAXVALUE)
不是空的范围;
它只允许存储一个值— "infinity"。
如果指定了DEFAULT
,则表将创建为父表的默认分区。此选项不适用于哈希分区表。
不适合给定父级表的任何其他分区的分区键值将路由到默认分区。
当一个表已有DEFAULT
分区并且要对它添加新分区时,
必须扫描默认分区以验证它不包含可能属于新分区的任何行。
如果默认分区包含大量行,则速度可能会很慢。
如果默认分区是外表或者它具有可证明的不可能包含能放置在新分区中的行的约束,则将略过扫描
当创建哈希分区时,必须指定模数和余数。 模数必须是正整数,余数必须是小于模数的非负整数。 通常情况下,当初始设置哈希分区表时,应选择一个与分区数相等的模数,并为每个表分配相同的模数和不同的余数(请参阅下方示例)。 不过,并不要求每个分区都具有相同的模数,只要求哈希分区表里面的分区中出现的每个模数都是下一个较大模数的因数。 这允许以增量的方式增加分区数量而不需要一次移动所有数据。 例如,假设你有一个包含 8 个分区的哈希分区表,每个分区有模数8,但发现有必要将分区数增加到 16 个。 您可以拆分其中一个模数-8分区,然后创建两个新的模数-16分区来覆盖键空间的相同部分(一个的余数等于被拆分的分区的余数,另一个的余数等于该值加 8),而后用数据重新填充他们。 然后,你可以对每一个余数-8分区重复此操作过程,直到没有剩余。 虽然这其中的每个步骤都可能会导致大量的数据移动操作,它仍然要好于建一个全新的表并一次移动全部数据。
分区必须与其所属的分区表的字段名和类型相同。
对分区表字段名或类型的修改,将自动传播到所有分区。
CHECK
约束将自动被每一个分区继承,但是单独的分区可以指定额外的CHECK
约束;与父表相同名称和条件的额外约束将被父表约束合并。
可以为每个分区分别指定默认值。但是请注意,在通过分区表插入元组时不会应用分区的默认值。
插入分区表中的行将自动路由到正确的分区。如果不存在合适的分区,则会发生错误。
像TRUNCATE这样的操作通常会影响一个表及其所有继承子级,这些操作将级联到所有分区,
但也可能在单个分区上执行。请注意,使用DROP TABLE
删除分区需要在父表上采用ACCESS EXCLUSIVE
锁。
LIKE source_table
[ like_option
... ]
LIKE
指定新表将从哪一个表自动地复制所有的列名、数据类型以及它们的非空约束。
和INHERITS
不同,新表和原始表在创建完成之后是完全分离的。对原始表的更改将不会被应用到新表,并且不可能在原始表的扫描中包括新表的数据。
同样与INHERITS
不同,用LIKE
拷贝的列和约束不会和相似的命名列及约束融合。如果显式指定了相同的名称或者在另一个LIKE
子句中指定了相同的名称,将会发出一个错误。
可选的like_option
子句指定要复制的原始表的附加属性。
指定 INCLUDING
复制该属性, 指定 EXCLUDING
忽略该属性。EXCLUDING
为默认值。
如果对同一类型的对象指定了多个规范,则使用最后一个规范。可用的选项包括:
INCLUDING COMMENTS
复制的列、约束和索引的注释将被复制。默认行为是去除注释,从而导致新表中复制的列和约束没有注释。
INCLUDING COMPRESSION
列的压缩方法将被拷贝。 默认行为是去除压缩方法,使得列采用默认压缩方法。
INCLUDING CONSTRAINTS
CHECK
约束将被复制。 列约束和表约束之间没有区别。非空约束始终复制到新表。
INCLUDING DEFAULTS
复制列定义的默认表达式将被复制。否则,不会复制默认表达式,从而导致新表中复制的列具有空默认值。
注意,复制调用数据库修改函数的默认值,例如nextval
,可能在原始表和新表之间创建功能联系。
INCLUDING GENERATED
列定义的任何生成表达式将被复制。 默认情况下,新列将是常规基本列。
INCLUDING IDENTITY
已复制列定义的任何标识规范都将被复制。为新表的每个标识列创建一个新序列,与与旧表关联的序列分开。
INCLUDING INDEXES
原始表上的索引、PRIMARY KEY
、 UNIQUE
和 EXCLUDE
约束将被建立在新表上。
根据默认规则选择新索引和约束的名称,而不考虑原始的命名。(此行为可避免新索引可能出现重复名称失败。)
INCLUDING STATISTICS
扩展统计信息将复制到新表。
INCLUDING STORAGE
已复制列定义的STORAGE
设置将被复制。
默认行为是排除STORAGE
设置,从而导致新表中已复制列具有类型规定的默认设置。
关于STORAGE
设置的更多信息,参见第 70.2 节。
INCLUDING ALL
INCLUDING ALL
是选择所有可用的单独选项的缩写形式。
(它能被用于在INCLUDING ALL
之后写单独的EXCLUDING
子句,以选择部分指定选项之外的所有选项。)
LIKE
子句也能被用来从视图、外部表或组合类型拷贝列定义。不适合的选项(例如来自视图的INCLUDING INDEXES
)会被忽略。
CONSTRAINT constraint_name
一个列约束或表约束的可选名称。如果该约束被违背,约束名将会出现在错误消息中,这样类似列必须为正
的约束名可以用来与客户端应用沟通有用的约束信息(指定包含空格的约束名时需要用到双引号)。如果没有指定约束名,系统将生成一个。
NOT NULL
该列不允许包含空值。
NULL
该列允许包含空值。这是默认情况。
这个子句只是提供与非标准 SQL 数据库的兼容。在新的应用中不推荐使用。
CHECK ( expression
) [ NO INHERIT ]
CHECK
指定一个产生布尔结果的表达式,一个插入或更新操作要想成功,其中新的或被更新的行必须满足该表达式。计算出 TRUE 或 UNKNOWN 的表达式就会成功。只要任何一个插入或更新操作的行产生了 FALSE 结果,将报告一个错误异常并且插入或更新不会修改数据库。一个被作为列约束指定的检查约束只应该引用该列的值,而一个出现在表约束中的表达式可以引用多列。
当前,CHECK
表达式不能包含子查询,也不能引用当前行的列之外的变量(参见 第 5.4.1 节)。可以引用系统列tableoid
,但不能引用其他系统列。
一个被标记为NO INHERIT
的约束将不会传播到子表。
当一个表有多个CHECK
约束时,检查完NOT NULL
约束后,对于每一行会以它们名称的字母表顺序来进行检查(版本 9.5 之前的PostgreSQL对于CHECK
约束不遵从任何特定的引发顺序)。
DEFAULT
default_expr
DEFAULT
子句为出现在其定义中的列赋予一个默认数据。该值是可以使用变量的表达式(特别是,不允许用对其他列的交叉引用)。子查询也是不允许的。
默认值表达式的数据类型必须匹配列的数据类型。
默认值表达式将被用在任何没有为该列指定值的插入操作中。如果一列没有默认值,那么默认值为空值。
GENERATED ALWAYS AS ( generation_expr
) STORED
此子句将列创建为generated column。 列无法被写入,读取时将返回指定表达式的结果。
关键字STORED
表示将在写入时计算列并将存储在磁盘上。
生成表达式可以引用表中的其他列,但不能引用其他生成的列。使用的任何函数和运算符都必须是不可改变的。不允许引用其他表。
GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options
) ]
该子句将列创建为标识列。
它将拥有一个隐式序列附加到它,并且新行中的列将自动从分配给它的序列中获取值。
这样的列为隐式NOT NULL
。
子句ALWAYS
和BY DEFAULT
确定如何在
INSERT
和UPDATE
命令中明确处理用户指定的值。
在INSERT
命令中,如果选择了ALWAYS
,则仅当
INSERT
语句指定OVERRIDING SYSTEM VALUE
时
才接受用户指定的值。如果选择BY DEFAULT
,则用户指定的值优先。
有关详细信息,请参阅INSERT。(在COPY
命令中,
无论此设置如何,始终使用用户指定的值。)
在UPDATE
命令中,如果选择了ALWAYS
,
则将列更新为除DEFAULT
之外的任何值都将被拒绝。
如果选择BY DEFAULT
,则该列可以正常更新。
(UPDATE
命令没有OVERRIDING
子句。)
可选的sequence_options
子句可用于覆盖序列的选项。
有关详细信息,请参见CREATE SEQUENCE。
UNIQUE
(列约束)UNIQUE ( column_name
[, ... ] )
[ INCLUDE ( column_name
[, ...])
] (表约束)
UNIQUE
约束指定一个表中的一列或多列组成的组包含唯一的值。
唯一表约束的行为与唯一列约束的行为相同,只是表约束能够跨越多列。
约束因此强制在这些列中的至少一列的任何两行必须不同。
对于一个唯一约束的目的来说,空值不被认为是相等的。
每一个唯一表约束将命名一个列的集合,并且它与该表上任何其他唯一或主键约束所命名的列集合都不相同。 (否则,冗余的唯一约束将被丢弃。)
在为多级分区层次结构建立唯一约束时, 目标分区表的分区键中的所有列,以及那些由它派生的所有分区表, 必须被包含在约束定义中。
添加唯一约束将自动在使用于约束的列或列组上创建唯一的 btree索引。
可选 INCLUDE
子句向该索引添加一个或多个列是简单的“payload”:在它们上面唯一性是不强制的,并且该索引不能基于这些列搜索。
然而它们可以通过一个仅对索引的扫描检索。
请注意虽然约束在包含的列上是非强制的,但是它仍然依赖于它们。
因此,这样的列上的某些操作(例如DROP COLUMN
)可能会导致级联约束和索引删除。
PRIMARY KEY
(列约束)PRIMARY KEY ( column_name
[, ... ] )
[ INCLUDE ( column_name
[, ...])
] (表约束)
PRIMARY KEY
约束指定表的一个或者多个列只能包含唯一(不重复)、非空的值。一个表上只能指定一个主键,可以作为列约束或表约束。
主键约束所涉及的列集合应该不同于同一个表上定义的任何唯一约束的列集合(否则,该唯一约束是多余的并且会被丢弃)。
PRIMARY KEY
强制的数据约束可以看成是UNIQUE
和NOT NULL
的组合,
然而,把一组列标识为主键也为模式设计提供了元数据,因为主键标识其他表可以依赖这一个列集合作为行的唯一标识符。
当放到分区表上时,PRIMARY KEY
约束共享前面描述的UNIQUE
约束的限制。
添加PRIMARY KEY
约束将自动在用于约束的列或列组上创建唯一的 btree 索引。
可选 INCLUDE
子句向该索引添加一个或多个列是简单的“payload”:唯一性对它们是非强制的,并且该索引不能基于这些列搜索。
然而它们可以通过一个仅对索引的扫描检索。
注意虽然包含的列的约束的唯一性是非强制的,但仍依赖于它们。
因此,这样的列上的某些操作(例如DROP COLUMN
)可能会导致级联约束和索引删除。
EXCLUDE [ USING index_method
] ( exclude_element
WITH operator
[, ... ] ) index_parameters
[ WHERE ( predicate
) ]
EXCLUDE
子句定一个排除约束,它保证如果任意两行在指定列或表达式上使用指定操作符进行比较,不是所有的比较都将会返回TRUE
。如果所有指定的操作符都测试相等,这就等价于一个UNIQUE
约束,尽管一个普通的唯一约束将更快。不过,排除约束能够指定比简单相等更通用的约束。例如,你可以使用&&
操作符指定一个约束,要求表中没有两行包含相互覆盖的圆(见 第 8.8 节)。
排除约束使用一个索引实现,这样每一个指定的操作符必须与用于索引访问方法index_method
的一个适当的操作符类(见第 11.10 节)相关联。操作符被要求是交换的。每一个exclude_element
可以选择性地指定一个操作符类或者顺序选项,这些在CREATE INDEX中有完整描述。
访问方法必须支持amgettuple
(见第 62 章),目前这意味着GIN无法使用。尽管允许,但是在一个排除约束中使用 B-树或哈希索引没有意义,因为它无法做得比一个普通唯一索引更出色。因此在实践中访问方法将总是GiST或SP-GiST。
predicate
允许你在该表的一个子集上指定一个排除约束。在内部这会创建一个部分索引。注意在为此周围的圆括号是必须的。
REFERENCES reftable
[ ( refcolumn
) ] [ MATCH matchtype
] [ ON DELETE referential_action
] [ ON UPDATE referential_action
]
(column constraint)FOREIGN KEY ( column_name
[, ... ] )
REFERENCES reftable
[ ( refcolumn
[, ... ] ) ]
[ MATCH matchtype
]
[ ON DELETE referential_action
]
[ ON UPDATE referential_action
]
(表约束)
这些子句指定一个外键约束,它要求新表的一列或一个列的组必须只包含能匹配被引用表的某个行在被引用列上的值。
如果refcolumn
列表被忽略,将使用reftable
的主键。
被引用列必须是被引用表中一个非可延迟唯一约束或主键约束的列。
用户必须在被引用的表(或整个表,或特定的引用列)上拥有REFERENCES
权限。
增加的外键约束需要SHARE ROW EXCLUSIVE
锁定引用的表。
注意外键约束不能在临时表和永久表之间定义。
被插入到引用列的一个值会使用给定的匹配类型与被引用表的值进行匹配。
有三种匹配类型:MATCH FULL
、MATCH PARTIAL
以及MATCH SIMPLE
(这是默认值)。
MATCH FULL
将不允许一个多列外键中的一列为空,除非所有外键列都是空;如果它们都是空,则不要求该行在被引用表中有一个匹配。
MATCH SIMPLE
允许任意外键列为空,如果任一为空,则不要求该行在被引用表中有一个匹配。
MATCH PARTIAL
现在还没有被实现(当然,NOT NULL
约束能被应用在引用列上来组织这些情况发生)。
另外,当被引用列中的数据被改变时,在这个表的列中的数据上可以执行特定的动作。ON DELETE
指定当被引用表中一个被引用行被删除时要执行的动作。同样,ON UPDATE
指定当被引用表中一个被引用列被更新为新值时要执行的动作。如果该行被更新,但是被引用列并没有被实际改变,不会做任何动作。除了NO ACTION
检查之外的引用动作不能被延迟,即便该约束被声明为可延迟的。对每一个子句可能有以下动作:
NO ACTION
产生一个错误指示删除或更新将会导致一个外键约束违背。如果该约束被延迟,并且仍存在引用行,这个错误将在约束检查时被产生。这是默认动作。
RESTRICT
产生一个错误指示删除或更新将会导致一个外键约束违背。这个动作与NO ACTION
形同,不过该检查不是可延迟的。
CASCADE
删除任何引用被删除行的行,或者把引用列的值更新为被引用列的新值。
SET NULL
将引用列设置为空。
SET DEFAULT
设置引用列为它们的默认值(如果该默认值非空,在被引用表中必须有一行匹配该默认值,否则该操作将会失败)。
如果被引用列被频繁地更改,最好在引用列上加上一个索引,这样与外键约束相关的引用动作能够更高效地被执行。
DEFERRABLE
NOT DEFERRABLE
这个子句控制该约束是否能被延迟。
一个不可延迟的约束将在每一次命令后立刻被检查。
可延迟约束的检查将被推迟到事务结束时进行(使用SET CONSTRAINTS
命令)。
NOT DEFERRABLE
是默认值。
当前,只有UNIQUE
、PRIMARY KEY
、EXCLUDE
以及REFERENCES
(外键)约束接受这个子句。
NOT NULL
以及CHECK
约束是不可延迟的。
注意在包括ON CONFLICT DO UPDATE
子句的INSERT
语句中,可延迟约束不能被用作冲突裁判者。
INITIALLY IMMEDIATE
INITIALLY DEFERRED
如果一个约束是可延迟的,这个子句指定检查该约束的默认时间。
如果该约束是INITIALLY IMMEDIATE
,它会在每一个语句之后被检查。
这是默认值。
如果该约束是INITIALLY DEFERRED
,它只会在事务结束时被检查。
约束检查时间可以用SET CONSTRAINTS
命令修改。
USING method
此可选子句指定用于存储新表内容的表访问方法;该方法需要的是类型TABLE
的访问方法。详见 第 61 章 。
如果未指定此选项,则为新表选择默认表访问方法。详见default_table_access_method。
WITH ( storage_parameter
[= value
] [, ... ] )
这个子句为一个表或索引指定可选的存储参数,详见Storage Parameters 。
为了向后兼容性,表的WITH
子句还可以包括OIDS=FALSE
以便指定新表的行不应包含 OIDs (对象标识符),OIDS=TRUE
不再受支持。
WITHOUT OIDS
这是向后兼容的语法,用于声明表WITHOUT OIDS
,不再支持创建表WITH OIDS
。
ON COMMIT
临时表在一个事务块结束时的行为由ON COMMIT
控制。三种选项是:
PRESERVE ROWS
在事务结束时不采取特殊的动作。这是默认行为。
DELETE ROWS
在每一个事务块结束时将删除临时表中的所有行。
实质上,在每一次提交时会完成一次自动的TRUNCATE
。
当应用于分区表上时,这不会级联到它的分区。
DROP
在当前事务块结束时将删除临时表。 当在分区表上使用时,这个操作会删除他的分区,而在具有继承子级的表上使用时,它将删除依赖的子级。
TABLESPACE tablespace_name
tablespace_name
是新表要创建于其中的表空间名称。如果没有指定,将参考default_tablespace,或者如果表是临时的则参考temp_tablespaces。
对于分区表,由于表本身不需要存储,指定表空间将 default_tablespace
作为默认表空间覆盖,在未显式指定其他表空间时用于任何新创建的分区。
USING INDEX TABLESPACE tablespace_name
这个子句允许选择与一个UNIQUE
、PRIMARY KEY
或者EXCLUDE
约束相关的索引将被创建在哪个表空间中。如果没有指定,将参考default_tablespace,或者如果表是临时的则参考temp_tablespaces。
WITH
子句能够为表或与一个UNIQUE
、PRIMARY KEY
或者EXCLUDE
约束相关的索引指定存储参数。
用于索引的存储参数已经在CREATE INDEX中介绍过。
当前可用于表的存储参数在下文中列出。
如下文所示,对于很多这类参数,都有一个名字带有toast.
前缀的附加参数,它能被用来控制该表的二级TOAST表(如果存在)的行为(关于 TOAST 详见第 70.2 节)。
如果一个表的参数值被设置但是相应的toast.
参数没有被设置,那么 TOAST 表将使用该表的参数值。
不支持为分区表指定这些参数,但可以为单个叶子分区指定它们。
fillfactor
(integer
)
一个表的填充因子是一个 10 到 100 之间的百分数。100(完全填满)是默认值。当一个较小的填充因子被指定时,INSERT
操作会把表页面只填满到指定的百分比,每个页面上剩余的空间被保留给该页上行的更新。这就让UPDATE
有机会把一行的已更新版本放在与其原始版本相同的页面上,这比把它放在一个不同的页面上效率更高。对于一个项从来不会被更新的表来说,完全填满是最好的选择,但是在更新繁重的表上则较小的填充因子更合适。这个参数不能对 TOAST 表设置。
toast_tuple_target
(integer
)
在我们尝试压缩和/或将长列值移动到TOAST表中之前,toast_tuple_target指定需要的最小元组长度, 也是在toasting开始时尝试减少长度的目标长度。这会影响标记为 External(用于移动)、 Main(用于压缩)或 Extended(用于两者)的列,并且仅适用于新元组。 对现有行没有影响。 这仅影响标记为"外部"或"扩展"的列,并且仅适用于新元数 - 对现有行没有影响。 默认情况下此参数设置为允许每个块至少 4 个元组,默认块大小为 2040 字节。 有效值介于 128 字节和(块大小-标头)之间,默认大小为 8160 字节。 更改此值对于非常短或非常长的行可能没有用处。 请注意默认设置通常接近最佳状态,在某些情况下设置此参数可能会产生负面影响。 不能对TOAST表设置此参数。
parallel_workers
(integer
)
这个参数设置用于辅助并行扫描这个表的工作者数量。 如果没有设置这个参数,系统将基于关系的尺寸来决定一个值。 规划者或使用并行扫描的实用程序选择的工作者数量可能会比较少,例如max_worker_processes的设置较小就是一种可能的原因。
autovacuum_enabled
, toast.autovacuum_enabled
(boolean
)
为一个特定的表启用或者禁用自动清理守护进程。如果为真,自动清理守护进程将遵照第 25.1.6 节中讨论的规则在这个表上执行自动的VACUUM
或者ANALYZE
操作。如果为假,这个表不会被自动清理,不过为了阻止事务 ID 回卷时还是会对它进行自动的清理。有关回卷阻止请见第 25.1.5 节。如果autovacuum参数为假,自动清理守护进程根本就不会运行(除非为了阻止事务 ID 回卷),设置独立的表存储参数也不会覆盖这个设置。因此显式地将这个存储参数设置为true
很少有大的意义,只有设置为false
才更有用。
vacuum_index_cleanup
, toast.vacuum_index_cleanup
(enum
)
当VACUUM
在此表上运行时强制或禁用索引清理。
默认值为AUTO
。
用OFF
,索引清理被禁用,用ON
则被启用,而采用AUTO
,决定被动态做出,每次VACUUM
运行时。
动态行为允许VACUUM
不需要的扫描索引以移除很少的死元组。
强制禁用全部索引清理可以显著加快VACUUM
,但如果表修改很频繁,也可能导致索引严重膨胀。
VACUUM
的INDEX_CLEANUP
参数,如果指定,将覆盖此选项的值。
vacuum_truncate
, toast.vacuum_truncate
(boolean
)
启用或禁用vacuum以尝试截断此表末尾的任何空页。默认值为true
。
如果true
,VACUUM
和autovacuum将执行截断,截断页的磁盘空间将返回到操作系统。
请注意,截断需要 ACCESS EXCLUSIVE
在表上锁定。
VACUUM
的TRUNCATE
参数,如果指定,覆盖此选项的值。
autovacuum_vacuum_threshold
, toast.autovacuum_vacuum_threshold
(integer
)
autovacuum_vacuum_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
)
autovacuum_vacuum_insert_threshold参数对于每个表的值。特殊值-1可用于禁用表上的插入为空。
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
)
vacuum_freeze_min_age参数对于每个表的值。注意自动清理将忽略超过系统范围autovacuum_freeze_max_age参数一半的针对每个表的autovacuum_freeze_min_age
参数。
autovacuum_freeze_max_age
, toast.autovacuum_freeze_max_age
(integer
)
autovacuum_freeze_max_age参数对于每个表的值。注意自动清理将忽略超过系统范围参数(只能被设置得较小)一半的针对每个表的autovacuum_freeze_max_age
参数。
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
)
vacuum_multixact_freeze_min_age参数对于每个表的值。注意自动清理将忽略超过系统范围autovacuum_multixact_freeze_max_age参数一半的针对每个表的autovacuum_multixact_freeze_min_age
参数。
autovacuum_multixact_freeze_max_age
, toast.autovacuum_multixact_freeze_max_age
(integer
)
autovacuum_multixact_freeze_max_age参数对于每个表的值。注意自动清理将忽略超过系统范围参数(只能被设置得较小)一半的针对每个表的autovacuum_multixact_freeze_max_age
参数。
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参数对于每个表的值。
user_catalog_table
(boolean
)
声明该表是一个用于逻辑复制目的的额外的目录表。详见第 49.6.2 节。不能对 TOAST 表设置这个参数。
PostgreSQL为每一个唯一约束和主键约束创建一个索引来强制唯一性。因此,没有必要显式地为主键列创建一个索引(详见CREATE INDEX)。
在当前的实现中,唯一约束和主键不会被继承。这使得继承和唯一约束的组合相当不正常。
一个表不能有超过 1600 列(实际上,由于元组长度限制,有效的限制通常更低)。
创建表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 GENERATED BY DEFAULT AS IDENTITY, name varchar(40) NOT NULL CHECK (name <> '') );
创建有一个二维数组的表:
CREATE TABLE array_int ( 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) );
创建相同的表,指定表和它的唯一索引指定 70% 的填充因子:
CREATE TABLE distributors ( did integer, name varchar(40), UNIQUE(name) WITH (fillfactor=70) ) WITH (fillfactor=70);
创建表circles
,带有一个排除约束阻止任意两个圆重叠:
CREATE TABLE circles ( c circle, EXCLUDE USING gist (c WITH &&) );
在表空间diskvol1
中创建表cinemas
:
CREATE TABLE cinemas ( id serial, name text, location text ) TABLESPACE diskvol1;
创建一个组合类型以及一个类型化的表:
CREATE TYPE employee_type AS (name text, salary numeric); CREATE TABLE employees OF employee_type ( PRIMARY KEY (name), salary WITH OPTIONS DEFAULT 1000 );
创建一个范围分区表:
CREATE TABLE measurement ( logdate date not null, peaktemp int, unitsales int ) PARTITION BY RANGE (logdate);
创建在分区键中具有多个列的范围分区表:
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 TABLE cities ( city_id bigserial not null, name text not null, population bigint ) PARTITION BY LIST (left(lower(name), 1));
建立哈希分区表:
CREATE TABLE orders ( order_id bigint not null, cust_id bigint not null, status text ) PARTITION BY HASH (order_id);
创建范围分区表的分区:
CREATE TABLE measurement_y2016m07 PARTITION OF measurement ( unitsales DEFAULT 0 ) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01');
使用分区键中的多个列创建范围分区表的几个分区:
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 TABLE cities_ab PARTITION OF cities ( CONSTRAINT city_id_nonzero CHECK (city_id != 0) ) FOR VALUES IN ('a', 'b');
创建本身是分区的列表分区表的分区,然后向其添加分区:
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 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 TABLE cities_partdef PARTITION OF cities DEFAULT;
CREATE TABLE
命令遵从SQL标准,除了以下例外。
尽管CREATE TEMPORARY TABLE
的语法很像 SQL 标准的语法,但事实是并不相同。在标准中,临时表只需要被定义一次并且会自动地存在(从空内容开始)于需要它们的每一个会话中。PostgreSQL则要求每一个会话为每一个要用的临时表发出它自己的CREATE TEMPORARY TABLE
命令。这允许不同的会话为不同的目的使用相同的临时表名,而标准的方法约束一个给定临时表名的所有实例都必须具有相同的表结构。
标准中对于临时表行为的定义被广泛地忽略了。PostgreSQL在这一点上的行为和多种其他 SQL 数据库是相似的。
SQL 标准也区分全局和局部临时表,其中一个局部临时表为每一个会话中的每一个 SQL 模块具有一个独立的内容集合,但是它的定义仍然是多个会话共享的。因为PostgreSQL不支持 SQL 模块,这种区别与PostgreSQL无关。
为了兼容性目的,PostgreSQL将在临时表声明中接受GLOBAL
和LOCAL
关键词,但是它们当前没有效果。我们不鼓励使用这些关键词,因为未来版本的PostgreSQL可能采用一种更兼容标准的(对它们含义的)解释。
临时表的ON COMMIT
子句也和 SQL 标准相似,但是有一些不同。如果忽略ON COMMIT
子句,SQL 指定默认行为是ON COMMIT DELETE ROWS
。但是,PostgreSQL中的默认行为是ON COMMIT PRESERVE ROWS
。SQL 中不存在ON COMMIT DROP
选项。
但一个UNIQUE
或PRIMARY KEY
约束是非可延迟的,只要一个行被插入或修改,PostgreSQL就会立即检查唯一性。SQL 标准指出只有在语句结束时才应该强制唯一性。当一个单一命令更新多个键值时,这两者是不同的。要得到兼容标准的行为,将该约束声明为DEFERRABLE
但是不延迟(即INITIALLY IMMEDIATE
)。注意这可能要显著地慢于立即唯一性检查。
SQL 标准指出CHECK
列约束只能引用它们应用到的列,只有CHECK
表约束能够引用多列。PostgreSQL并没有强制这个限制,它同样处理列检查约束和表检查约束。
EXCLUDE
约束
EXCLUDE
约束类型是一种PostgreSQL扩展。
NULL
“约束”
NULL
“约束”(实际上是一个非约束)是一个PostgreSQL对 SQL 标准的扩展,它也被包括(以及对称的NOT NULL
约束)在一些其他的数据库系统中以实现兼容性。因为它是任意列的默认值,它的存在就像噪声一样。
SQL标准规定在包含表或域的模式范围内表和域的约束必须具有唯一的名称。
PostgreSQL是比较宽松的:它只需要约束名称在附加到特定表或域的约束之间是唯一的。
但是,对于基于索引的约束(UNIQUE
,PRIMARY KEY
, and EXCLUDE
constraints),
这个特别的自由度并不存在,因为关联的索引被命名为与约束相同的名称,并且索引名称在相同模式的所有关系中必须是唯一的。
当前,PostgreSQL没有记录NOT NULL
约束的名称,因此它们不受唯一性限制的影响。
这在将来的版本中可能会改变。
通过INHERITS
子句的多继承是一种PostgreSQL的语言扩展。SQL:1999 以及之后的标准使用一种不同的语法和不同的语义定义了单继承。SQL:1999-风格的继承还没有被PostgreSQL。
PostgreSQL允许创建一个没有列的表(例如CREATE TABLE foo();
)。这是一个对于 SQL 标准的扩展,它不允许零列表。零列表本身并不是很有用,但是不允许它们会为ALTER TABLE DROP COLUMN
带来奇怪的特殊情况,因此忽略这种规则限制看起来更加整洁。
PostgreSQL允许一个表拥有多个标识列。
该标准指定一个表最多只能有一个标识列。
这主要是为了给模式更改或迁移提供更大的灵活性。
请注意,INSERT
命令仅支持一个适用于整个语句的覆盖子句,因此不支持具有不同行为的多个标识列。
STORED
选项不是标准,但也用于其他 SQL 实现。 SQL 标准不规定生成列的存储。
LIKE
子句
虽然 SQL 标准中有一个LIKE
子句,但是PostgreSQL接受的很多LIKE
子句选项却不在标准中,并且有些标准中的选项也没有被PostgreSQL实现。
WITH
子句
WITH
子句是一个PostgreSQL扩展,存储参数不在标准中。
PostgreSQL的表空间概念不是标准的一部分。因此,子句TABLESPACE
和USING INDEX TABLESPACE
是扩展。
类型化的表实现了 SQL 标准的一个子集。根据标准,一个类型化的表具有与底层组合类型相对应的列,以及其他的“自引用列”。PostgreSQL不显式支持自引用列。
PARTITION BY
子句
PARTITION BY
子句是PostgreSQL的一个扩展。
PARTITION OF
子句
PARTITION OF
子句PostgreSQL的一个扩展。