CREATE TABLE

CREATE TABLE

定义一个新表。

Note: 引用完整性语法(外键约束)被接受但未强制执行。

概要

CREATE [ [GLOBAL | LOCAL] {TEMPORARY | TEMP } | UNLOGGED] TABLE [IF NOT EXISTS]
    table_name (
    [ { column_name data_type [ COLLATE collation ] [column_constraint [ ... ] ]
[ ENCODING ( storage_directive [, ...] ) ]
    | table_constraint
    | LIKE source_table [ like_option ... ] }
    | [ column_reference_storage_directive [, ...]
    [, ... ]
] )
[ INHERITS ( parent_table [, ... ] ) ]
[ WITH ( storage_parameter [=value] [, ... ] ) 
       | WITH OIDS | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace_name ]
[ DISTRIBUTED BY (column [opclass], [ ... ] ) 
       | DISTRIBUTED RANDOMLY | DISTRIBUTED REPLICATED ]
[ PARTITION BY partition_type (column)
       [ SUBPARTITION BY partition_type (column) ] 
          [ SUBPARTITION TEMPLATE ( template_spec ) ]
       [...]
    ( partition_spec ) 
        | [ SUBPARTITION BY partition_type (column) ]
          [...]
    ( partition_spec
      [ ( subpartition_spec
           [(...)] 
         ) ] 
    ) ]

CREATE [ [GLOBAL | LOCAL] {TEMPORARY | TEMP} | UNLOGGED ] TABLE [IF NOT EXISTS] 
   table_name
    OF type_name [ (
  { column_name WITH OPTIONS [ column_constraint [ ... ] ]
    | table_constraint } 
    [, ... ]
) ]
[ WITH ( storage_parameter [=value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace_name ]

其中column_constraint是:

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

table_constraint是:

[ CONSTRAINT constraint_name ]
{ CHECK ( expression ) [ NO INHERIT ]
  | UNIQUE ( column_name [, ... ] ) index_parameters
  | PRIMARY KEY ( column_name [, ... ] ) index_parameters
  | FOREIGN KEY ( column_name [, ... ] ) 
      REFERENCES reftable [ ( refcolumn [, ... ] ) ]
      [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] 
      [ ON DELETE key_action ] [ ON UPDATE key_action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
like_option是:
{INCLUDING|EXCLUDING} {DEFAULTS|CONSTRAINTS|INDEXES|STORAGE|COMMENTS|ALL}

UNIQUEPRIMARY KEY中的index_parameters约束为:

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

列的storage_directive是:

compresstype={ZLIB|ZSTD|QUICKLZ|RLE_TYPE|NONE}
    [compresslevel={0-9}]
    [blocksize={8192-2097152} ]

表的storage_parameter是:

   appendoptimized={TRUE|FALSE}
   blocksize={8192-2097152}
   orientation={COLUMN|ROW}
   checksum={TRUE|FALSE}
   compresstype={ZLIB|ZSTD|QUICKLZ|RLE_TYPE|NONE}
   compresslevel={0-9}
   fillfactor={10-100}
   oids[=TRUE|FALSE]

key_action是:

    ON DELETE
   | ON UPDATE
   | NO ACTION
   | RESTRICT
   | CASCADE
   | SET NULL
   | SET DEFAULT

partition_type是:

    LIST | RANGE

partition_specification是:

partition_element [, ...]

partition_element是:

   DEFAULT PARTITION
                name
   | [PARTITION name] VALUES (list_value [,...] )
   | [PARTITION name]
      START ([datatype] 'start_value') [INCLUSIVE | EXCLUSIVE]
      [ END ([datatype] 'end_value') [INCLUSIVE | EXCLUSIVE] ]
      [ EVERY ([datatype] [number |INTERVAL] 'interval_value') ]
   | [PARTITION name]
      END ([datatype] 'end_value') [INCLUSIVE | EXCLUSIVE]
      [ EVERY ([datatype] [number |INTERVAL] 'interval_value') ]
[ WITH ( partition_storage_parameter=value [, ... ] ) ]
[ column_reference_storage_directive [, ...] ]
[ TABLESPACE tablespace ]

其中subpartition_spectemplate_spec是:

subpartition_element [, ...]

subpartition_element是:

   DEFAULT SUBPARTITION name
    | [SUBPARTITION name] VALUES (list_value [,...] )
    | [SUBPARTITION name]
       START ([datatype] 'start_value') [INCLUSIVE | EXCLUSIVE]
       [ END ([datatype] 'end_value') [INCLUSIVE | EXCLUSIVE] ]
       [ EVERY ([datatype] [number |INTERVAL] 'interval_value') ]
    | [SUBPARTITION name]
       END ([datatype] 'end_value') [INCLUSIVE | EXCLUSIVE]
       [ EVERY ([datatype] [number |INTERVAL] 'interval_value') ]
[ WITH ( partition_storage_parameter=value [, ... ] ) ]
[ column_reference_storage_directive [, ...] ]
[ TABLESPACE tablespace ]

其中分区的storage_parameter是:

   appendoptimized={TRUE|FALSE}
   blocksize={8192-2097152}
   orientation={COLUMN|ROW}
   checksum={TRUE|FALSE}
   compresstype={ZLIB|ZSTD|QUICKLZ|RLE_TYPE|NONE}
   compresslevel={1-19}
   fillfactor={10-100}
   oids[=TRUE|FALSE]

描述

CREATE TABLE在当前数据库中创建一个最初为空的表。 执行命令的用户拥有该表。

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

如果指定模式名称,Greenplum将在指定的模式中创建表。 否则,Greenplum将在当前模式中创建表。 临时表存在于特殊的模式中,因此在创建临时表时不能指定模式名称。 表名称必须与同一模式中的任何其他表,外部表,序列,索引,视图或外部表的名称不同。

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

可选的约束子句指定新行或更新行必须满足的条件才能成功执行插入或更新操作。 约束是一个SQL对象,可以通过多种方式帮助定义表中的有效值集。 约束适用于表,而不适用于分区。 您不能将约束添加到分区或子分区。

引用完整性约束(外键)被接受但不强制执行。 该信息保留在系统catalog中,否则将被忽略。

有两种定义约束的方法:表约束和列约束。 列约束被定义为列定义的一部分。 表约束定义不与特定列绑定,并且可以包含多个列。 每个列约束也可以写为表约束。 当约束仅影响一列时,使用列约束只是一种符号上的方便。

创建表时,还有一个附加子句来声明Greenplum数据库分发策略。 如果未提供DISTRIBUTED BYDISTRIBUTED RANDOMLYDISTRIBUTED REPLICATED子句, 则Greenplum数据库将通过使用PRIMARY KEY(如果表具有一个)或表的第一列作为分发键,向该表分配哈希分发策略。 几何或用户定义数据类型的列不符合Greenplum分布键列的要求。 如果表中没有符合条件的数据类型的列,则将根据轮询或随机分布来分配行。 为了确保数据在Greenplum数据库系统中的均匀分配, 您希望选择一个对于每个记录都是唯一的分配键,或者如果不可能,则选择DISTRIBUTED RANDOMLY

如果提供了DISTRIBUTED REPLICATED子句,则Greenplum数据库会将表的所有行分配给Greenplum数据库系统中的所有segment。 如果用户定义的函数必须在segment上执行,并且这些函数需要访问表的所有行,则可以使用此选项。 复制函数还可以用于防止表的broadcast motions,从而提高查询性能。 DISTRIBUTED REPLICATED子句不能与PARTITION BY子句或INHERITS子句一起使用。 复制的表也不能被另一个表继承。 隐藏的系统列(ctidcmincmaxxminxmaxgp_segment_id)无法在复制表的用户查询中引用,因为它们没有单一的,无歧义的值。

通过PARTITION BY子句,您可以将表分为多个子表(或部分),这些子表一起构成父表并共享其模式。 尽管子表作为独立表存在,但是Greenplum数据库以重要方式限制了它们的使用。 在内部,分区被实现为继承的一种特殊形式。 每个子表分区都是根据不同的CHECK约束创建的,该约束根据一些定义条件限制表可以包含的数据。 查询优化器还使用CHECK约束来确定要扫描哪些表分区以满足给定的查询谓词。 这些分区约束由Greenplum数据库自动管理。

参数

GLOBAL | LOCAL
提供这些关键字是为了实现SQL标准兼容性,但在Greenplum数据库中无效,并且已弃用。
TEMPORARY | TEMP
如果指定,该表将被创建为临时表。 临时表在会话结束时或在当前事务结束时自动删除(请参见ON COMMIT)。 临时表存在时,具有相同名称的现有永久表在当前会话中不可见,除非使用模式限定名称引用它们。 在临时表上创建的所有索引也会自动成为临时索引。
UNLOGGED
如果指定,该表将创建为未记录表。 写入未记录表的数据不会写入预写(WAL)日志,这使它们比普通表快得多。 但是,未记录表的内容不会复制到mirror实例。 同样,未记录的表也不是崩溃安全的。 segment实例崩溃或异常关闭后,该segment上未记录表的数据将被截断。 在未记录表上创建的所有索引也会自动成为未记录索引。
table_name
要创建的新表的名称(可以由模式指定)。
OF type_name
创建一个类型化的表,该表从指定的组合类型(名称可以由模式指定)获取其结构。 类型化的表与其类型相关联。 例如,如果删除了类型(使用DROP TYPE ... CASCADE),则将删除该表。
当一个类型化的表被创建时,列的数据类型由底层的组合类型决定而没有在CREATE TABLE命令中直接指定。 但是CREATE TABLE命令可以对表增加默认值和约束,并且可以指定存储参数。
column_name
要在新表中创建的列的名称。
data_type
列的数据类型。这可能包括数组说明符。
对于包含文本数据的表列,请指定数据类型VARCHARTEXT。 不建议指定数据类型CHAR。 在Greenplum数据库中,数据类型VARCHARTEXT处理作为有效字符添加到数据 (在最后一个非空格字符之后添加的空格字符)的填充,而数据类型CHAR不处理。 请参阅注解
COLLATE collation
COLLATE子句为该列分配排序规则(该排序规则必须是可排序的数据类型)。 如果未指定,则使用列数据类型的默认排序规则。
Note: 仅当查询中的所有列使用相同的排序规则时,GPORCA才支持排序规则。 如果查询中的列使用不同的排序规则,则Greenplum使用Postgres查询优化器。
DEFAULT default_expr
DEFAULT子句为出现在其列定义中的列分配默认数据值。 该值是任何不带变量的表达式(不允许对当前表中的其他列进行子查询和交叉引用)。 默认表达式的数据类型必须与列的数据类型匹配。 默认表达式将在未为列指定值的任何插入操作中使用。 如果列没有默认值,则默认值为null。
ENCODING ( storage_directive [, ...] )
对于列,可选的ENCODING子句指定列数据的压缩类型和块大小。 有关compresstypecompresslevelblocksize值,请参见storage_options
该子句仅对追加优化的,面向列的表有效。
列压缩设置从表级别继承到分区级别再到子分区级别。 最低级别的设置具有优先权。
INHERITS ( parent_table [, …])
可选的INHERITS子句指定一个表列表,新表将从中自动继承所有列。 使用INHERITS将在新的子表及其父表之间创建持久关系。 对父级的模式修改通常也会传播到子级,默认情况下,子级表的数据包含在父级扫描中。
在Greenplum数据库中,创建分区表时不使用INHERITS子句。 尽管在分区层次结构中使用了继承的概念,但是使用PARTITION BY子句创建了分区表的继承结构。
如果一个以上的父表中存在相同的列名,则将报告错误,除非每个父表中的列的数据类型都匹配。 如果没有冲突,则将重复的列合并以在新表中形成一个列。 如果新表的列名列表包含一个也被继承的列名,则数据类型必须同样与继承的列匹配,并且列定义将合并为一个。 如果新表显式指定了该列的默认值,则该默认值将覆盖该列的继承声明中的所有默认值。 否则,为该列指定默认值的所有父项都必须指定相同的默认值,否则将报告错误。
CHECK约束基本上以与列相同的方式合并: 如果多个父表或新表定义包含名称相同的约束,则这些约束必须全部具有相同的校验表达式,否则将报告错误。 具有相同名称和表达式的约束将合并为一个副本。 不会考虑在父级中标记为NO INHERIT的约束。 请注意,新表中未命名的CHECK约束将永远不会被合并,因为将始终为其选择唯一的名称。
STORAGE设置也会从父表中复制。
LIKE source_table like_option ...]
LIKE子句指定一个表,新表将从该表中自动复制所有列名,其数据类型,非空约束和分发策略。 不会复制诸如追加优化或分区结构之类的存储属性。 与INHERITS不同,新表和原始表在创建完成后完全解耦。
仅当指定INCLUDING DEFAULTS时,才会复制复制的列定义的默认表达式。 默认行为是排除默认表达式,导致新表中复制的列具有空默认值。
非空约束始终会复制到新表中。 仅当指定INCLUDING CONSTRAINTS时,才会复制CHECK约束。 列约束和表约束之间没有区别。
仅在指定INCLUDING INDEXES子句的情况下,才会在新表上创建原始表的索引, PRIMARY KEYUNIQUE约束。 不论原始名称如何命名,都会根据默认规则选择新索引和约束的名称。 (此行为避免了新索引可能出现的重复名称错误。)
除非指定了INCLUDING INDEXES子句,否则不会在新表上创建原始表上的任何索引。
仅当指定了INCLUDING STORAGE时,才会复制复制的列定义的STORAGE设置。 默认行为是排除STORAGE设置,导致新表中复制的列具有特定于类型的默认设置。
仅当指定INCLUDING COMMENTS时,才会复制复制的列,约束和索引的注释。 默认行为是排除注释,导致新表中复制的列和约束没有注释。
INCLUDING ALLINCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING INDEXES INCLUDING STORAGE INCLUDING COMMENTS的缩写形式.
请注意,与INHERITS不同,LIKE复制的列和约束不会与名称相似的列和约束合并。 如果显式指定了相同的名称,或者在另一个LIKE子句中指定了相同的名称,则将指示错误。
LIKE子句还可用于从视图,外部表或复合类型中复制列。 不适用的选项(例如,从视图INCLUDING INDEXES)将被忽略。
CONSTRAINT constraint_name
列或表约束的可选名称。 如果违反了约束,那么约束名称将出现在错误消息中,因此可以使用约束名称(例如列必须为正)来将有用的约束信息传达给客户端应用程序。 (需要双引号指定包含空格的约束名称。)如果未指定约束名称,则系统将生成一个名称。
Note: 指定的constraint_name用于约束,但系统生成的唯一名称用于索引名。 在某些以前的版本中,提供的名称同时用于约束名称和索引名称。
NULL | NOT NULL
指定是否允许该列包含空值。默认值为NULL
CHECK (expression) [ NO INHERIT ]
CHECK子句指定一个生成布尔结果的表达式,新的或更新的行必须满足才能使插入或更新操作成功。 计算为TRUEUNKNOWN的表达式会成功。 如果插入或更新操作的任何行都产生FALSE结果,则会引发错误异常,并且插入或更新不会更改数据库。 指定为列约束的检查约束应仅引用该列的值,而出现在表约束中的表达式可以引用多个列。
标有NO INHERIT的约束不会传播到子表。
当前,CHECK表达式不能包含子查询,也不能引用当前行的列以外的变量。
UNIQUE ( column_constraint )
UNIQUE ( column_name [, ... ] ) ( table_constraint )
UNIQUE约束指定表的一组一个或多个列只能包含唯一值。 唯一表约束的行为与列约束的行为相同,但具有跨多个列的附加功能。 出于唯一约束的目的,空值不视为相等。 唯一的列必须包含Greenplum分布键的所有列。 此外,如果表已分区,则<key>必须包含分区键中的所有列。 请注意,分区表中的<key>约束与简单的UNIQUE INDEX不同。
有关唯一约束管理和限制的信息,请参见注解
PRIMARY KEY ( column constraint )
PRIMARY KEY ( column_name [, ... ] ) ( table constraint )
PRIMARY KEY约束指定表的一列或多列只能包含唯一(非重复),非null值。 只能为一个表指定一个主键,无论是作为列约束还是表约束。
要使一个表具有主键,它必须是哈希分布的(不是随机分布的),并且主键(唯一的列)必须包含Greenplum分布键的所有列。 此外,如果表已分区,则<key>必须包含分区键中的所有列。 请注意,分区表中的<key>约束与简单的UNIQUE INDEX不同。
PRIMARY KEY强制执行与UNIQUENOT NULL相同的组合数据约束, 但是将一组列标识为主键也可以提供有关模式设计的元数据,因为主键标识其他表可以依赖这一个列集合作为行的唯一标识符。
有关主键管理和限制的信息,请参阅注解
REFERENCES reftable [ ( refcolumn ) ]
[ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
[ON DELETE | ON UPDATE] [key_action]
FOREIGN KEY (column_name [, ...])
REFERENCESFOREIGN KEY子句指定引用完整性约束(外键约束)。 Greenplum接受PostgreSQL语法中指定的参照完整性约束,但不强制执行。 有关引用完整性约束的信息,请参见PostgreSQL文档。
DEFERRABLE
NOT DEFERRABLE
[NOT] DEFERRABLE子句控制约束是否可以被推迟。 一个不可推迟的约束将在每个命令后立即进行检查。 可以推迟检查约束,直到事务结束(使用SET CONSTRAINTS命令)。 默认值是NOT DEFERRABLE。 当前,只有UNIQUEPRIMARY KEY约束是可推迟的。 NOT NULLCHECK约束不可延迟。 REFERENCES(外键)约束接受此子句,但不强制执行。
INITIALLY IMMEDIATE
INITIALLY DEFERRED
如果约束是可延迟的,则此子句指定检查约束的默认时间。 如果该约束是INITIALLY IMMEDIATE,则在每个语句之后对其进行检查。 这是默认值。 如果约束是INITIALLY DEFERRED,则仅在事务结束时进行检查。 可以使用SET CONSTRAINTS命令更改约束检查时间。
WITH ( storage_parameter=value )
WITH子句可以为表以及与UNIQUEPRIMARY约束关联的索引指定存储参数。 请注意,您还可以通过在分区规范中声明WITH子句来在特定分区或子分区上设置存储参数。 最低级别的设置具有优先权。
某些表存储选项的默认值可以使用服务器配置参数gp_default_storage_options指定。 有关设置默认存储选项的信息,请参阅注解
可以使用以下存储选项:
appendoptimized — 设置为TRUE可将表创建为追加优化的表。 如果为FALSE或未声明,则将表创建为常规堆存储表。
blocksize — 设置为表中每个块的大小(以字节为单位)。 blocksize必须介于8192和2097152字节之间,并且是8192的倍数。默认值为32768。
orientation — 设置为column以用于列式存储,或设置为row(默认)以用于行式存储。 仅当appendoptimized=TRUE时,此选项才有效。堆存储表只能是面向行的。
checksum — 此选项仅对追加优化的表(appendoptimized=TRUE)有效。 值TRUE是默认值,并为追加优化表启用CRC校验和验证。 校验和是在块创建期间计算的,并存储在磁盘上。 在块读取期间执行校验和验证。 如果在读取期间计算出的校验和与存储的校验和不匹配,则事务中止。 如果将值设置为FALSE以禁用校验和验证,将不会执行检查表数据是否存在磁盘损坏的操作。
compresstype — 设置为ZLIB(默认值),ZSTDRLE_TYPEQUICKLZ1以指定使用的压缩类型。 值NONE禁用压缩。 Zstd提供速度或良好的压缩率,可通过compresslevel选项进行调整。 提供QuickLZ和zlib是为了向后兼容。 在通常的工作负载上,Zstd的性能优于这些压缩类型。 仅当appendoptimized=TRUE时,compresstype选项才有效。
Note: 注意:1QuickLZ压缩仅在商业版本的Pivotal Greenplum数据库中可用。

仅当指定了orientation=column时才支持值RLE_TYPE,它启用游程编码(RLE)压缩算法。 当相同的数据值出现在许多连续的行中时,RLE的压缩数据比Zstd,zlib或QuickLZ压缩算法更好。

对于BIGINTINTEGERDATETIMETIMESTAMP类型的列,如果将compresstype选项设置为RLE_TYPE压缩,则还将应用增量压缩。 增量压缩算法基于连续行中列值之间的增量,旨在改善按排序顺序加载数据或将压缩应用于按排序顺序的列数据时的压缩。

有关使用表压缩的信息,请参阅Greenplum数据库管理员指南中的“选择表存储模型”。

compresslevel — 对于追加优化表的Zstd压缩,请将其设置为1(最快压缩)到19(最高压缩率)之间的整数值。 对于zlib压缩,有效范围是1到9。QuickLZ压缩级别只能设置为1。 如果未声明,则默认值为1。 对于RLE_TYPE,压缩级别可以是1(最快压缩)到4(最高压缩率)之间的整数值。
仅当appendoptimized=TRUE时,compresslevel选项才有效。
fillfactor — 有关此索引存储参数的更多信息,请参见CREATE INDEX
oids — 设置为oids=FALSE(默认值),以便不为行分配对象标识符。 Greenplum强烈建议您在创建表时不要启用OIDS。 在大型表上(例如典型的Greenplum数据库系统中的表),对表行使用OID可能会导致32位OID计数器的折回。 一旦计数器回绕,就不能再认为OID是唯一的,这不仅使它们对用户应用程序无用, 而且还会在Greenplum数据库系统catalog表中引起问题。 此外,从表中排除OID会使表每行存储在磁盘上所需的空间减少了每行4个字节,从而略微提高了性能。 分区表或追加优化的面向列的表上不允许使用OIDS。
WITH OIDS
WITHOUT OIDS
它们是分别等同于WITH (OIDS)WITH (OIDS=FALSE)的过时语法。 如果希望同时提供OIDS设置和存储参数,则必须使用WITH ( ... )语法;往上看。 Greenplum强烈建议您在创建表时不要启用OIDS。 有关使用oids的更多信息,请参见oids参数说明。
ON COMMIT
可以使用ON COMMIT控制事务块末尾的临时表的行为。 这三个选项是:
PRESERVE ROWS - 临时表的事务结束时不会采取任何特殊操作。这是默认行为。
DELETE ROWS - 临时表中的所有行将在每个事务块的末尾删除。 本质上,每次提交都会自动执行一次TRUNCATE
DROP - 临时表将在当前事务块的末尾删除。
TABLESPACE tablespace
要在其中创建新表的表空间的名称。如果未指定,则使用数据库的默认表空间。
USING INDEX TABLESPACE tablespace
该子句允许选择将在其中创建与UNIQUEPRIMARY KEY约束关联的索引的表空间。 如果未指定,则使用数据库的默认表空间。
DISTRIBUTED BY (column [opclass], [ ... ] )
DISTRIBUTED RANDOMLY
DISTRIBUTED REPLICATED
用于声明表的Greenplum数据库分布策略。 DISTRIBUTED BY使用具有一个或多个声明为分布键的列的哈希分布。 为了获得最均匀的数据分配,分布键应为表的主键或唯一列(或一组列)。 如果无法做到这一点,则可以选择DISTRIBUTED RANDOMLY,它将数据轮询发送到segment实例。 此外,可以指定运算符类opclass,以使用非默认哈希函数。
如果在创建表时未指定DISTRIBUTED BY子句, 则Greenplum数据库服务器配置参数gp_create_table_random_default_distribution将控制表默认分布策略。 如果未指定分布策略,Greenplum数据库将遵循以下规则来创建表。
如果参数的值是off(默认值),则Greenplum数据库根据以下命令选择表分布键:
  • 如果指定了LIKEINHERITS子句,则Greenplum从源表或父表复制分布键。
  • 如果指定了PRIMARY KEYUNIQUE约束,则Greenplum选择所有键列中最大的子集作为分布键。
  • 如果既未指定约束,也未指定LIKEINHERITS子句,则Greenplum选择第一个合适的列作为分布键。 (具有几何或用户定义数据类型的列不符合作为Greenplum分布键列的条件。)
如果参数的值设置为on,则Greenplum数据库遵循以下规则:
  • 如果未指定PRIMARY KEYUNIQUE列, 则表的分布是随机的(DISTRIBUTED RANDOMLY)。 即使表创建命令包含LIKEINHERITS子句,表分布也是随机的。
  • 如果指定了PRIMARY KEYUNIQUE列,则还必须指定DISTRIBUTED BY子句。 如果在表创建命令中未指定DISTRIBUTED BY子句,则该命令将失败。
有关设置默认表分布策略的更多信息, 请参见gp_create_table_random_default_distribution
DISTRIBUTED REPLICATED子句将整个表复制到所有Greenplum数据库segment实例。 当函数需要访问表中的所有行或需要通过阻止broadcast motion来提高查询性能时,必须在segment上执行用户定义的函数时可以使用它。
PARTITION BY
声明用于对表进行分区的一列或多列。
创建分区表时,Greenplum数据库使用指定的表名创建根分区表(根分区)。 Greenplum数据库还会根据您指定的分区选项创建表,子表的层次结构,这些表是子分区。 Greenplum数据库pg_partition*系统视图包含有关子分区表的信息。
对于每个分区级别(表的每个层次结构级别),一个分区表最多可以有32,767个分区。
Note: Greenplum数据库将分区表数据存储在叶子表中,叶子表是子表层次结构中的最低级表,供分区表使用。
partition_type
声明分区类型:LIST(值列表)或RANGE(数字或日期范围)。
partition_specification
声明要创建的各个分区。 可以单独定义每个分区,或者对于范围分区,可以使用EVERY子句(带有START和可选END子句)来定义用于创建单个分区的增量模式。
DEFAULT PARTITION name — 声明默认分区。 当数据与现有分区不匹配时,会将其插入默认分区。 没有默认分区的分区设计将拒绝与现有分区不匹配的传入行。
PARTITION name — 声明要用于分区的名称。 使用以下命名约定创建分区:parentname_level#_prt_givenname
VALUES — 对于列表分区,定义分区将包含的值。
START — 对于范围分区,定义分区的起始范围值。 默认情况下,起始值为INCLUSIVE。 例如,如果您声明开始日期为'2016-01-01', 则分区将包含所有大于或等于'2016-01-01'的日期。 通常,START表达式的数据类型与分区键列的类型相同。 如果不是这种情况,则必须显式转换为预期的数据类型。
END — 对于范围分区,定义分区的结束范围值。 默认情况下,结束值为EXCLUSIVE。 例如,如果您声明结束日期为'2016-02-01', 则分区将包含所有小于但不等于'2016-02-01'的日期。 通常,END表达式的数据类型与分区键列的类型相同。 如果不是这种情况,则必须显式转换为预期的数据类型。
EVERY — 对于范围分区,定义如何将值从START递增到END以创建单个分区。 通常,EVERY表达式的数据类型与分区键列的类型相同。 如果不是这种情况,则必须显式转换为预期的数据类型。
WITH — 设置分区的表存储选项。 例如,您可能希望将较旧的分区作为追加优化表,而将较新的分区作为常规堆表。
TABLESPACE — 要在其中创建分区的表空间的名称。
SUBPARTITION BY
声明用于对表的第一级分区进行子分区的一个或多个列。 子分区的规范格式类似于上述分区的规范格式。
SUBPARTITION TEMPLATE
您可以选择声明一个用于创建子分区的子分区模板(低级别子表),而不是为每个分区分别声明每个子分区定义。 然后,此子分区规范将应用于所有父分区。

注解

  • 在Greenplum数据库(基于Postgres的系统)中, 数据类型VARCHARTEXT处理填充作为有效字符添加到文本的数据(最后一个非空格字符之后添加空格字符); 数据类型CHAR则没有。

    在Greenplum数据库中,CHAR(n)类型的值用尾随空格填充到指定的宽度n。 值将存储并显示为空格。 但是,填充空格在语义上无关紧要。 分配值时,将忽略尾随空格。 比较数据类型CHAR的两个值时,尾随空格在语义上也无关紧要, 而将字符值转换为其他字符串类型之一时,尾随空格也将被删除。

  • 不建议在新应用程序中使用OID:在可能的情况下,最好使用SERIAL或其他序列生成器作为表的主键。 但是,如果您的应用程序确实使用OID来标识表的特定行, 则建议在该表的OID列上创建唯一约束,以确保即使在计数器回绕后,表中的OID的确可以唯一地标识行。 避免假设OID在表之间是唯一的;如果需要数据库范围的唯一标识符,则可以使用表OID和行OID的组合。
  • Greenplum数据库对于主键和作为Greenplum表中的分布键的列的唯一约束具有一些特殊条件。 为了在Greenplum数据库中实施唯一约束,表必须是哈希分布的(不是DISTRIBUTED RANDOMLY), 并且约束列必须与表的分布键列相同(或作为其的超集)。 另外,分布键必须是约束列的左子集,并且列的顺序正确。 例如,如果主键是(a,b,c),则分布键只能是以下之一:(a),(a,b)或(a,b,c)。

    复制表(DISTRIBUTED REPLICATED)可以同时具有PRIMARY KEYUNIQUE列约束。

    主键约束只是唯一约束和非空约束的组合。

    Greenplum数据库自动为每个UNIQUEPRIMARY KEY约束创建一个UNIQUE索引,以强制执行唯一性。 因此,没有必要为主键列显式创建索引。 在追加优化表上不允许使用UNIQUEPRIMARY KEY约束,因为在追加优化表上不允许通过约束创建的UNIQUE索引。

    Greenplum数据库中不支持外键约束。

    对于继承的表,当前实现中不会继承唯一约束,主键约束,索引和表特权。

  • 对于追加优化的表,可重复读或可序列化事务中不允许UPDATEDELETE,这将导致事务中止。 CLUSTERDECLARE...FOR UPDATE和触发器不支持追加优化的表。
  • 要将数据插入分区表中,请指定根分区表,即使用CREATE TABLE命令创建的表。 您还可以在INSERT命令中指定分区表的叶子表。 如果数据对于指定的叶子表无效,则返回错误。 不支持在INSERT命令中指定不是叶子表的子表。 不支持在分区表的任何子表上执行其他DML命令,例如UPDATEDELETE。 这些命令必须在根分区表(使用CREATE TABLE命令创建的表)上执行。
  • 可以使用服务器配置参数gp_default_storage_option指定这些表存储选项的默认值。
    • appendoptimized
    • blocksize
    • checksum
    • compresstype
    • compresslevel
    • orientation

    可以为系统,数据库或用户设置默认值。 有关设置存储选项的信息,请参阅服务器配置参数gp_default_storage_options

Important: 当前的Greenplum数据库Postgres优化器允许使用具有多列(复合)分区键的列表分区。 GPORCA不支持复合键,因此不建议使用复合分区键。

示例

在名为baby的模式中创建一个名为rank的表, 并使用rankgenderyear列分发数据:

CREATE TABLE baby.rank (id int, rank int, year smallint,
gender char(1), count int ) DISTRIBUTED BY (rank, gender,
year);

创建表files和表分配器(默认情况下,主键将用作Greenplum分布键):

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

创建一个gzip压缩的,追加优化的表:

CREATE TABLE sales (txn_id int, qty int, date date) 
WITH (appendoptimized=true, compresslevel=5) 
DISTRIBUTED BY (txn_id);

使用子分区模板和每个级别的默认分区创建一个三级分区表:

CREATE TABLE sales (id int, year int, month int, day int, 
region text)
DISTRIBUTED BY (id)
PARTITION BY RANGE (year)

  SUBPARTITION BY RANGE (month)
    SUBPARTITION TEMPLATE (
       START (1) END (13) EVERY (1), 
       DEFAULT SUBPARTITION other_months )

  SUBPARTITION BY LIST (region)
    SUBPARTITION TEMPLATE (
       SUBPARTITION usa VALUES ('usa'),
       SUBPARTITION europe VALUES ('europe'),
       SUBPARTITION asia VALUES ('asia'),
       DEFAULT SUBPARTITION other_regions)

( START (2008) END (2016) EVERY (1),
  DEFAULT PARTITION outlying_years);

兼容性

CREATE TABLE命令符合SQL标准,但以下情况除外:

  • Temporary Tables — 在SQL标准中,临时表仅定义一次,并在每个需要它们的会话中自动存在(从空内容开始)。 相反,Greenplum数据库要求每个会话为要使用的每个临时表发出自己的CREATE TEMPORARY TABLE命令。 这允许不同的会话出于不同的目的而使用相同的临时表名称,而标准的方法将给定临时表名称的所有实例约束为具有相同的表结构。

    全局和本地临时表之间的标准区别不在Greenplum数据库中。 Greenplum数据库将在临时表声明中接受GLOBALLOCAL关键字,但它们无效且已弃用。

    如果省略ON COMMIT子句,则SQL标准将默认行为指定为ON COMMIT DELETE ROWS。 但是,Greenplum数据库中的默认行为是ON COMMIT PRESERVE ROWS。 SQL标准中不存在ON COMMIT DROP选项。

  • Column Check Constraints — SQL标准说,CHECK列约束只能引用它们所适用的列。 只有CHECK表约束可以引用多个列。 Greenplum数据库不强制执行此限制;它对待列和表检查约束都一样。
  • NULL ConstraintNULL约束是对SQL标准的Greenplum数据库扩展, 为了与某些其他数据库系统兼容(以及对称的NOT NULL约束)。 由于它是任何列的默认值,因此不需要它的存在。
  • Inheritance — 通过INHERITS子句的多重继承是Greenplum数据库语言的扩展。 SQL:1999及更高版本使用不同的语法和语义定义了单个继承。 Greenplum数据库尚不支持SQL:1999样式的继承。
  • Partitioning — 通过PARTITION BY子句进行的表分区是Greenplum数据库语言的扩展。
  • Zero-column tables — Greenplum数据库允许创建不包含任何列的表(例如CREATE TABLE foo();)。 这是SQL标准的扩展,不允许使用零列表。 零列表本身并没有什么用,但是不允许使用零列表在ALTER TABLE DROP COLUMN时会产生奇怪的特殊情况, 因此Greenplum决定忽略此规范限制。
  • LIKE — 尽管SQL标准中存在LIKE子句, 但Greenplum数据库接受的许多选项都不在该标准中,并且Greenplum数据库并未实现该标准的某些选项。
  • WITH clauseWITH子句是Greenplum数据库扩展。 存储参数和OID都不在标准中。
  • Tablespaces — 表空间的Greenplum数据库概念不是SQL标准的一部分。 子句TABLESPACEUSING INDEX TABLESPACE是扩展。
  • Data Distribution — 并行或分布式数据库的Greenplum数据库概念不是SQL标准的一部分。 DISTRIBUTED子句是扩展。