ALTER TABLE

更改一个表的定义。

概要

ALTER TABLE [IF EXISTS] [ONLY] name 
    action [, ... ]

ALTER TABLE [IF EXISTS] [ONLY] name 
    RENAME [COLUMN] column_name TO new_column_name

ALTER TABLE [ IF EXISTS ] [ ONLY ] name 
    RENAME CONSTRAINT constraint_name TO new_constraint_name

ALTER TABLE [IF EXISTS] name 
    RENAME TO new_name

ALTER TABLE [IF EXISTS] name 
    SET SCHEMA new_schema

ALTER TABLE ALL IN TABLESPACE name [ OWNED BY role_name [, ... ] ]
    SET TABLESPACE new_tablespace [ NOWAIT ]

ALTER TABLE [IF EXISTS] name 
    SET (encodechain=new_encodechain)

ALTER TABLE [IF EXISTS] [ONLY] name SET 
     WITH (REORGANIZE=true|false)
   | DISTRIBUTED BY ({column_name [opclass]} [, ... ] )
   | DISTRIBUTED RANDOMLY
   | DISTRIBUTED REPLICATED

ALTER TABLE [IF EXISTS] [ONLY] name SET SEGMENT_SET segment_set_name

ALTER TABLE name
   [ ALTER PARTITION { partition_name | FOR (RANK(number)) 
   | FOR (value) } [...] ]  partition_action 
   partition_action

其中 action 是下列之一:

  ADD [COLUMN] column_name data_type [ DEFAULT default_expr ]
      [column_constraint [ ... ]]
      [ COLLATE collation ]
      [ ENCODING ( storage_directive [,...] ) ]
  DROP [COLUMN] [IF EXISTS] column_name [RESTRICT | CASCADE]
  ALTER [COLUMN] column_name [ SET DATA ] TYPE type [COLLATE collation] [USING expression]
  ALTER [COLUMN] column_name SET DEFAULT expression
  ALTER [COLUMN] column_name DROP DEFAULT
  ALTER [COLUMN] column_name { SET | DROP } NOT NULL
  ALTER [COLUMN] column_name SET STATISTICS integer
  ALTER [COLUMN] column SET ( attribute_option = value [, ... ] )
  ALTER [COLUMN] column RESET ( attribute_option [, ... ] )
  ADD table_constraint [NOT VALID]
  ADD table_constraint_using_index
  VALIDATE CONSTRAINT constraint_name
  DROP CONSTRAINT [IF EXISTS] constraint_name [RESTRICT | CASCADE]
  DISABLE TRIGGER [trigger_name | ALL | USER]
  ENABLE TRIGGER [trigger_name | ALL | USER]
  CLUSTER ON index_name
  SET WITHOUT CLUSTER
  SET WITHOUT OIDS
  SET (storage_parameter = value)
  RESET (storage_parameter [, ... ])
  INHERIT parent_table
  NO INHERIT parent_table
  OF type_name
  NOT OF
  OWNER TO new_owner
  SET TABLESPACE new_tablespace

其中 table_constraint_using_index 是:

  [ CONSTRAINT constraint_name ]
  { UNIQUE | PRIMARY KEY } USING INDEX index_name
  [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]

partition_action 是:

  ALTER DEFAULT PARTITION
  DROP DEFAULT PARTITION [IF EXISTS]
  DROP PARTITION [IF EXISTS] { partition_name | 
      FOR (RANK(number)) | FOR (value) } [CASCADE]
  TRUNCATE DEFAULT PARTITION
  TRUNCATE PARTITION { partition_name | FOR (RANK(number)) | 
      FOR (value) }
  RENAME DEFAULT PARTITION TO new_partition_name
  RENAME PARTITION { partition_name | FOR (RANK(number)) | 
      FOR (value) } TO new_partition_name
  ADD DEFAULT PARTITION name [ ( subpartition_spec ) ]
  ADD PARTITION [partition_name] partition_element
     [ ( subpartition_spec ) ]
  EXCHANGE PARTITION { partition_name | FOR (RANK(number)) | 
       FOR (value) } WITH TABLE table_name
        [ WITH | WITHOUT VALIDATION ]
  EXCHANGE DEFAULT PARTITION WITH TABLE table_name
   [ WITH | WITHOUT VALIDATION ]
  SET SUBPARTITION TEMPLATE (subpartition_spec)
  SPLIT DEFAULT PARTITION
    {  AT (list_value)
     | START([datatype] range_value) [INCLUSIVE | EXCLUSIVE] 
        END([datatype] range_value) [INCLUSIVE | EXCLUSIVE] 
        [[SEGMENT_SET segment_set_name]] }
    [ INTO ( PARTITION new_partition_name, 
             PARTITION default_partition_name ) ]
  SPLIT PARTITION { partition_name | FOR (RANK(number)) | 
     FOR (value) } AT (value) 
    [ INTO (PARTITION partition_name, PARTITION partition_name)] 

