
# ALTER TABLE
#### 功能描述
修改表，包括修改表的定义、重命名表、重命名表中指定的列、重命名表的约束、设置表的所属模式、添加/更新多个列、打开/关闭行访问控制开关。
#### 注意事项
- 表的所有者、被授予了表ALTER权限的用户或被授予ALTER ANY TABLE权限的用户有权限执行ALTER TABLE命令，系统管理员默认拥有此权限。但要修改表的所有者或者修改表的模式，当前用户必须是该表的所有者或者系统管理员，且该用户是新所有者角色的成员。
- 不能修改分区表的TABLESPACE，但可以修改分区的TABLESPACE。
- 不支持修改存储参数ORIENTATION。
- SET SCHEMA操作不支持修改为系统内部模式，当前仅支持用户模式之间的修改。
 
- 不支持增加自增列，或者增加DEFAULT值中包含nextval()表达式的列。
- 不支持对外表、临时表开启行访问控制开关。
- 通过约束名删除PRIMARY KEY约束时，不会删除NOT NULL约束，如果有需要，请手动删除NOT NULL约束。
- 使用JDBC时，支持通过PrepareStatement对DEFAULT值进行参数化设置。
- 如果用ADD COLUMN增加一个字段，那么所有表中现有行都初始化为该字段的缺省值 (如果没有声明DEFAULT子句，那么就是 NULL)。 新增列没有声明DEFAULT值时，默认值为NULL，不会触发全表更新。
  新增列如果有DEFAULT值，必须符合以下所有要求，否则会带来全表更新开销，影响在线业务：
  1. 数据类型为以下类型中的一种：BOOL, BYTEA, SMALLINT, BIGINT, SMALLINT, INTEGER, NUMERIC, FLOAT, DOUBLE PRECISION, CHAR, VARCHAR, TEXT, TIMESTAMPTZ, TIMESTAMP, DATE, TIME, TIMETZ, INTERVAL；
  2. 新增列的DEFAULT值长度不超过128个字节；
  3. 新增列DEFAULT值不包含易变（volatile）函数；
  4. 新增列设置有DEFAULT值，且DEFAULT值不为NULL。
  如果不确定是否满足条件3，可以查询PG_RPOC系统表中函数的provolatile属性是否为'v'。
  
