CREATE TABLE
CREATE TABLE¶
定义一个新表。
Note: 引用完整性语法(外键约束)被接受但未强制执行。
- 语法
-
``` sql 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] [, … ] ) | 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 [(…)] ) ] ) ] [ ORDER_COLUMNS ( column_name [, … ] ) ]
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] [, … ] ) | WITHOUT OIDS ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACE tablespace_name ] [ ORDER_COLUMNS ( column_name [, … ] ) ]
其中`column_constraint`是: ``` sql [ 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|COMMENTS|CONSTRAINTS|GENERATED|IDENTITY|INDEXES|STATISTICS|STORAGE|COMMENTS|PARTITIONS|ALL}
UNIQUE
和PRIMARY 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
是:appendonly={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_spec
或template_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
是:appendonly={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
权限。如果指定模式名称,SeaboxMPP将在指定的模式中创建表。 否则,SeaboxMPP将在当前模式中创建表。临时表存在于特殊的模式中,因此在创建临时表时不能指定模式名称。
表名称必须与同一模式中的任何其他表,外部表,序列,索引,视图或外部表的名称不同。
CREATE TABLE
还会自动创建一个数据类型,该数据类型表示与表的一行相对应的复合类型。因此,表不能与同一模式中的任何现有数据类型具有相同的名称。可选的约束子句指定新行或更新行必须满足的条件才能成功执行插入或更新操作。 约束是一个SQL对象,可以通过多种方式帮助定义表中的有效值集。约束适用于表,而不适用于分区。 您不能将约束添加到分区或子分区。
引用完整性约束(外键)被接受但不强制执行。 该信息保留在系统catalog中,否则将被忽略。
有两种定义约束的方法:表约束和列约束。 列约束被定义为列定义的一部分。 表约束定义不与特定列绑定,并且可以包含多个列。每个列约束也可以写为表约束。 当约束仅影响一列时,使用列约束只是一种符号上的方便。
创建表时,还有一个附加子句来声明SeaboxMPP数据库分发策略。 如果未提供
DISTRIBUTED BY
,DISTRIBUTED RANDOMLY
或DISTRIBUTED REPLICATED
子句, 则SeaboxMPP数据库将通过使用PRIMARY KEY
(如果表具有一个)或表的第一列作为分发键,向该表分配哈希分发策略。几何或用户定义数据类型的列不符合SeaboxMPP分布键列的要求。如果表中没有符合条件的数据类型的列,则将根据轮询或随机分布来分配行。 为了确保数据在SeaboxMPP数据库系统中的均匀分配,希望选择一个对于每个记录都是唯一的分配键,或者如果不可能,则选择
DISTRIBUTED RANDOMLY
。如果提供了
DISTRIBUTED REPLICATED
子句,则SeaboxMPP数据库会将表的所有行分配给SeaboxMPP数据库系统中的所有executor。如果用户定义的函数必须在executor上执行,并且这些函数需要访问表的所有行,则可以使用此选项。 复制函数还可以用于防止表的broadcast motions,从而提高查询性能。
DISTRIBUTED REPLICATED
子句不能与PARTITION BY
子句或INHERITS
子句一起使用。 复制的表也不能被另一个表继承。隐藏的系统列(
rowid
,ctid
,cmin
,cmax
,xmin
,xmax
和sc_dbindex_id
)无法在复制表的用户查询中引用,因为它们没有单一的,无歧义的值。通过
PARTITION BY
子句,您可以将表分为多个子表(或部分),这些子表一起构成父表并共享其模式。尽管子表作为独立表存在,但是SeaboxMPP数据库以重要方式限制了它们的使用。在内部,分区被实现为继承的一种特殊形式。每个子表分区都是根据不同的CHECK
约束创建的,该约束根据一些定义条件限制表可以包含的数据。查询优化器还使用
CHECK
约束来确定要扫描哪些表分区以满足给定的查询谓词。 这些分区约束由SeaboxMPP数据库自动管理。 - 参数
-
该SQL命令参数说明见下
GLOBAL
|LOCAL
- 提供这些关键字是为了实现SQL标准兼容性,但在SeaboxMPP数据库中无效,并且已弃用。
TEMPORARY
|TEMP
- 如果指定,该表将被创建为临时表。 临时表在会话结束时或在当前事务结束时自动删除(请参见
ON COMMIT
)。临时表存在时,具有相同名称的现有永久表在当前会话中不可见,除非使用模式限定名称引用它们。在临时表上创建的所有索引也会自动成为临时索引。 UNLOGGED
- 如果指定,该表将创建为未记录表。 写入未记录表的数据不会写入预写(WAL)日志,这使它们比普通表快得多。但是,未记录表的内容不会复制到mirror实例。同样,未记录的表也不是崩溃安全的。executor实例崩溃或异常关闭后,该executor上未记录表的数据将被截断。在未记录表上创建的所有索引也会自动成为未记录索引。
table_name
- 要创建的新表的名称(可以由模式指定)。
OF type_name
-
创建一个类型化的表,该表从指定的组合类型(名称可以由模式指定)获取其结构。 类型化的表与其类型相关联。例如,如果删除了类型(使用
DROP TYPE ... CASCADE
),则将删除该表。当一个类型化的表被创建时,列的数据类型由底层的组合类型决定而没有在
CREATE TABLE
命令中直接指定。 但是CREATE TABLE
命令可以对表增加默认值和约束,并且可以指定存储参数。 column_name
- 要在新表中创建的列的名称。
data_type
-
列的数据类型。这可能包括数组说明符。对于包含文本数据的表列,请指定数据类型
VARCHAR
或TEXT
。 不建议指定数据类型CHAR
。在SeaboxMPP数据库中,数据类型
VARCHAR
或TEXT
处理作为有效字符添加到数据(在最后一个非空格字符之后添加的空格字符)的填充,而数据类型CHAR
不处理。 COLLATE collation
COLLATE
子句为该列分配排序规则(该排序规则必须是可排序的数据类型)。 如果未指定,则使用列数据类型的默认排序规则。DEFAULT default_expr
-
DEFAULT
子句为出现在其列定义中的列分配默认数据值。 该值是任何不带变量的表达式(不允许对当前表中的其他列进行子查询和交叉引用)。默认表达式的数据类型必须与列的数据类型匹配。 默认表达式将在未为列指定值的任何插入操作中使用。 如果列没有默认值,则默认值为null。
ENCODING ( storage_directive \[, ...\] )
-
对于列,可选的
ENCODING
子句指定列数据的压缩类型和块大小。该子句仅对列存表有效。
列压缩设置从表级别继承到分区级别再到子分区级别。 最低级别的设置具有优先权。
INHERITS ( parent_table \[, …\])
-
可选的
INHERITS
子句指定一个表列表,新表将从中自动继承所有列。 使用INHERITS
将在新的子表及其父表之间创建持久关系。对父级的模式修改通常也会传播到子级,默认情况下,子级表的数据包含在父级扫描中。在SeaboxMPP数据库中,创建分区表时不使用INHERITS
子句。尽管在分区层次结构中使用了继承的概念,但是使用
PARTITION BY
子句创建了分区表的继承结构。如果一个以上的父表中存在相同的列名,则将报告错误,除非每个父表中的列的数据类型都匹配。如果没有冲突,则将重复的列合并以在新表中形成一个列。如果新表的列名列表包含一个也被继承的列名,则数据类型必须同样与继承的列匹配,并且列定义将合并为一个。
如果新表显式指定了该列的默认值,则该默认值将覆盖该列的继承声明中的所有默认值。否则,为该列指定默认值的所有父项都必须指定相同的默认值,否则将报告错误。
CHECK
约束基本上以与列相同的方式合并:如果多个父表或新表定义包含名称相同的约束,则这些约束必须全部具有相同的校验表达式,否则将报告错误。具有相同名称和表达式的约束将合并为一个副本。 不会考虑在父级中标记为NO INHERIT
的约束。请注意,新表中未命名的CHECK
约束将永远不会被合并,因为将始终为其选择唯一的名称。列
STORAGE
设置也会从父表中复制。 LIKE source_table [like_option ...\]
-
LIKE
子句指定一个表,新表将从该表中自动复制所有列名,其数据类型,非空约束和分发策略。不会复制诸如列存或分区结构之类的存储属性。与INHERITS
不同,新表和原始表在创建完成后完全解耦。仅当指定
INCLUDING DEFAULTS
时,才会复制复制的列定义的默认表达式。默认行为是排除默认表达式,导致新表中复制的列具有空默认值。非空约束始终会复制到新表中。 仅当指定
INCLUDING CONSTRAINTS
时,才会复制CHECK
约束。列约束和表约束之间没有区别。仅在指定
INCLUDING INDEXES
子句的情况下,才会在新表上创建原始表的索引,PRIMARY KEY
和UNIQUE
约束。 不论原始名称如何命名,都会根据默认规则选择新索引和约束的名称。(此行为避免了新索引可能出现的重复名称错误。)除非指定了INCLUDING INDEXES
子句,否则不会在新表上创建原始表上的任何索引。仅当指定了
INCLUDING STORAGE
时,才会复制复制的列定义的STORAGE
设置。默认行为是排除STORAGE
设置,导致新表中复制的列具有特定于类型的默认设置。仅当指定
INCLUDING COMMENTS
时,才会复制复制的列,约束和索引的注释。默认行为是排除注释,导致新表中复制的列和约束没有注释。INCLUDING ALL
是INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING INDEXES INCLUDING STORAGE INCLUDING COMMENTS
的缩写形式. 请注意,与INHERITS
不同,LIKE
复制的列和约束不会与名称相似的列和约束合并。如果显式指定了相同的名称,或者在另一个
LIKE
子句中指定了相同的名称,则将指示错误。LIKE
子句还可用于从视图,外部表或复合类型中复制列。 不适用的选项(例如,从视图INCLUDING INDEXES
)将被忽略。 CONSTRAINT constraint_name
-
列或表约束的可选名称。
如果违反了约束,那么约束名称将出现在错误消息中,因此可以使用约束名称(例如列必须为正)来将有用的约束信息传达给客户端应用程序。(需要双引号指定包含空格的约束名称。)如果未指定约束名称,则系统将生成一个名称。
注意: 指定的
constraint_name
用于约束,但系统生成的唯一名称用于索引名。在某些以前的版本中,提供的名称同时用于约束名称和索引名称。 NULL
|NOT NULL
- 指定是否允许该列包含空值。默认值为
NULL
。 CHECK (expression) \[ NO INHERIT \]
-
CHECK
子句指定一个生成布尔结果的表达式,新的或更新的行必须满足才能使插入或更新操作成功。计算为TRUE
或UNKNOWN
的表达式会成功。如果插入或更新操作的任何行都产生
FALSE
结果,则会引发错误异常,并且插入或更新不会更改数据库。指定为列约束的检查约束应仅引用该列的值,而出现在表约束中的表达式可以引用多个列。标有
NO INHERIT
的约束不会传播到子表。当前,CHECK
表达式不能包含子查询,也不能引用当前行的列以外的变量。 UNIQUE ( column_constraint )
|UNIQUE ( column_name \[, ... \] ) ( table_constraint )
UNIQUE
约束指定表的一组一个或多个列只能包含唯一值。 唯一表约束的行为与列约束的行为相同,但具有跨多个列的附加功能。出于唯一约束的目的,空值不视为相等。 唯一的列必须包含SeaboxMPP分布键的所有列。此外,如果表已分区,则<key>
必须包含分区键中的所有列。 请注意,分区表中的<key>
约束与简单的UNIQUE INDEX
不同。- PRIMARY KEY (
column constraint
) | PRIMARY KEY (column_name
[, … ] ) (table constraint
) -
PRIMARY KEY
约束指定表的一列或多列只能包含唯一(非重复),非null值。只能为一个表指定一个主键,无论是作为列约束还是表约束。要使一个表具有主键,它必须是哈希分布的(不是随机分布的),并且主键(唯一的列)必须包含SeaboxMPP分布键的所有列。
此外,如果表已分区,则
<key>
必须包含分区键中的所有列。请注意,分区表中的
<key>
约束与简单的UNIQUE INDEX
不同。PRIMARY KEY
强制执行与UNIQUE
和NOT NULL
相同的组合数据约束,但是将一组列标识为主键也可以提供有关模式设计的元数据,因为主键标识其他表可以依赖这一个列集合作为行的唯一标识符。 - REFERENCES
reftable
[ (refcolumn
) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ON DELETE | ON UPDATE] [key_action
] FOREIGN KEY (column_name
[, …]) REFERENCES
和FOREIGN KEY
子句指定引用完整性约束(外键约束)。DEFERRABLE
|NOT DEFERRABLE
-
[NOT] DEFERRABLE
子句控制约束是否可以被推迟。 一个不可推迟的约束将在每个命令后立即进行检查。 可以推迟检查约束,直到事务结束(使用[SET CONSTRAINTS
]命令)。 默认值是NOT DEFERRABLE
。当前,只有
UNIQUE
和PRIMARY KEY
约束是可推迟的。NOT NULL
和CHECK
约束不可延迟。REFERENCES
(外键)约束接受此子句,但不强制执行。 INITIALLY IMMEDIATE
|INITIALLY DEFERRED
-
如果约束是可延迟的,则此子句指定检查约束的默认时间。 如果该约束是
INITIALLY IMMEDIATE
,则在每个语句之后对其进行检查。 这是默认值。如果约束是
INITIALLY DEFERRED
,则仅在事务结束时进行检查。 可以使用SET CONSTRAINTS
命令更改约束检查时间。 WITH (storage_parameter=value)
-
WITH
子句可以为表以及与UNIQUE
或PRIMARY
约束关联的索引指定存储参数。请注意,还可以通过在分区规范中声明
WITH
子句来在特定分区或子分区上设置存储参数。最低级别的设置具有优先权。某些表存储选项的默认值可以使用服务器配置参数
sc_default_storage_options
指定。可以使用以下存储选项:
-
appendonly — 设置为
TRUE
可将表创建为列存的表(需与orientation或compresstype联合使用)。如果为FALSE
或未声明,则将表创建为常规堆存储表。非必须参数,只是为了兼容旧版本。 -
blocksize — 设置为表中每个块的大小(以字节为单位)。
blocksize
必须介于8192和2097152字节之间,并且是8192的倍数。默认值为32768。 -
orientation — 设置为
column
以用于列式存储。 -
checksum — 此选项仅对列存表有效。值
TRUE
是默认值,并为列存表启用CRC校验和验证。校验和是在块创建期间计算的,并存储在磁盘上。在块读取期间执行校验和验证。 如果在读取期间计算出的校验和与存储的校验和不匹配,则事务中止。如果将值设置为FALSE
以禁用校验和验证,将不会执行检查表数据是否存在磁盘损坏的操作。 -
compresstype — 设置为
ZLIB
(默认值),ZSTD
,RLE_TYPE
或QUICKLZ
以指定使用的压缩类型。值NONE
禁用压缩。 Zstd提供速度或良好的压缩率,可通过compresslevel
选项进行调整。提供QuickLZ和zlib是为了向后兼容。 在通常的工作负载上,Zstd的性能优于这些压缩类型。当相同的数据值出现在许多连续的行中时,RLE的压缩数据比Zstd,zlib或QuickLZ压缩算法更好。对于BIGINT
,INTEGER
,DATE
,TIME
或TIMESTAMP
类型的列,如果将compresstype
选项设置为RLE_TYPE
压缩,则还将应用增量压缩。增量压缩算法基于连续行中列值之间的增量,旨在改善按排序顺序加载数据或将压缩应用于按排序顺序的列数据时的压缩。 -
compresslevel — 对于列存表的Zstd压缩,请将其设置为1(最快压缩)到19(最高压缩率)之间的整数值。对于zlib压缩,有效范围是1到9。QuickLZ压缩级别只能设置为1。 如果未声明,则默认值为1。对于
RLE_TYPE
,压缩级别可以是1(最快压缩)到4(最高压缩率)之间的整数值。当orientation
=column
或指定compresstype时,compresslevel
选项才有效。 -
fillfactor — 有关此索引存储参数的更多信息,请参见
CREATE INDEX
。 -
oids — 设置为
oids=FALSE
(默认值),以便不为行分配对象标识符。强烈建议在创建表时不要启用OIDS。在大型表上(例如典型的SeaboxMPP数据库系统中的表),对表行使用OID可能会导致32位OID计数器的折回。一旦计数器回绕,就不能再认为OID是唯一的,这不仅使它们对用户应用程序无用,而且还会在SeaboxMPP数据库系统catalog表中引起问题。此外,从表中排除OID会使表每行存储在磁盘上所需的空间减少了每行4个字节,从而略微提高了性能。分区表或列存表上不允许使用OIDS。
-
WITHOUT OIDS
-
等同于
WITH (OIDS=FALSE)
的过时语法。如果希望同时提供OIDS设置和存储参数,则必须使用
WITH ( ... )
语法,如上一个参数说明所示。WITH OIDS
将不再支持。 ON COMMIT
-
可以使用
ON COMMIT
控制事务块末尾的临时表的行为。 这三个选项是:-
PRESERVE ROWS - 临时表的事务结束时不会采取任何特殊操作。这是默认行为。
-
DELETE ROWS - 临时表中的所有行将在每个事务块的末尾删除。 本质上,每次提交都会自动执行一次
TRUNCATE
。 -
DROP - 临时表将在当前事务块的末尾删除。
-
TABLESPACE tablespace
- 要在其中创建新表的表空间的名称。如果未指定,则使用数据库的默认表空间。
USING INDEX TABLESPACE tablespace
- 该子句允许选择将在其中创建与
UNIQUE
或PRIMARY KEY
约束关联的索引的表空间。 如果未指定,则使用数据库的默认表空间。 DISTRIBUTED BY (column \[opclass\], \[ ... \] )
|DISTRIBUTED RANDOMLY
|DISTRIBUTED REPLICATED
-
用于声明表的SeaboxMPP数据库分布策略。
DISTRIBUTED BY
使用具有一个或多个声明为分布键的列的哈希分布。为了获得最均匀的数据分配,分布键应为表的主键或唯一列(或一组列)。如果无法做到这一点,则可以选择
DISTRIBUTED RANDOMLY
,它将数据轮询发送到executor实例。 此外,可以指定运算符类opclass
,以使用非默认哈希函数。如果在创建表时未指定DISTRIBUTED BY子句,则SeaboxMPP数据库服务器配置参数
sc_create_table_random_default_distribution
将控制表默认分布策略。如果未指定分布策略,SeaboxMPP数据库将遵循以下规则来创建表
-
如果参数的值是
off
(默认值),则SeaboxMPP数据库根据以下命令选择表分布键: -
如果指定了
LIKE
或INHERITS
子句,则SeaboxMPP从源表或父表复制分布键。 -
如果指定了
PRIMARY KEY
或UNIQUE
约束,则SeaboxMPP选择所有键列中最大的子集作为分布键。 -
如果既未指定约束,也未指定
LIKE
或INHERITS
子句,则SeaboxMPP选择第一个合适的列作为分布键。(具有几何或用户定义数据类型的列不符合作为SeaboxMPP分布键列的条件。) -
如果参数的值设置为
on
,则SeaboxMPP数据库遵循以下规则: -
如果未指定PRIMARY KEY或UNIQUE列,则表的分布是随机的(DISTRIBUTED RANDOMLY)。即使表创建命令包含LIKE或INHERITS子句,表分布也是随机的。
-
如果指定了PRIMARY KEY或UNIQUE列,则还必须指定DISTRIBUTED BY子句。如果在表创建命令中未指定DISTRIBUTED BY子句,则该命令将失败。
有关设置默认表分布策略的更多信息,请参见[
sc_create_table_random_default_distribution
]配置参数说明。DISTRIBUTED REPLICATED
子句将整个表复制到所有SeaboxMPP数据库executor实例。当函数需要访问表中的所有行或需要通过阻止broadcast motion来提高查询性能时,必须在executor上执行用户定义的函数时可以使用它。
-
PARTITION BY
-
声明用于对表进行分区的一列或多列。建分区表时,SeaboxMPP数据库使用指定的表名创建根分区表(根分区)。
SeaboxMPP数据库还会根据您指定的分区选项创建表,子表的层次结构,这些表是子分区。SeaboxMPP数据库pg_partition*系统视图包含有关子分区表的信息。
对于每个分区级别(表的每个层次结构级别),一个分区表最多可以有32,767个分区。
注意:SeaboxMPP数据库将分区表数据存储在叶子表中,叶子表是子表层次结构中的最低级表,供分区表使用。
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
- 可以选择声明一个用于创建子分区的子分区模板(低级别子表),而不是为每个分区分别声明每个子分区定义。然后,此子分区规范将应用于所有父分区。
ORDER_COLUMNS ( column_name [, ... ] )
ORDER_COLUMNS
指定表的一列或多列作为排序列,最多可以指定8个排序列,排序列不能重复。目前只支持列存表进行指定,分区表主表指定可为所有列存子表指定。
- 注解
-
创建表须注意以下几点: - 在SeaboxMPP数据库(基于Seabox的系统)中,数据类型
VARCHAR
或TEXT
处理填充作为有效字符添加到文本的数据(最后一个非空格字符之后添加空格字符);数据类型CHAR
则没有。在SeaboxMPP数据库中,
CHAR(n)
类型的值用尾随空格填充到指定的宽度n
。 值将存储并显示为空格。但是,填充空格在语义上无关紧要。 分配值时,将忽略尾随空格。比较数据类型CHAR
的两个值时,尾随空格在语义上也无关紧要,而将字符值转换为其他字符串类型之一时,尾随空格也将被删除。-
不建议在新应用程序中使用OID:在可能的情况下,最好使用
SERIAL
或其他序列生成器作为表的主键。但是,如果应用程序确实使用OID来标识表的特定行,则建议在该表的OID列上创建唯一约束,以确保即使在计数器回绕后,表中的OID的确可以唯一地标识行。避免假设OID在表之间是唯一的;如果需要数据库范围的唯一标识符,则可以使用表OID和行OID的组合。 -
SeaboxMPP数据库对于主键和作为SeaboxMPP表中的分布键的列的唯一约束具有一些特殊条件。
为了在SeaboxMPP数据库中实施唯一约束,表必须是哈希分布的(不是
DISTRIBUTED RANDOMLY
), 并且约束列必须与表的分布键列相同(或作为其的超集)。 另外,分布键必须是约束列的左子集,并且列的顺序正确。例如,如果主键是(a,b,c),则分布键只能是以下之一:(a),(a,b)或(a,b,c)。复制表(
DISTRIBUTED REPLICATED
)可以同时具有PRIMARY KEY
和UNIQUE
列约束。主键约束只是唯一约束和非空约束的组合。
SeaboxMPP数据库自动为每个
UNIQUE
或PRIMARY KEY
约束创建一个UNIQUE
索引,以强制执行唯一性。因此,没有必要为主键列显式创建索引。SeaboxMPP数据库中不支持外键约束。
对于继承的表,当前实现中不会继承唯一约束,主键约束,索引和表权限。
-
对于列存表,可重复读或可序列化事务中不允许
UPDATE
和DELETE
,这将导致事务中止。CLUSTER
,DECLARE...FOR UPDATE
和触发器不支持列存表。 -
要将数据插入分区表中,请指定根分区表,即使用
CREATE TABLE
命令创建的表。还可以在INSERT
命令中指定分区表的叶子表。
如果数据对于指定的叶子表无效,则返回错误。 不支持在
INSERT
命令中指定不是叶子表的子表。不支持在分区表的任何子表上执行其他DML命令,例如
UPDATE
和DELETE
。这些命令必须在根分区表(使用CREATE TABLE
命令创建的表)上执行。-
可以使用服务器配置参数
sc_default_storage_option
指定这些表存储选项的默认值。 -
appendonly
-
blocksize
-
checksum
-
compresstype
-
compresslevel
-
orientation
可以为系统,数据库或用户设置默认值。有关设置存储选项的信息,请参阅服务器配置参数
sc_default_storage_options
。- 注意:当前的SeaboxMPP数据库Seabox优化器允许使用具有多列(复合)分区键的列表分区。
-
- 示例
-
在名为
baby
的模式中创建一个名为rank
的表, 并使用rank
,gender
和year
列分发数据:CREATE TABLE baby.rank (id int, rank int, year smallint, gender char(1), count int ) DISTRIBUTED BY (rank, gender, year);
创建表files和表分配器(默认情况下,主键将用作SeaboxMPP分布键):
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 (orientation = column, 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标准中,临时表仅定义一次,并在每个需要它们的会话中自动存在(从空内容开始)。相反,SeaboxMPP数据库要求每个会话为要使用的每个临时表发出自己的
CREATE TEMPORARY TABLE
命令。这允许不同的会话出于不同的目的而使用相同的临时表名称,而标准的方法将给定临时表名称的所有实例约束为具有相同的表结构。
全局和本地临时表之间的标准区别不在SeaboxMPP数据库中。SeaboxMPP数据库将在临时表声明中接受
GLOBAL
和LOCAL
关键字,但它们无效且已弃用。如果省略
ON COMMIT
子句,则SQL标准将默认行为指定为ON COMMIT DELETE ROWS
。但是,SeaboxMPP数据库中的默认行为是ON COMMIT PRESERVE ROWS
。 SQL标准中不存在ON COMMIT DROP
选项。-
Column Check Constraints — SQL标准说,
CHECK
列约束只能引用它们所适用的列。 只有CHECK
表约束可以引用多个列。SeaboxMPP数据库不强制执行此限制;它对待列和表检查约束都一样。 -
NULL Constraint —
NULL
约束是对SQL标准的SeaboxMPP数据库扩展,为了与某些其他数据库系统兼容(以及对称的NOT NULL
约束)。 由于它是任何列的默认值,因此不需要它的存在。 -
Inheritance — 通过
INHERITS
子句的多重继承是SeaboxMPP数据库语言的扩展。SQL:1999及更高版本使用不同的语法和语义定义了单个继承。SeaboxMPP数据库尚不支持SQL:1999样式的继承。 -
Partitioning — 通过
PARTITION BY
子句进行的表分区是SeaboxMPP数据库语言的扩展。 -
Zero-column tables — SeaboxMPP数据库允许创建不包含任何列的表(例如
CREATE TABLE foo();
)。这是SQL标准的扩展,不允许使用零列表。 零列表本身并没有什么用,但是不允许使用零列表在ALTER TABLE DROP COLUMN
时会产生奇怪的特殊情况, 因此SeaboxMPP决定忽略此规范限制。 -
LIKE — 尽管SQL标准中存在
LIKE
子句,但SeaboxMPP数据库接受的许多选项都不在该标准中,并且SeaboxMPP数据库并未实现该标准的某些选项。 -
WITH clause —
WITH
子句是SeaboxMPP数据库扩展。 存储参数和OID都不在标准中。 -
Tablespaces — 表空间的SeaboxMPP数据库概念不是SQL标准的一部分。子句
TABLESPACE
和USING INDEX TABLESPACE
是扩展。 -
Data Distribution — 并行或分布式数据库的SeaboxMPP数据库概念不是SQL标准的一部分。
DISTRIBUTED
子句是扩展。
- Temporary Tables — 在SQL标准中,临时表仅定义一次,并在每个需要它们的会话中自动存在(从空内容开始)。相反,SeaboxMPP数据库要求每个会话为要使用的每个临时表发出自己的
- 相关SQL命令
ALTER TABLE
,DROP TABLE
,CREATE EXTERNAL TABLE
,CREATE TABLE AS