其中 partition_element 如下:

    VALUES (list_value [,...] )
  | START ([datatype] 'start_value') [INCLUSIVE | EXCLUSIVE]
     [ END ([datatype] 'end_value') [INCLUSIVE | EXCLUSIVE] ]
  | END ([datatype] 'end_value') [INCLUSIVE | EXCLUSIVE]
[ WITH ( partition_storage_parameter=value [, ... ] ) ]
[ TABLESPACE tablespace ]

其中 subpartition_spec 是:

subpartition_element [, ...]

其中 subpartition_element 是:

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

其中 storage_parameter 是:

   appendoptimized={TRUE|FALSE}
   blocksize={8192-2097152}
   orientation={COLUMN|ROW}
   compresstype={ZLIB|ZSTD|QUICKLZ|RLE_TYPE|NONE|MXCUSTOM}
   // 当 compresstype=MXCUSTOM,需指定具体的 encodechain
   encodechain={LZ4|ZSTD|DELTADELTA(缩放位数)|DELTAZIGZAG|GORILLA|FLOATINT|SIMPLE8B|AUTO}
   /* 当 compresstype=MXCUSTOM,且 encodechain=AUTO 时,支持在表级别指定自适应编码模式:     
    * automode=1 表示压缩率优先,automode=2 表示速度优先 
    */
   automode={1|2}
   compresslevel={0-9}
   fillfactor={10-100}
   oids[FALSE]

描述