#### 语法格式
- 修改表的定义。
  ```
  ALTER TABLE [ IF EXISTS ] { table_name [*] | ONLY table_name | ONLY ( table_name ) }
      action [, ... ];
  ```
  - 其中列相关的操作column_clause可以是以下子句之一：
    ```
    ADD [ COLUMN ] column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ]    
    | MODIFY column_name data_type    
    | MODIFY column_name [ CONSTRAINT constraint_name ] NOT NULL [ ENABLE ]
    | MODIFY column_name [ CONSTRAINT constraint_name ] NULL
    | DROP [ COLUMN ] [ IF EXISTS ] column_name [ RESTRICT | CASCADE ]    
    | ALTER [ COLUMN ] column_name [ SET DATA ] TYPE data_type [ COLLATE collation ] [ USING expression ]    
    | ALTER [ COLUMN ] column_name { SET DEFAULT expression | DROP DEFAULT }    
    | ALTER [ COLUMN ] column_name { SET | DROP } NOT NULL    
    | ALTER [ COLUMN ] column_name SET STATISTICS [PERCENT] integer    
    | ADD STATISTICS (( column_1_name, column_2_name [, ...] ))    
    | DELETE STATISTICS (( column_1_name, column_2_name [, ...] ))    
    | ALTER [ COLUMN ] column_name SET ( {attribute_option = value} [, ... ] )    
    | ALTER [ COLUMN ] column_name RESET ( attribute_option [, ... ] )    
    | ALTER [ COLUMN ] column_name SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
    ```
    ![](https://support.huaweicloud.com/centralized-devg-v2-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
    - **ADD \[ COLUMN \] column_name data_type \[ COLLATE collation \] \[ column_constraint \[ ... \] \]**
      向表中增加一个新的字段。用ADD COLUMN增加一个字段，所有表中现有行都初始化为该字段的缺省值（如果没有声明DEFAULT子句，值为NULL）。
      
    
    - **ADD ( { column_name data_type } \[, ...\] )**
      向表中增加多列。
      
    
    - **MODIFY ( { column_name data_type \| column_name \[ CONSTRAINT constraint_name \] NOT NULL \[ ENABLE \] \| column_name \[ CONSTRAINT constraint_name \] NULL } \[, ...\] )**
      修改表已存在字段的数据类型。此命令会导致该字段的统计信息清空，建议在修改后重新收集该列的统计信息。
      
    
    - **DROP \[ COLUMN \] \[ IF EXISTS \] column_name \[ RESTRICT \| CASCADE \]**
      从表中删除一个字段，和这个字段相关的索引和表约束也会被自动删除。如果任何表之外的对象依赖于这个字段，必须声明CASCADE ，比如视图。
      DROP COLUMN命令并不是物理上把字段删除，而只是简单地把它标记为对SQL操作不可见。随后对该表的插入和更新将在该字段存储一个NULL。因此，删除一个字段是很快的，但是它不会立即释放表在磁盘上的空间，因为被删除了的字段占据的空间还没有回收。这些空间将在执行VACUUM时而得到回收。
      
    
    - **ALTER \[ COLUMN \] column_name \[ SET DATA \] TYPE data_type \[ COLLATE collation \] \[ USING expression \]**
      改变表字段的数据类型。该字段涉及的索引和简单的表约束将被自动地转换为使用新的字段类型，方法是重新分析最初提供的表达式。
      当字段的原始数据类型和修改后的数据类型二进制兼容时，执行该语句不需要对整表进行重写，其他场景下会进行整表重写。原类型和目标类型是否二进制兼容可以在PG_CAST系统表中查看，如果castmethod为'b'则为二进制兼容。例如源表中数据类型是text类型，如果转为int类型则会触发表重写；转为clob类型则不会触发表重写。如果表重写被触发，该表上被删除的空间也将被立刻回收。
      此命令会导致该字段的统计信息清空，建议在修改后重新收集该列的统计信息。
      
    
    - **ALTER \[ COLUMN \] column_name { SET DEFAULT expression \| DROP DEFAULT }**
      为一个字段设置或者删除缺省值。请注意缺省值只应用于随后的INSERT命令，它们不会修改表中已经存在的行。也可以为视图创建缺省，这个时候它们是在视图的ON INSERT规则应用之前插入到INSERT句中的。
      
    
    - **ALTER \[ COLUMN \] column_name { SET \| DROP } NOT NULL**
      修改一个字段是否允许NULL值或者拒绝NULL值。如果表在字段中包含非NULL，则只能使用SET NOT NULL。
      
    
    - **ALTER \[ COLUMN \] column_name SET STATISTICS \[PERCENT\] integer**
      为随后的ANALYZE操作设置针对每个字段的统计收集目标。目标的范围可以在0到10000之内设置。设置为-1时表示重新恢复到使用系统缺省的统计目标。
      
    
    - **ALTER \[ COLUMN \] column_name SET ( {attribute_option = value} \[, ... \] )**
      **ALTER \[ COLUMN \] column_name RESET ( attribute_option \[, ... \] )**
      设置/重置属性选项。
      目前，属性选项只定义了n_distinct和n_distinct_inherited。n_distinct影响表本身的统计值，而n_distinct_inherited影响表及其继承子表的统计。目前，只支持SET/RESET n_distinct参数，禁止SET/RESET n_distinct_inherited参数。
      
    
    - **ALTER \[ COLUMN \] column_name SET STORAGE { PLAIN \| EXTERNAL \| EXTENDED \| MAIN }**
      为一个字段设置存储模式。这个设置控制这个字段是内联保存还是保存在一个附属的表里，以及数据是否要压缩。仅支持对行存表的设置。SET STORAGE本身并不改变表上的任何东西，只是设置将来的表操作时，建议使用的策略。
      
     
    其中列约束column_constraint为：
    ```
    [ CONSTRAINT constraint_name ]
        { NOT NULL |
          NULL |
          CHECK ( expression ) |
          DEFAULT default_expr  |
          GENERATED ALWAYS AS ( generation_expr ) STORED |
          UNIQUE index_parameters |
          PRIMARY KEY index_parameters |
          REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
              [ ON DELETE action ] [ ON UPDATE action ] }    [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
    ```
    
  
  
  
  - 其中根据已有唯一索引为表增加主键约束或唯一约束table_constraint_using_index为：
    ```
    [ CONSTRAINT constraint_name ]
        { UNIQUE | PRIMARY KEY } USING INDEX index_name
        [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
    ```
    
  
  
  
  - 其中表约束table_constraint为：
    ```
    [ CONSTRAINT constraint_name ]
        { CHECK ( expression ) |
          UNIQUE ( column_name [, ... ] ) index_parameters |
          PRIMARY KEY ( column_name [, ... ] ) index_parameters |
          PARTIAL CLUSTER KEY ( column_name [, ... ]  }
          FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]
             [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] }
        [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
    ```
    其中索引参数index_parameters为：
    ```
    [ WITH ( {storage_parameter = value} [, ... ] ) ]
        [ USING INDEX TABLESPACE tablespace_name ]
    ```
    
   
 
- 重命名表。对名称的修改不会影响所存储的数据。
  ```
  ALTER TABLE [ IF EXISTS ] table_name 
      RENAME TO new_table_name;
  ```
  
- 重命名表中指定的列。
  ```
  ALTER TABLE [ IF EXISTS ] { table_name [*] | ONLY table_name | ONLY ( table_name )}
      RENAME [ COLUMN ] column_name TO new_column_name;
  ```
  
- 重命名表的约束。
  ```
  ALTER TABLE [ IF EXISTS ] { table_name [*] | ONLY table_name | ONLY ( table_name ) }
      RENAME CONSTRAINT constraint_name TO new_constraint_name;
  ```
  
- 设置表的所属模式。
  ```
  ALTER TABLE [ IF EXISTS ] table_name 
      SET SCHEMA new_schema;
  ```
  ![](https://support.huaweicloud.com/centralized-devg-v2-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  - 这种形式把表移动到另外一个模式。相关的索引、约束都跟着移动。目前序列不支持改变schema。 若该表拥有序列，需要将序列删除，重建，或者取消拥有关系， 才能将表schema更改成功。
  
  - 要修改一个表的模式，用户必须在新模式上拥有CREATE权限。要把该表添加为一个父表的新子表，用户必须同时又是父表的所有者。要修改所有者，用户还必须是新的所有角色的直接或间接成员，并且该成员必须在此表的模式上有CREATE权限。这些限制规定了该用户不能做出了重建和删除表之外的事情。不过，系统管理员可以以任何方式修改任意表的所有权限。
  
  - 除了RENAME和SET SCHEMA之外所有动作都可以捆绑在一个经过多次修改的列表中并行使用。比如，可以在一个命令里增加几个字段或修改几个字段的类型。对于大表，此种操作带来的效率提升更明显，原因在于只需要对该大表做一次处理。
  
  - 增加一个CHECK或NOT NULL约束将会扫描该表，以保证现有的行符合约束要求。
  
  - 用一个非空缺省值增加一个字段或者改变一个字段的现有类型会重写整个表。对于大表来说，这个操作可能会花很长时间，并且它还临时需要两倍的磁盘空间。
    
- 添加多个列。
  ```
  ALTER TABLE [ IF EXISTS ] table_name
      ADD ( { column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ]} [, ...] );
  ```
  
- 更新多个列。
  ```
  ALTER TABLE [ IF EXISTS ] table_name 
      MODIFY ( { column_name data_type | column_name [ CONSTRAINT constraint_name ] NOT NULL [ ENABLE ] | column_name [ CONSTRAINT constraint_name ] NULL } [, ...] );
  ```
  
#### 参数说明
- **IF EXISTS**
  如果不存在相同名称的表，不会抛出一个错误，而会发出一个通知，告知表不存在。
  
- **table_name \[\*\] \| ONLY table_name \| ONLY ( table_name )**
  table_name是需要修改的表名。
  若声明了ONLY选项，则只有那个表被更改。若未声明ONLY，该表及其所有子表都将会被更改。另外，可以在表名称后面显示的增加\*选项来指定包括子表，即表示所有后代表都被扫描，这是默认行为。
  
- **constraint_name**
  要删除的现有约束的名称。
  
- **index_name**
  索引名称。
  
- **storage_parameter**
  表的存储参数的名称。
  创建索引新增一个选项：
  - parallel_workers（int类型） 表示创建索引时起的bgworker线程数量，例如2就表示将会起2个bgworker线程并发创建索引。
    取值范围：\[0,32\]，0表示关闭该功能。
    默认值：不设置该参数，表示未开启并行建索引功能。
    
  
  
  
  - hasuids（bool类型） 默认值：off
    参数开启：更新表元组时，为元组分配表级唯一标识id。
    
  
  
  优化器统计信息固化新增一个选项：
  - min_tuples (float8类型） 默认值：0
    优化器基于统计信息估算表数据量大小时会取统计信息估算和该参数的较大值。
    
   
- **new_owner**
  表新拥有者的名称。
  
- **new_tablespace**
  表所属新的表空间名称。
  
- **column_name** ，**column_1_name， column_2_name**
  现存的或新字段的名称。
  
- **data_type**
  新字段的类型，或者现存字段的新类型。
  
- **collation**
  字段排序规则名称。可选字段COLLATE指定了新字段的排序规则，如果省略，排序规则为新字段的默认类型。排序规则可以使用"select \* from pg_collation;"命令从pg_collation系统表中查询，默认的排序规则为查询结果中以default开始的行。
  
- **USING expression**
  USING子句声明如何从旧的字段值里计算新的字段值；如果省略，缺省从旧类型向新类型的赋值转换。如果从旧数据类型到新类型没有隐含或者赋值的转换，则必须提供一个USING子句。
  ![](https://support.huaweicloud.com/centralized-devg-v2-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  ALTER TYPE的USING选项实际上可以声明涉及该行旧值的任何表达式，即它可以引用除了正在被转换的字段之外其他的字段。这样，就可以用ALTER TYPE语法做非常普遍性的转换。因为这个灵活性，USING表达式并没有作用于该字段的缺省值（如果有的话），结果可能不是缺省表达式要求的常量表达式。这就意味着如果从旧类型到新类型没有隐含或者赋值转换的话，即使存在USING子句，ALTER TYPE也可能无法把缺省值转换成新的类型。在这种情况下，应该用DROP DEFAULT先删除缺省，执行ALTER TYPE，然后使用SET DEFAULT增加一个合适的新缺省值。类似的考虑也适用于涉及该字段的索引和约束。
  
- **NOT NULL \| NULL**
  设置列是否允许空值。
  
- **ENABLE**
  表示启动该约束，缺省时默认启用。
  
- **integer**
  带符号的整数常值。当使用PERCENT时表示按照表数据的百分比收集统计信息，integer的取值范围为0-100。
  
- **attribute_option**
  属性选项。
  
- **PLAIN \| EXTERNAL \| EXTENDED \| MAIN**
  字段存储模式。
  - PLAIN必须用于定长的数值（比如integer）并且是内联的、不压缩的。
  
  - MAIN用于内联、可压缩的数据。
  
  - EXTERNAL用于外部保存、不压缩的数据。使用EXTERNAL将令在text和bytea字段上的子字符串操作更快，但付出的代价是增加了存储空间。
  
  - EXTENDED用于外部的压缩数据，EXTENDED是大多数支持非PLAIN存储的数据的缺省。
   
- **CHECK ( expression )**
  每次将要插入的新行或者将要被更新的行必须使表达式结果为真才能成功，否则会抛出一个异常并且不会修改数据库。
  声明为字段约束的检查约束应该只引用该字段的数值，而在表约束里出现的表达式可以引用多个字段。
  目前，CHECK表达式不能包含子查询也不能引用除当前行字段之外的变量。
  
- **DEFAULT default_expr**
  给字段指定缺省值。
  缺省表达式的数据类型必须和字段类型匹配。
  缺省表达式将被用于任何未声明该字段数值的插入操作。如果没有指定缺省值则缺省值为NULL 。
  
- **GENERATED ALWAYS AS ( generation_expr ) STORED**
  该子句将字段创建为生成列，生成列的值在写入（插入或更新）数据时由generation_expr计算得到，STORED表示像普通列一样存储生成列的值。
  ![](https://support.huaweicloud.com/centralized-devg-v2-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  - 生成表达式不能以任何方式引用当前行以外的其他数据。生成表达式不能引用其他生成列，不能引用系统列。生成表达式不能返回结果集，不能使用子查询，不能使用聚集函数，不能使用窗口函数。生成表达式调用的函数只能是不可变（IMMUTABLE）函数。
  
  - 不能为生成列指定默认值。
  
  - 生成列不能作为分区键的一部分。
  
  - 生成列不能和ON UPDATE约束子句的CASCADE,SET NULL,SET DEFAULT动作同时指定。生成列不能和ON DELETE约束子句的SET NULL,SET DEFAULT动作同时指定。
  
  - 修改和删除生成列的方法和普通列相同。删除生成列依赖的普通列，生成列被自动删除。不能改变生成列所依赖的列的类型。
  
  - 生成列不能被直接写入。在INSERT或UPDATE命令中, 不能为生成列指定值, 但是可以指定关键字DEFAULT。
  
  - 生成列的权限控制和普通列一样。
  
  - 内存表MOT不支持生成列。外表中仅postgres_fdw支持生成列。
    
- **UNIQUE index_parameters**
  **UNIQUE ( column_name \[, ... \] ) index_parameters**
  UNIQUE约束表示表里的一个或多个字段的组合必须在全表范围内唯一。
  
- **PRIMARY KEY index_parameters**
  **PRIMARY KEY ( column_name \[, ... \] ) index_parameters**
  主键约束表明表中的一个或者一些字段只能包含唯一（不重复）的非NULL值。
  
- **REFERENCES reftable \[ ( refcolum ) \] \[ MATCH matchtype \] \[ ON DELETE action \] \[ ON UPDATE action \] (column constraint)**
  **FOREIGN KEY ( column_name \[, ... \] ) REFERENCES reftable \[ ( refcolumn \[, ... \] ) \] \[ MATCH matchtype \] \[ ON DELETE action \] \[ ON UPDATE action \] (table constraint)**
  外键约束要求新表中一列或多列构成的组应该只包含、匹配被参考表中被参考字段值。若省略refcolum，则将使用reftable的主键。被参考列应该是被参考表中的唯一字段或主键。外键约束不能被定义在临时表和永久表之间。
  参考字段与被参考字段之间存在三种类型匹配，分别是：
  - MATCH FULL：不允许一个多字段外键的字段为NULL，除非全部外键字段都是NULL。
  
  - MATCH SIMPLE（缺省）：允许任意外键字段为NULL。
  
  - MATCH PARTIAL：目前暂不支持。
  
  
  另外，当被参考表中的数据发生改变时，某些操作也会在新表对应字段的数据上执行。ON DELETE子句声明当被参考表中的被参考行被删除时要执行的操作。ON UPDATE子句声明当被参考表中的被参考字段数据更新时要执行的操作。对于ON DELETE子句、ON UPDATE子句的可能动作：
  - NO ACTION（缺省）：删除或更新时，创建一个表明违反外键约束的错误。若约束可推迟，且若仍存在任何引用行，那这个错误将会在检查约束的时候产生。
  
  - RESTRICT：删除或更新时，创建一个表明违反外键约束的错误。与NO ACTION相同，只是动作不可推迟。
  
  - CASCADE：删除新表中任何引用了被删除行的行，或更新新表中引用行的字段值为被参考字段的新值。
  
  - SET NULL：设置引用字段为NULL。
  
  - SET DEFAULT：设置引用字段为它们的缺省值。
   
- **DEFERRABLE \| NOT DEFERRABLE \| INITIALLY DEFERRED \| INITIALLY IMMEDIATE**
  设置该约束是否可推迟。
  - DEFERRABLE：可以推迟到事务结尾使用SET CONSTRAINTS命令检查。
  
  - NOT DEFERRABLE：在每条命令之后马上检查。
  
  - INITIALLY IMMEDIATE：那么每条语句之后就立即检查它。
  
  - INITIALLY DEFERRED：只有在事务结尾才检查它。
    ![](https://support.huaweicloud.com/centralized-devg-v2-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
    Ustore表不支持新增DEFERRABLE 以及 INITIALLY DEFERRED约束。
    
   
- **WITH ( {storage_parameter = value} \[, ... \] )**
  为表或索引指定一个可选的存储参数。
  
- **tablespace_name**
  索引所在表空间的名称。
  
- **new_table_name**
  修改后新的表名称。
  
- **new_column_name**
  表中指定列修改后新的列名称。
  
- **new_constraint_name**
  修改后表约束的新名称。
  
- **new_schema**
  修改后新的模式名称。
  
- **CASCADE**
  级联删除依赖于被依赖字段或者约束的对象（比如引用该字段的视图）。
  
- **RESTRICT**
  如果字段或者约束还有任何依赖的对象，则拒绝删除该字段。这是缺省行为。
  
- **schema_name**
  表所在的模式名称。
  
 
#### 修改表示例
- **重命名表**
  ```
  openGauss=# CREATE TABLE aa(c1 int, c2 int);
  openGauss=# ALTER TABLE IF EXISTS aa RENAME TO test_alt1;
  ```
  
- **修改表所属模式**
  ```
  --创建模式test_schema。
  openGauss=# CREATE SCHEMA test_schema;
  --把表test_alt1的所属模式修改为test_schema。
  openGauss=# ALTER TABLE test_alt1 SET SCHEMA test_schema;
  --查询表信息。
  openGauss=# SELECT schemaname,tablename FROM pg_tables WHERE tablename = 'test_alt1';
   schemaname  | tablename 
  -------------+-----------
   test_schema | test_alt1
  (1 row)
  ```
  
- **修改表的所有者**
  ```
  --创建用户test_user。
  openGauss=# CREATE USER test_user PASSWORD 'XXXXXXXXXX';
  -- 修改test_alt1表的所有者为test_user;
  openGauss=# ALTER TABLE IF EXISTS test_schema.test_alt1 OWNER TO test_user;
  -- 查看
  openGauss=# SELECT tablename, schemaname, tableowner FROM pg_tables WHERE tablename = 'test_alt1';
   tablename | schemaname  | tableowner 
  -----------+-------------+------------
   test_alt1 | test_schema | test_user
  (1 row)
  ```
  
- **修改表的表空间**
  ```
  --创建表空间tbs_data1。
  openGauss=# CREATE TABLESPACE tbs_data1 RELATIVE LOCATION 'tablespace1/tbs_data1';
  --修改test_alt1表的空间为tbs_data1。
  openGauss=# ALTER TABLE test_schema.test_alt1 SET TABLESPACE tbs_data1;
  -- 查看。
  openGauss=# SELECT tablename, tablespace FROM pg_tables WHERE tablename = 'test_alt1';
   tablename | tablespace 
  -----------+------------
   test_alt1 | tbs_data1
  (1 row)
  --删除。
  openGauss=# DROP TABLE test_schema.test_alt1; 
  openGauss=# DROP TABLESPACE tbs_data1; 
  openGauss=# DROP SCHEMA test_schema; 
  openGauss=# DROP USER test_user;
  ```
  
 
#### 修改列示例
- **修改列名**
  ```
  -- 建表
  openGauss=# CREATE TABLE test_alt2(c1 INT,c2 INT);
  -- 修改列名
  openGauss=# ALTER TABLE test_alt2 RENAME c1 TO id;
  openGauss=# ALTER TABLE test_alt2 RENAME COLUMN c2 to areaid; 
  -- 查看
  openGauss=# \d test_alt1
     Table "public.test_alt1"
   Column |  Type   | Modifiers 
  --------+---------+-----------
   id     | integer | 
   areaid | integer |
  ```
  
- **增加列**
  ```
  -- 表test_alt1增加列
  openGauss=# ALTER TABLE IF EXISTS test_alt2 ADD COLUMN name VARCHAR(20);
  -- 查看
  openGauss=# \d test_alt2
             Table "public.test_alt1"
    Column  |         Type          | Modifiers 
  ----------+-----------------------+-----------
   id       | integer               | 
   areacode | integer               | 
   name     | character varying(20) |
  ```
  
- **修改列的数据类型**
  ```
  -- 修改test_alt1表中name字段的类型
  openGauss=# ALTER TABLE test_alt1 MODIFY name VARCHAR(50);
  -- 查看
  openGauss=# \d test_alt1
            Table "public.test_alt2"
   Column |         Type          | Modifiers 
  --------+-----------------------+-----------
   id     | integer               | 
   areaid | integer               | 
   name   | character varying(50) |
  ```
  ```
  -- 修改test_alt1表中name字段的类型
  openGauss=# ALTER TABLE test_alt2 ALTER COLUMN name TYPE VARCHAR(25);
  -- 查看
  openGauss=# \d test_alt2
            Table "public.test_alt2"
   Column |         Type          | Modifiers 
  --------+-----------------------+-----------
   id     | integer               | 
   areaid | integer               | 
   name   | character varying(25) |
  ```
  
- **删除列**
  ```
  -- 删除test_alt1中areaid字段
  openGauss=# ALTER TABLE test_alt2 DROP COLUMN areaid;
  -- 查看
  openGauss=# \d test_alt2
            Table "public.test_alt2"
   Column |         Type          | Modifiers 
  --------+-----------------------+-----------
   id     | integer               | 
   name   | character varying(25) |
  ```
  
- **修改字段存储模式**
  ```
  --查看表详细信息。
  openGauss=# \d+ test_alt2
                                Table "public.test_alt2"
   Column |         Type          | Modifiers | Storage  | Stats target | Description 
  --------+-----------------------+-----------+----------+--------------+-------------
   id     | integer               |           | plain    |              | 
   name   | character varying(25) |           | extended |              | 
  Has OIDs: no
  Options: orientation=row, storage_type=USTORE
  --修改test_alt2表中name字段的存储模式。
  openGauss=# ALTER TABLE test_alt2 ALTER COLUMN name SET STORAGE PLAIN;
  --查看。
  openGauss=# \d+ test_alt2
                               Table "public.test_alt2"
   Column |         Type          | Modifiers | Storage | Stats target | Description 
  --------+-----------------------+-----------+---------+--------------+-------------
   id     | integer               |           | plain   |              | 
   name   | character varying(25) |           | plain   |              | 
  Has OIDs: no
  Options: orientation=row, storage_type=USTORE
  --删除。
  openGauss=# DROP TABLE test_alt2;
  ```
  
 
#### 修改约束示例
- **为列添加非空约束**
  ```
  --建表。
  openGauss=# CREATE TABLE test_alt3(pid INT, areaid CHAR(5), name VARCHAR(20));
  --为pid添加非空约束。
  openGauss=# ALTER TABLE test_alt3 MODIFY pid NOT NULL;
  --查看。
  openGauss=# \d test_alt3
            Table "public.test_alt3"
   Column |         Type          | Modifiers 
  --------+-----------------------+-----------
   pid    | integer               | not null
   areaid | character(5)          | 
   name   | character varying(20) |
  ```
  
- **取消列的非空约束**
  ```
  openGauss=# ALTER TABLE test_alt3 MODIFY pid NULL;
  --查看。
  openGauss=# \d test_alt3
            Table "public.test_alt3"
   Column |         Type          | Modifiers 
  --------+-----------------------+-----------
   pid    | integer               | 
   areaid | character(5)          | 
   name   | character varying(20) |
  ```
  
- **修改字段默认值**
  ```
  --修改test_alt1表中id的默认值。
  openGauss=# ALTER TABLE test_alt3 ALTER COLUMN areaid SET DEFAULT '00000';
  --查看。
  openGauss=# \d test_alt3
                   Table "public.test_alt3"
   Column |         Type          |        Modifiers        
  --------+-----------------------+-------------------------
   pid    | integer               | 
   areaid | character(5)          | default '00000'::bpchar
   name   | character varying(20) |
  ```
  ```
  --删除id的默认值。
  openGauss=# ALTER TABLE test_alt3 ALTER COLUMN areaid DROP DEFAULT;
  --查看。
  openGauss=# \d test_alt3
            Table "public.test_alt3"
   Column |         Type          | Modifiers 
  --------+-----------------------+-----------
   pid    | integer               | 
   areaid | character(5)          | 
   name   | character varying(20) |
  ```
  
- **添加表级约束**
  - 直接添加约束
    ```
    --给表添加主键约束。
    openGauss=# ALTER TABLE test_alt3 ADD CONSTRAINT pk_test3_pid PRIMARY KEY (pid);
    --查看。
    openGauss=# \d test_alt3
              Table "public.test_alt3"
     Column |         Type          | Modifiers 
    --------+-----------------------+-----------
     pid    | integer               | not null
     areaid | integer               | 
     name   | character varying(20) | 
    Indexes:
        "pk_test3_pid" PRIMARY KEY, btree (pid) TABLESPACE pg_default
    ```
    
  
  - 先创建索引然后再添加约束
    ```
    --建表
    openGauss=# CREATE TABLE test_alt4(c1 INT, c2 INT);
    --建索引。
    openGauss=# CREATE UNIQUE INDEX pk_test4_c1 ON test_alt4(c1);
    --添加约束时关联已经创建的索引。
    openGauss=# ALTER TABLE test_alt4 ADD CONSTRAINT pk_test4_c1 PRIMARY KEY USING INDEX pk_test4_c1;
    --查看。
    openGauss=# \d test_alt4
       Table "public.test_alt4"
     Column |  Type   | Modifiers 
    --------+---------+-----------
     c1     | integer | not null
     c2     | integer | 
    Indexes:
        "pk_test4_c1" PRIMARY KEY, btree (c1) TABLESPACE pg_default
    --删除。
    openGauss=# DROP TABLE test_alt4;
    ```
    
   
- **删除表级约束**
  ```
  --删除约束。
  openGauss=# ALTER TABLE test_alt3 DROP CONSTRAINT IF EXISTS pk_test3_pid;
  --查看。
  openGauss=# \d test_alt3
            Table "public.test_alt3"
   Column |         Type          | Modifiers 
  --------+-----------------------+-----------
   pid    | integer               | not null
   areaid | integer               | 
   name   | character varying(20) | 
  --删除。
  openGauss=# DROP TABLE test_alt3;
  ```
  
 
#### 相关链接
[CREATE TABLE](https://support.huaweicloud.com/centralized-devg-v2-gaussdb/gaussdb_42_0424.html#ZH-CN_TOPIC_0000002186016182)，[DROP TABLE](https://support.huaweicloud.com/centralized-devg-v2-gaussdb/gaussdb_42_0464.html#ZH-CN_TOPIC_0000002186016234)