ALTER TABLE 更改一个表的定义。下文描述了几种形式:

  • ADD COLUMN — 向表中增加一个新列,使用和 CREATE TABLE相同的语义。ENCODING 子句只有在追加和列存储表中有效
  • DROP COLUMN [IF EXISTS] — 从表中删除列。请注意,如果删除用作 YMatrix 数据库分配键的表列,则表的分配策略将更改为 DISTRIBUTED RANDOMLY。 涉及该列的索引和表约束也会自动删除。如果有表外的任何内容依赖该列(例如视图),则需要指定 CASCADE。 如果指定了 IF EXISTS 且该列不存在,则不会引发任何错误,而是发出通知。
  • IF EXISTS — 如果表不存在,不要抛出错误,而是发出通知。
  • SET DATA TYPE — 此表单更改表的列的数据类型。 请注意,您不能更改用作分发键或分区键的列数据类型。 通过重新解析最初提供的表达式,涉及该列的索引和简单表约束将自动转换为使用新的列类型。可选的 COLLATE 子句为新列指定排序规则,如果省略,则排序规则是新列类型的默认排序规则。可选的 USING 子句指定如何从旧的值计算新的列值。如果省略,则默认转换与从旧数据类型到新数据类型的转换相同。如果没有从旧类型转换为新类型的隐式或赋值,则必须提供 USING 子句。
  • SET/DROP DEFAULT — 设置或删除列的默认值。默认值仅适用于后续的 INSERT 或 UPDATE 命令。它们不会导致表中已有的行发生更改。
  • SET/DROP NOT NULL — 更改是将列标记为允许空值还是拒绝空值。当列不包含空值时,只能使用 SET NOT NULL。
  • SET STATISTICS — 为后续的 ANALYZE 操作设置每个列的统计信息收集目标。可以在 0 到 10000 的范围内设置目标,也可以设置为 -1 以使用系统默认统计信息目标(default_statistics_target)。当设置成 0,则不收集统计信息。
  • SET (attribute_option = value [, ... ])和 RESET (attribute_option [, ...] )
    设置或重置每个属性选项。当前,唯一定义的按属性的选项是 n_distinct,n_distinct_inherited 和 encodechain,前两者覆盖了后续 ANALYZE 操作所做的不同值估计数,encodechain 用于建表后修改表的编码链压缩算法。n_distinct 影响表本身的统计信息,而 n_distinct_inherited 影响表及其继承子级收集的统计信息。当设置为正值时,ANALYZE 将假定该列恰好包含指定数量的不同非空值。当设置为负值(必须大于或等于 -1)时,ANALYZE 将假定列中不同的非空值的数量在表的大小中是线性的;确切的计数应通过将估计的表大小乘以给定数字的绝对值来计算。例如,值 -1 表示该列中的所有值都是不同的,而值 -0.5 表示每个值平均出现两次。当表的大小随时间变化时,这很有用,因为直到查询计划时间才执行表中行数的乘法。将值指定为 0 可恢复为通常估计不同值的数量。
  • ADD table_constraint [NOT VALID] — 使用与 CREATE TABLE 相同的语法向表(不仅仅是分区)添加新约束。 当前仅将 NOT VALID 选项用于外键和 CHECK 约束。 如果约束标记为 NOT VALID,则 YMatrix 数据库将跳过可能冗长的初始检查,以验证表中的所有行均满足约束。 约束将仍然针对后续的插入或更新(即,对于外键而言,除非在引用表中有匹配的行,否则它们将失败;对于外键,除非新行与指定的检查匹配,否则它们将失败) 约束)。 但是,除非使用 VALIDATE CONSTRAINT 选项对其进行验证,否则数据库将不假定该约束对表中的所有行均有效。 创建表时将跳过约束检查,因此 CREATE TABLE 语法不包括此选项。
  • VALIDATE CONSTRAINT — 该形式通过扫描表以确保没有不满足该约束的行,从而验证了以前创建为 NOT VALID 的外键约束。 如果约束已被标记为有效,则什么也不会发生。 将验证与约束的初始创建分开的好处是与约束创建相比,验证对表的锁定更少。
  • ADD table_constraint_using_index — 根据现有的唯一索引将新的 PRIMARY KEY 或 UNIQUE 约束添加到表中。 索引的所有列都将包含在约束中。 索引不能具有表达式列,也不能是部分索引。 另外,它必须是具有默认排序顺序的 b 树索引。 这些限制确保索引等于由常规 ADD PRIMARY KEY 或 ADD UNIQUE 命令建立的索引。对于分区表不支持为存在的唯一索引增加 PRIMARY KEY 或 UNIQUE 约束。如果指定了 PRIMARY KEY,并且索引的列尚未标记为 NOT NULL,则此命令将尝试对每个此类列执行 ALTER COLUMN SET NOT NULL。 这需要全表扫描,以验证列不包含空值。 在所有其他情况下,这是一个快速的操作。如果提供了约束名称,那么索引将被重命名以匹配约束名称。 否则,约束将被命名为与索引相同。执行此命令后,索引将由约束“拥有”,就像使用常规 ADD PRIMARY KEY 或 ADD UNIQUE 命令构建索引一样。 特别是,删除约束将使索引也消失。
    注意:在需要添加新约束而不长时间阻止表更新的情况下,使用现有索引添加约束可能会有所帮助。 为此,请使用 CREATE INDEX CONCURRENTLY 创建索引,然后使用此语法将其安装为正式约束。 请参见下面的示例。
  • DROP CONSTRAINT [IF EXISTS] — 将指定的约束放在表上。 如果指定了 IF EXISTS 且该约束不存在,则不会引发任何错误。 在这种情况下,将发出通知。
  • DISABLE/ENABLE TRIGGER — 禁用或启用属于该表的触发器。 禁用的触发器对于系统仍然是已知的,但是在其触发事件发生时不会执行。 对于延迟的触发器,将在事件发生时而不是在实际执行触发器功能时检查启用状态。 可以禁用或启用由名称指定的单个触发器,或表上的所有触发器,或仅由用户创建的触发器。 禁用或启用约束触发器需要超级用户特权。
    注意:YMatrix 数据库中不支持触发器。 由于 YMatrix 数据库的并行性,触发器通常具有非常有限的功能。
  • CLUSTER ON/SET WITHOUT CLUSTER — 选择或删除默认索引以用于将来的 CLUSTER 操作。 它实际上并没有重新群集表。 请注意,建议不要使用 CLUSTER 对 YMatrix 数据库中的表进行物理重新排序,因为它会花费很长时间。 最好使用 CREATE TABLE AS 重新创建表并按索引列对其进行排序。
    注意:追加优化表不支持 CLUSTER ON。
  • SET WITHOUT OIDS — 从表中删除 OID 系统列。
  • SET ( FILLFACTOR = value) / RESET (FILLFACTOR) — 更改表的填充因子。 表格的填充系数是 10 到 100 之间的百分比。默认值为 100(完全打包)。 当指定较小的填充因子时,INSERT 操作仅将表页面打包到指定的百分比; 每个页面上的剩余空间都保留用于更新该页面上的行。 这样,UPDATE 就有机会将行的更新副本与原始副本放置在同一页面上,这比将其放置在另一页面上更为有效。 对于一个条目从不更新的表,完全打包是最佳选择,但在更新频繁的表中,较小的填充因子是合适的。 请注意,此命令不会立即修改表内容。 您将需要重写表以获得所需的效果。 可以使用 VACUUM 或强制表重写的 ALTER TABLE 形式之一来完成。
  • SET DISTRIBUTED — 更改表的分配策略。 更改哈希分发策略,或更改为复制策略或从复制策略更改将导致表数据在磁盘上进行物理重新分发,这可能会占用大量资源。
  • INHERIT parent_table / NO INHERIT parent_table — 添加或删除目标表作为指定父表的子表。 对父级的查询将包括其子表的记录。 要作为子项添加,目标表必须已经包含与父项相同的所有列(它也可以具有其他列)。 这些列必须具有匹配的数据类型,并且如果它们在父级中具有 NOT NULL 约束,那么它们在子级中也必须具有 NOT NULL 约束。 对于父级的所有 CHECK 约束,还必须有匹配的子表约束,但在父级中标记为不可继承的(即用 ALTER TABLE ... ADD CONSTRAINT ... NO INHERIT 创建)的约束除外。 匹配的所有子表约束均不得标记为不可继承。 当前不考虑 UNIQUE, PRIMARY KEY 和 FOREIGN KEY 约束,但是将来可能会改变。
  • OF type_name — 这种形式将表链接到复合类型,就像 CREATE TABLE OF 已经形成了它一样。 该表的列名和类型列表必须与组合类型的列表完全匹配; oid 系统列的存在可以不同。 该表不得从任何其他表继承。 这些限制确保 CREATE TABLE OF 将允许等效的表定义。
  • NOT OF — 这种形式将类型化表与其类型分离。
  • OWNER — 将表,序列或视图的所有者更改为指定的用户。
  • SET TABLESPACE — 将表的表空间更改为指定的表空间,并将与表关联的数据文件移动到新表空间。表中的索引(如果有)不会移动;但是可以使用其他 SET TABLESPACE 命令分别移动它们。可以使用 ALL IN TABLESPACE 表单移动表空间中当前数据库中的所有表,该表单将锁定所有要先移动的表,然后再移动每个表。此表单还支持 OWNED BY,该操作仅移动指定角色所拥有的表。如果指定了 NOWAIT 选项,则如果该命令无法立即获取所有必需的锁,则该命令将失败。请注意,此命令不会移动系统目录,请根据需要使用 ALTER DATABASE 或显式 ALTER TABLE 调用。 information_schema 关系不视为系统目录的一部分,将被移动。另请参见 CREATE TABLESPACE。如果更改分区表的表空间,则所有子表分区也将移至新表空间。
  • RENAME — 更改表(或索引,序列或视图)的名称,表中单个列的名称或表的约束的名称。 对存储的数据没有影响。 请注意,YMatrix 数据库分布列不能重命名。
  • SET SCHEMA — 将表移到另一个架构。 表列拥有的关联索引,约束和序列也将移动。
  • SET SEGMENT_SET - 修改分区表的 SEGMENT_SET 对象。
  • ALTER PARTITION | DROP PARTITION | RENAME PARTITION | TRUNCATE PARTITION | ADD PARTITION | SPLIT PARTITION | EXCHANGE PARTITION | SET SUBPARTITION TEMPLATE — 更改分区表的结构。 在大多数情况下,您必须遍历父表才能更改其子表分区之一。

注意:如果将分区添加到具有子分区编码的表中,则新分区将继承该子分区的存储指令。

除 RENAME 和 SET SCHEMA 之外,所有作用于单个表的 ALTER TABLE 形式都可以组合成多个更改列表以一起应用。 例如,可以在单个命令中添加几列和/或更改几列的类型。 这对于大型表尤其有用,因为只需要对表进行一次遍历。

您必须拥有该表才能使用 ALTER TABLE。 要更改表的架构或表空间,您还必须对新架构或表空间具有 CREATE 特权。 要将表添加为父表的新子级,您还必须拥有父表。 要更改所有者,您还必须是新拥有角色的直接或间接成员,并且该角色必须对表的架构具有 CREATE 特权。 要添加列或更改列类型或使用 OF 子句,您还必须对数据类型具有 USAGE 特权。 超级用户自动具有这些特权。

注意:如果表具有多个分区,表具有压缩功能或表的块大小很大,则内存使用量会显着增加。 如果与该表关联的关系的数量很大,则这种情况可能会迫使对该表进行的操作使用更多的内存。 例如,如果该表是一个 CO 表并具有大量列,则每个列都是一个关系。 诸如 ALTER TABLE ALTER COLUMN 之类的操作将打开表中的所有列,以分配关联的缓冲区。 如果 CO 表具有 40 列和 100 个分区,并且这些列被压缩并且块大小为 2MB(系统系数为 3),则系统尝试分配 24 GB,即(40 × 100)×(2 × 3)MB 或 24GB。

参数

ONLY

  • 仅对指定的表名执行操作。 如果不使用 ONLY 关键字,则将在命名表以及与该表关联的任何子表分区上执行该操作。
    注意:只允许在父表或子表中添加或删除列,或更改列的类型。 父表及其后代必须始终具有相同的列和类型。

name

  • 要更改的现有表的名称(可能是模式限定的)。 如果 ONLY 指定,则仅更改该表。 如果未指定 ONLY,则更新表及其所有后代表(如果有)。
    注意:约束只能添加到整个表,不能添加到分区。 由于该限制,name 参数只能包含表名,而不能包含分区名。

column_name

  • 新列或现有列的名称。 请注意,YMatrix 数据库分布列必须格外小心。 更改或删除这些列会更改表的分发策略。

new_column_name

  • 现有列的新名称。

new_name

  • 表的新名称。

type

  • 新列的数据类型,或现有列的新数据类型。 如果更改 YMatrix 分布键列的数据类型,则只能将其更改为兼容类型(例如,text 到 varchar 可以,但 text 到 int 则不能)。

table_constraint

  • 表的新表约束。 请注意,YMatrix 数据库当前不支持外键约束。 此外,表仅允许一个唯一约束,并且唯一性必须在 YMatrix 数据库分发键内。

constraint_name

  • 要删除的现有约束的名称。

CASCADE

  • 自动删除依赖于已删除列或约束的对象(例如,引用该列的视图)。

RESTRICT

  • 如果有任何相关对象,则拒绝删除列或约束。 这是默认行为。

trigger_name

  • 要禁用或启用的单个触发器的名称。 请注意,YMatrix 数据库不支持触发器。

ALL

  • 禁用或启用属于该表的所有触发器,包括与约束相关的触发器。 如果任何触发器是内部生成的约束触发器(例如用于实现外键约束或可延迟的唯一性和排除约束的触发器),则这需要超级用户特权。

USER

  • 禁用或启用属于该表的所有触发器,但内部生成的约束触发器(例如用于实现外键约束或可延迟的唯一性和排除约束的触发器除外)除外。

index_name

  • 表应标记为集群的索引名称。 请注意,建议不要使用 CLUSTER 对 YMatrix 数据库中的表进行物理重新排序,因为它会花费很长时间。 最好使用 CREATE TABLE AS 重新创建表并按索引列对其进行排序。

FILLFACTOR

  • 设置表格的填充系数百分比。

value

  • FILLFACTOR 参数的新值,介于 10 到 100 之间的百分比。默认值为 100。

DISTRIBUTED BY ({column_name [opclass]}) | DISTRIBUTED RANDOMLY | DISTRIBUTED REPLICATED

  • 指定表的分布策略。 更改哈希分布策略会导致物理上重新分配表数据,这可能会占用大量资源。 如果声明相同的哈希分配策略或从哈希更改为随机分配,则除非声明 SET WITH (REORGANIZE=true),否则不会重新分配数据。更改为复制的分布策略或从复制的分布策略更改将导致表数据被重新分发。

REORGANIZE=true|false

  • 当哈希分布策略未更改或从哈希更改为随机分布,并且无论如何都希望重新分布数据时,请使用 REORGANIZE=true 。

parent_table

  • 父表要与此表关联或取消关联。

new_owner

  • 表的新所有者的角色名称。

new_tablespace

  • 该表将被移动到的表空间的名称。

new_schema

  • 表将被移动到的模式的名称。

parent_table_name

  • 更改分区表时,顶级父表的名称。

ALTER [DEFAULT] PARTITION

  • 如果要更改的分区比第一级分区深,请使用 ALTER PARTITION 子句指定要更改层次结构中的哪个子分区

DROP [DEFAULT] PARTITION

  • 删除指定的分区。 如果分区具有子分区,则子分区也会自动删除。

TRUNCATE [DEFAULT] PARTITION

  • 截断指定的分区。 如果分区具有子分区,则子分区也会自动被截断。

RENAME [DEFAULT] PARTITION

  • 更改分区的分区名称(而不是关系名称)。 分区表是使用以下命名约定创建的: \<parentname>_\<level>_prt_\<partition_name>。

ADD DEFAULT PARTITION

  • 将默认分区添加到现有分区设计中。 当数据与现有分区不匹配时,会将其插入默认分区。 没有默认分区的分区设计将拒绝与现有分区不匹配的传入行。 必须为默认分区指定名称。

ADD PARTITION

  • partition_element - 使用表(范围或列表)的现有分区类型,定义要添加的新分区的边界。
  • name - 此新分区的名称。
  • VALUES - 对于列表分区,定义分区将包含的值。
  • START - 对于范围分区,定义分区的起始范围值。 默认情况下,起始值为 INCLUSIVE。 例如,如果您声明开始日期为 “2016-01-01”,则分区将包含所有大于或等于 “2016-01-01” 的日期。 通常,START 表达式的数据类型与分区键列的类型相同。 如果不是这种情况,则必须显式转换为预期的数据类型。
  • END - 对于范围分区,定义分区的结束范围值。 默认情况下,最终值为 EXCLUSIVE。 例如,如果您声明结束日期为 “2016-02-01”,则分区将包含所有小于但不等于 “2016-02-01”的日期。 通常, END 表达式的数据类型与分区键列的类型相同。 如果不是这种情况,则必须显式转换为预期的数据类型。
  • WITH - 设置分区的表存储选项。 例如,您可能希望将较旧的分区作为追加优化表,而将较新的分区作为常规堆表。 有关存储选项的说明,请参见 CREATE TABLE。
  • TABLESPACE - 要在其中创建分区的表空间的名称。
  • subpartition_spec - 仅允许在没有子分区模板的情况下创建的分区设计。 声明要添加的新分区的子分区规范。 如果分区表最初是使用子分区模板定义的,则该模板将用于自动生成子分区。
  • SEGMENT_SET - 指定要添加的新分区的 SEGMENT_SET 对象。

EXCHANGE [DEFAULT] PARTITION

  • 将另一个表交换到分区层次结构中,替换为现有分区的位置。 在多级分区设计中,您只能交换最低级别的分区(包含数据的分区)。
  • YMatrix 数据库服务器配置参数 gp_enable_exchange_default_partition 控制 EXCHANGE DEFAULT PARTITION 子句的可用性。 该参数的默认值是 off。 该子句不可用,如果在 ALTER TABLE 命令中指定了该子句,则 YMatrix 数据库将返回错误。
  • 注意:交换默认分区之前,必须确保要交换的表中的数据(新的默认分区)对默认分区有效。 例如,新的默认分区中的数据不得包含在分区表的其他叶子分区中有效的数据。 否则,由 GPORCA 执行的具有交换的默认分区的分区表查询可能会返回错误的结果。
  • WITH TABLE table_name - 您要交换到分区设计中的表的名称。 您可以交换一个表,其中表数据存储在数据库中。 例如,该表是使用 CREATE TABLE 命令创建的。 该表必须具有与父表相同的列数,列顺序,列名,列类型和分发策略。
  • 使用 EXCHANGE PARTITION 子句,您还可以将可读的外部表(使用 CREATE EXTERNAL TABLE 命令创建)交换到分区层次结构中,而不是现有的叶子子分区。 如果您指定了可读的外部表,则还必须指定 WITHOUT VALIDATION 子句,以针对要交换的分区的 CHECK 约束跳过表验证。
  • 如果分区表包含具有检查约束或 NOT NULL 约束的列,则不支持与外部表交换叶子分区。
  • 您无法与复制表交换分区。 不支持将分区与分区表或分区表的子分区交换。
  • WITH | WITHOUT VALIDATION - 验证表中的数据是否与您要交换的分区的 CHECK 约束相匹配。 默认设置是根据 CHECK 约束验证数据。
  • 注意:如果指定 WITHOUT VALIDATION 子句,则必须确保针对现有子叶分区交换的表中的数据对于分区上的 CHECK 约束是有效的。

SET SUBPARTITION TEMPLATE

  • 修改现有分区的子分区模板。 设置新的子分区模板后,所有添加的新分区将具有新的子分区设计(现有分区不会被修改)。

SPLIT DEFAULT PARTITION

  • 分割默认分区。 在多级分区中,只能拆分范围分区,而不能拆分列表分区,并且只能拆分最低级别的默认分区(包含数据的分区)。 拆分默认分区将创建一个包含指定值的新分区,并保留默认分区,其中包含与现有分区不匹配的任何值。
  • AT - 对于列表分区表,指定一个列表值,该值应用作拆分条件。
  • START - 对于范围分区表,指定新分区的起始值。
  • END - 对于范围分区表,指定新分区的结束值。
  • INTO - 允许您为新分区指定名称。 使用 INTO 子句拆分默认分区时,指定的第二个分区名称应始终为现有默认分区的名称。 如果您不知道默认分区的名称,则可以使用 pg_partitions 视图进行查找。

SPLIT PARTITION

  • 将现有分区分为两个分区。 在多级别分区中,只能拆分范围分区,而不能拆分列表分区,并且只能拆分最低级别的分区(包含数据的分区)。
  • AT - 指定一个单一值,该值应用作分割条件。 该分区将分为两个新分区,指定的分割值是后一个分区的起始范围。
  • INTO - 允许用户为分裂创建两个新分区指定名字。

partition_name

  • 给定的分区名称。

FOR (RANK(number))

  • 对于范围分区,分区在范围中的排名。

FOR ('value')

  • 通过声明一个落在分区边界说明中的值来指定一个分区。如果用FOR声明的值匹配一个分区和它的一个子分区(例如,如果值是一个日期并且表先按月分区然后按日分区),那么FOR将在第一个找到匹配的层次上操作(例如,每月的分区)。如果用户的目的是在子分区上操作,则必须按如下的方式声明:ALTER TABLE name ALTER PARTITION FOR ('2016-10-01') DROP PARTITION FOR ('2016-10-01');

注解

ALTER TABLE 命令中指定的表名不能是一个表中的分区名。

在修改或者删除作为 YMatrix 数据库分布键一部分的列时要特别小心,因为这可能会改变表的分布策略。.

YMatrix 数据库当前不支持外键约束。对于要在 YMatrix 数据库中实施的唯一约束,表必须被哈希分布(不能用DISTRIBUTED RANDOMLY),并且所有的分布键列必须和唯一约束列中前部的列相同。

增加 CHECK 或者 NOT NULL 约束要求扫描表以验证现有的行是否符合约束。

当使用 ADD COLUMN 添加列时,表中的所有现有行都使用该列的默认值初始化,如果未指定 DEFAULT 子句,则初始化为 NULL。添加具有非空默认值的列或更改现有列的类型将需要重写整个表和索引。作为例外,如果 USING 子句不更改列的内容,并且旧类型可以强制转换为新类型或新类型不受限制的域,则不需要重写表,但是受影响列上的任何索引都必须仍在重建中。添加或删除系统 oid 列还需要重写整个表。对于大型表,表和索引的重建可能会花费大量时间;并且暂时需要多达两倍的磁盘空间。

您可以在单个 ALTER TABLE 命令中指定多个更改,这些更改将在表上一次传递。

DROP COLUMN 表单不会物理删除列,而只是使它对 SQL 操作不可见。表中随后的插入和更新操作将为该列存储一个空值。因此,删除列很快,但是不会立即减小表的磁盘大小,因为删除的列所占用的空间不会被回收。随着现有行的更新,空间将随着时间的推移而回收。但是,如果删除系统 oid 列,则表将立即被重写。

要强制立即回收被删除的列占用的空间,您可以执行 ALTER TABLE 的一种形式来重写整个表。这将导致重建的每一行,并将删除的列替换为空值。

ALTER TABLE 的重写形式不是 MVCC 安全的。在表重写之后,如果并发事务使用的是在重写发生之前拍摄的快照,则该表将对并发事务显示为空。

SET DATA TYPE 的 USING 选项实际上可以指定涉及该行的旧值的任何表达式。也就是说,它可以引用其他列以及要转换的列。这允许使用 SET DATA TYPE 语法完成非常通用的转换。由于具有这种灵活性,因此 USING 表达式不会应用于列的默认值(如果有);结果可能不是默认值所需的常量表达式。这意味着当没有从旧类型到新类型的隐式或赋值转换时,即使提供了 USING 子句,SET DATA TYPE 也可能无法转换默认值。在这种情况下,请使用 DROP DEFAULT 删除默认值,执行 ALTER TYPE,然后使用 SET DEFAULT 添加合适的新默认值。类似的考虑适用于涉及该列的索引和约束。

如果表已分区或具有任何后代表,则不允许在父表中添加,重命名或更改列的类型或重命名继承的约束,而无需对后代进行相同的操作。这样可以确保后代始终具有与父代匹配的列。

要查看分区表的结构,可以使用视图 pg_partitions。该视图可以帮助您识别您可能要更改的特定分区。

仅当后代不从任何其他父级继承该列并且从未对该列进行独立定义时,递归 DROP COLUMN 操作才会删除后代表的列。非递归 DROP COLUMN(仅 ALTER TABLE ONLY ... DROP COLUMN)从不删除任何后代列,而是将它们标记为独立定义而不是继承。

TRIGGER, CLUSTER, OWNER 和 TABLESPACE 操作永远不会递归到后代表。也就是说,它们始终像指定 ONLY 那样起作用。仅对未标记为 NO INHERIT 的 CHECK 约束重复添加约束。

如果包含已被交换以使用外部表的叶子分区的分区表上的数据没有更改,则支持这些 ALTER PARTITION 操作。否则,将返回错误。

  • Adding or dropping a column.
  • Changing the data type of column.

分区表不支持这些 ALTER PARTITION 操作,该分区表包含已被交换以使用外部表的叶子分区:

  • Setting a subpartition template.
  • Altering the partition properties.
  • Creating a default partition.
  • Setting a distribution policy.
  • Setting or dropping a NOT NULL constraint of column.
  • Adding or dropping constraints.
  • Splitting an external partition.

不允许更改系统目录表的任何部分。

YMatrix 支持建表后利用 SQL 语句再次修改编码链压缩算法

示例

向列中添加列:

ALTER TABLE distributors ADD COLUMN address varchar(30);

重命名现有列:

ALTER TABLE distributors RENAME COLUMN address TO city;

重命名现有表:

ALTER TABLE distributors RENAME TO suppliers;

向列添加非空约束:

ALTER TABLE distributors ALTER COLUMN street SET NOT NULL;

重命名现有约束:

ALTER TABLE distributors RENAME CONSTRAINT zipchk TO zip_check;

向表及其所有子级添加检查约束:

ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK 
(char_length(zipcode) = 5);

要将检查约束仅添加到表而不是其子表,请执行以下操作:

ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5) NO INHERIT;

(检查约束也不会被将来的子代继承。)

从表及其所有子级中删除检查约束:

ALTER TABLE distributors DROP CONSTRAINT zipchk;

仅从一个表中删除检查约束:

ALTER TABLE ONLY distributors DROP CONSTRAINT zipchk;

(对于任何继承 distributors 的子表,检查约束仍然存在。)

将表移动到不同的模式:

ALTER TABLE myschema.distributors SET SCHEMA yourschema;

将表的分发策略更改为已复制:

ALTER TABLE myschema.distributors SET DISTRIBUTED REPLICATED;

修改已创建分区表的 SEGMENT_SET 对象:

## 在三节点集群中创建 SEGMENT_SET 对象 ss1,ss2
CREATE SEGMENT_SET ss1 SEGMENTS('0,2');
CREATE SEGMENT_SET ss2 SEGMENTS('1,2');

## 创建普通表 t1 和分区表 t2
CREATE TABLE t1(a int, b int) DISTRIBUTED BY(a) SEGMENT_SET ss1;
CREATE TABLE t2(a int, b int) DISTRIBUTED BY(a) PARTITION BY RANGE(b) (DEFAULT PARTITION others SEGMENT_SET ss1);

# 修改普通表 t1 的 SEGMENT_SET 对象。
ALTER TABLE t1 SET SEGMENT_SET ss2;

## 修改分区表 t2 的 SEGMENT_SET 对象,t2 所有子分区的 SEGMENT_SET 也会被修改。
ALTER TABLE t2 SET SEGMENT_SET ss2;

只修改某个分区的 SEGMENT_SET:

ALTER TABLE t2_prt_1_others SET SEGMENT_SET ss1;
ALTER TABLE t2 ALTER DEFAULT PARTITION SET SEGMENT_SET ss1;

指定新分区的 SEGMENT_SET 对象:

ALTER TABLE t2 ADD PARTITION START(6) END(10) SEGMENT_SET ss2;

将新分区添加到分区表:

ALTER TABLE sales ADD PARTITION 
            START (date '2017-02-01') INCLUSIVE 
            END (date '2017-03-01') EXCLUSIVE;

向现有分区设计添加默认分区:

ALTER TABLE sales ADD DEFAULT PARTITION other;

重命名分区:

ALTER TABLE sales RENAME PARTITION FOR ('2016-01-01') TO 
jan08;

删除范围序列中的第一个(最旧的)分区:

ALTER TABLE sales DROP PARTITION FOR (RANK(1));

将表交换到用户的分区设计中:

ALTER TABLE sales EXCHANGE PARTITION FOR ('2016-01-01') WITH 
TABLE jan08;

拆分默认分区(现有的默认分区名称 other)为 2017 年 1 月添加新的每月分区:

ALTER TABLE sales SPLIT DEFAULT PARTITION 
START ('2017-01-01') INCLUSIVE 
END ('2017-02-01') EXCLUSIVE 
INTO (PARTITION jan09, PARTITION other);

将每月分区分成两个分区,第一个分区包含日期 1 月 1 日至 15 日,第二个分区包含日期 1 月 16 日至 31 日:

ALTER TABLE sales SPLIT PARTITION FOR ('2016-01-01')
AT ('2016-01-16')
INTO (PARTITION jan081to15, PARTITION jan0816to31);

要重新创建主键约束,而在重建索引时不阻止更新:

CREATE UNIQUE INDEX CONCURRENTLY dist_id_temp_idx ON distributors (dist_id);
ALTER TABLE distributors DROP CONSTRAINT distributors_pkey,
ADD CONSTRAINT distributors_pkey PRIMARY KEY USING INDEX dist_id_temp_idx;

修改表级别压缩算法为自适应编码

ALTER TABLE t SET (encodechain=auto);

兼容性

ADD (不包含 USING INDEX),DROP,SET DEFAULT和 SET DATA TYPE (不包含 USING) 符合 SQL 标准。 其他形式是 SQL 标准的 YMatrix 数据库扩展。 同样,在单个 ALTER TABLE 命令中指定多个操纵的功能也是一种扩展。

ALTER TABLE DROP COLUMN 可用于删除表的唯一列,而保留零列表。 这是 SQL 的扩展,不允许使用零列表。

另见

CREATE TABLEDROP TABLE