# CREATE TABLE
#### 功能描述
在当前数据库中创建一个新的空白表，该表由命令执行者所有。当前默认创建行存表。
 #### 注意事项
- 对于HASH分布表，当对非分布键添加主键约束或唯一约束，将默认建立全局二级索引，其中全局二级索引的约束请参见[功能约束](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0250.html#ZH-CN_TOPIC_0000002793707595__section1228615342117)。对于非HASH分布表，主键约束和唯一约束必须包含分布键，否则会报错。
- 分布方式默认取值为HASH(column_name)，column_name包括：表的主键列、表的唯一约束列（如果存在）或表中数据类型支持作为分布列的第一列，优先级别为主键列\>唯一约束列\>表中数据类型支持作为分布列的第一列。当同时存在主键列以及多个唯一约束列且未指定表的分布方式时，按照优先级别选取表的主键列后，其余唯一约束列将默认建立全局二级索引。
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  MYSQL兼容模式下（即sql_compatibility = 'MYSQL'），若使用字符类型的分布列，不建议使用不区分大小写的字符序（如：utf8mb4_general_ci、utf8mb4_unicode_ci、utf8mb4_0900_ai_ci），容易造成数据倾斜，无法平均分布，推荐使用utf8mb4_bin字符序。
  
- 仅当表属性enable_update_distkey设置为on时，满足以下约束条件支持更新（UPDATE）分布列的操作，否则分布列不支持更新（UPDATE）操作。
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  - 仅当相应表属性enable_update_distkey设置为on或时才支持更新分布列。
  
  - 不支持将UPDATE语句下推DN执行，直接生成PGXC计划，不会根据更新分布列前后值而对计划做改变。
  
  - 不支持带有行级UPDATE TRIGGER的表，否则会执行失败，报错进行提示。
  
  - 对行级INSERT/DELETE TRIGGER不生效，STATEMENT级UPDATE TRIGGER正常执行。
  
  - 不支持并发更新同一行，先获取锁的执行，DN上后获取锁的行为按照GUC参数concurrent_dml_mode设置情况存在不同的行为（返回0或报错）。如果报错，则可能存以下情况：
    - 报错提示信息为update distribute column conflict。
    
    - 报错提示信息为锁超时，即当获取锁时间超过阈值。
     
  
  - 不支持带有全局二级索引（GSI）的表，否则会执行报错。
  
  - 只支持HASH分布，不支持LIST分布或RANGE分布，否则会执行报错。
  
  - 不支持MERGE INTO和UPSERT更新分布列的行为，否则会执行报错。
  
  - 不支持gtm_free，否则会执行报错。
  
  - 不支持UPDATE RETURNING，否则会执行报错。
  
  - 不支持JOIN，否则会执行报错。
  
  - 不支持UPDATE LIMIT，否则会执行报错。
    
- 如果在建表过程中数据库系统发生故障，系统恢复后可能无法自动清除已创建的磁盘文件和大小为0的磁盘文件。
- 使用JDBC时，支持通过PreparedStatement对DEFAULT值进行参数化设置。
- 行存表的表级约束不支持外键。
- 不支持在rowid/rowno系统列上创建外键约束。
- 被授予CREATE ANY TABLE权限的用户，可以在public模式和用户模式下创建表。如果需要创建包含serial类型列的表，还需要CREATE ANY SEQUENCE创建序列的权限。
- XML类型数据不能作为主键和外键。
- 在为数据对象增加或者变更ILM策略时，如果追加了行表达式，仅支持白名单中列出的函数作为行表达式。具体请参见[行表达式函数白名单](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0416.html)。
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  - 如果数据库无限创建表，可能会对CN造成以下影响：
    - 资源耗尽：每个表都会占用一定的磁盘空间，无限创建表会导致大量的内存和磁盘空间被占用，可能会导致CN的资源耗尽，从而导致系统崩溃或变得不稳定。
      - 性能下降：无限创建表会导致大量的I/O操作和CPU计算，数据库的元数据信息将会变得十分庞大，可能会导致CN的性能下降，包括插入、查询、更新和删除等操作，从而导致系统响应变慢或无法满足业务需求。
      
      - 安全问题：过多的表会导致数据库的管理和维护变得困难，无限创建表可能会导致数据泄露或数据丢失等安全问题，数据库的稳定性会降低从而给企业带来不可估量的损失。
       
    
    
    因此，对于数据库，应该合理规划表的数量和大小，避免无限创建表，从而保证系统的稳定性、可靠性和安全性。
    
  
  - 在ILM策略的ON ( EXPR )行级表达式支持的函数中，有部分函数的输出可能会受兼容性参数影响。例如，upper函数在MYSQL兼容模式下设置b_format_version='5.7'和b_format_dev_version='s2'后，将无法转大写。
    
 
- 表约束个数不能超过32767个。
 #### 语法格式
创建表。
```
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name
    { ( { column_name data_type [ CHARACTER SET | CHARSET charset ] [ COLLATE collation ] [ column_constraint [ ... ] ]
        | table_constraint
        | LIKE source_table [ like_option [...] ] }
        [, ... ] )
    | LIKE source_table }
    [ table_option [ ,... ] [ ... ] ]
    [ htap_option ]
    [ WITH ( {storage_parameter = value} [, ... ] ) ]
    [ WITHOUT OIDS ]
    [ ON COMMIT { PRESERVE ROWS | DELETE ROWS } ]
    [ ILM ADD POLICY ROW STORE COMPRESS 
 { ADVANCED [ MEDIUM | HIGH ] ROW AFTER n { day | days | month | months | year | years } OF NO MODIFICATION [ ON ( EXPR )] 
 | TURBO [ LOW | MEDIUM | HIGH ] UNIT AFTER n { hour| hours | day | days | month | months | year | years } OF NO MODIFICATION 
 | NONE}]
    [ TABLESPACE tablespace_name ]
    [ DISTRIBUTE BY { REPLICATION | HASH ( column_name [, ...] ) 
    | MURMURHASH ( expression )
    | RANGE ( column_name [, ...] ) { SLICE REFERENCES tablename | ( slice_less_than_item [, ...] )
    | ( slice_start_end_item [, ...] ) }
    | LIST ( column_name [, ...] ) { SLICE REFERENCES tablename | ( slice_values_item [, ...] ) }
    } ]
    [ TO { GROUP groupname | NODE ( nodename [, ... ] ) } ];
```
- 其中table_option为：
  ```
  { COMMENT [ = ] 'string' |
    AUTO_INCREMENT [ = ] value |
    [ DEFAULT ] CHARACTER SET | CHARSET [ = ] default_charset |
    [ DEFAULT ] COLLATE [ = ] default_collation |
    ENGINE [ = ] { InnoDB | 'InnoDB' | "InnoDB" } }
  ```
  
- 其中htap_option为：
  ```
  { COLVIEW [ PRIORITY { HIGH | LOW | NONE } ] |
    NOCOLVIEW }
  ```
  
- 其中列约束column_constraint为：
  ```
  [ CONSTRAINT constraint_name ]
  { NOT NULL |
    NULL |
    CHECK ( expression ) |
    DEFAULT default_expr |
    ON UPDATE update_expr |
    AUTO_INCREMENT |
    COMMENT 'string' |
    COLVIEW |
    NOCOLVIEW |
    UNIQUE [KEY] index_parameters |
    PRIMARY KEY index_parameters |
    ENCRYPTED WITH ( [DATATYPE_CL = client_logic_type,]COLUMN_ENCRYPTION_KEY = column_encryption_key, ENCRYPTION_TYPE = encryption_type_value ) |
    REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
        [ ON DELETE action ] [ ON UPDATE action ] }
  [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
  ```
  

- 其中表约束table_constraint为：
  ```
  [ CONSTRAINT [ constraint_name ] ]
  { CHECK ( expression ) |
    UNIQUE [ index_name ] [ USING method ] ( { { column_name [ ( length ) ] | ( expression ) } [ ASC | DESC ] }[, ... ] ) index_parameters |
    PRIMARY KEY [ USING method ] ( { column_name [ ASC | DESC ] } [, ... ] ) index_parameters 
  [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
  { [ COMMENT 'string' ] [ ... ] }
  ```
  

- 其中like选项like_option为：
  ```
  { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | PARTITION | RELOPTIONS | DISTRIBUTION | UPDATE | ILM | ALL }
  ```
  
- 其中索引参数index_parameters为：
  ```
  [ WITH ( {storage_parameter = value} [, ... ] ) ]
  [ USING INDEX TABLESPACE tablespace_name ]
  ```
  

- RANGE分布规则如下：
  - slice_less_than_item为：
    ```
    SLICE name VALUES LESS THAN ({ expression | MAXVALUE } [, ...]) [ DATANODE datanode_name | ( datanode_name_list [, ... ] ) ]
    ```
    
  
  - slice_start_end_item为：
    ```
    SLICE name {
    { START ( expression ) END ( expression ) EVERY ( expression ) } |
    { START ( literal ) END ( { literal | MAXVALUE } ) } |
    { START ( literal ) } |
    { END ( { literal | MAXVALUE } ) }
    }
    ```
    
   
- 其中LIST分布规则如下：
  slice_values_item为：
  ```
  [ ( SLICE name VALUES (expression [, ... ]) [DATANODE datanode_name | ( datanode_name_list )]
   [, ... ] ) |
    ( SLICE name VALUES (DEFAULT) [DATANODE datanode_name] | ( datanode_name_list ) )
  ]
  ```
  
- 其中update_expr为：
  ```
  { CURRENT_TIMESTAMP | LOCALTIMESTAMP | NOW() }
  ```
  
 
#### 参数说明
- **UNLOGGED**
  如果指定此关键字，则创建的表为非日志表。在非日志表中写入的数据不会被写入到预写日志中，这样就会比普通表快很多。但是非日志表在冲突、执行操作系统重启、数据库重启、主备切换、切断电源操作或异常关机后会被全部清空，会造成数据丢失的风险。非日志表中的内容也不会被复制到备服务器中。在非日志表中创建的索引也不会被自动记录。
  使用场景：非日志表不能保证数据的安全性，用户应该在确保数据已经做好备份的前提下使用，例如系统升级时进行数据的备份。
  故障处理：当异常关机等操作导致非日志表上的索引发生数据丢失时，用户应该对发生错误的索引进行重建。
  
- **GLOBAL \| LOCAL**
  创建临时表时可以在TEMP或TEMPORARY前指定GLOBAL或LOCAL关键字。如果指定GLOBAL关键字，GaussDB会创建全局临时表，否则创建本地临时表。
  
- **TEMPORARY \| TEMP**
  如果指定TEMP或TEMPORARY关键字，则创建的表为临时表。临时表分为全局临时表和本地临时表两种类型。创建临时表时如果指定GLOBAL关键字则为全局临时表，否则为本地临时表。
  全局临时表的元数据对所有会话可见，会话结束后元数据继续存在。会话与会话之间的用户数据、索引和统计信息相互隔离，每个会话只能看到或更改自己提交的数据。全局临时表有两种模式：一种基于会话级别（ON COMMIT PRESERVE ROWS），当会话结束时自动清空用户数据；一种基于事务级别（ON COMMIT DELETE ROWS），当执行COMMIT或ROLLBACK时自动清空用户数据。建表时如果没有指定ON COMMIT选项，则缺省为会话级别。与本地临时表不能指定schema不同，全局临时表建表时可以指定schema。
  本地临时表只在当前会话可见，本会话结束后自动删除。因此，在除当前会话连接的CN以外的其他CN故障时，仍然可以在当前会话上创建和使用临时表。由于临时表只在当前会话创建，对于涉及对临时表操作的DDL语句，会产生DDL失败的报错。因此，建议DDL语句中不要对临时表进行操作。TEMP和TEMPORARY等价。
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  - 本地临时表通过每个会话中以pg_temp开头的Schema来保证只对当前会话可见，因此，用户在日常操作中请勿手动删除以pg_temp，pg_toast_temp开头的Schema。
  
  - 如果建表时不指定TEMPORARY \| TEMP关键字，而指定表的Schema为当前会话的pg_temp开头的Schema，则该表会被创建为临时表。
  
  - ALTER/DROP全局临时表和索引时，如果其它会话正在使用，则禁止操作（ALTER INDEX index_name REBUILD除外）。
  
  - 全局临时表的DDL只会影响当前会话的用户数据和索引。例如TRUNCATE、REINDEX、ANALYZE只对当前会话有效。
  
  - 全局临时表功能可以通过设置GUC参数max_active_global_temporary_table控制是否启用。如果max_active_global_temporary_table=0，则关闭全局临时表功能。
  
  - 临时表只对当前会话可见，因此不支持与\\parallel on（并行执行）同时使用。
  
  - 临时表不支持DN故障或者主备切换。
  
  - 全局临时表不响应自动清理，在长连接场景使用时尽量使用ON COMMIT DELETE ROWS的全局临时表，或定期手动执行VACUUM，否则可能导致clog日志不回收（可以通过设置vacuum_gtt_defer_check_age，对长时间未清理全局临时表的情况告警）。
  
  - 全局临时表不支持以下场景：
    - 不支持创建全局临时SEQUENCE，各个会话的全局临时表使用共享的SEQUENCE，只能保证唯一性，不保证连续性。
    
    - 不支持创建全局临时视图。
    
    - 不支持创建分区表。
    
    - 不支持创建hashbucket表。
    
    - 不支持扩展统计信息。
    
    - 不支持ON COMMIT DROP属性。
    
    - 不支持GSI索引。
    
    - 不支持'M'兼容性。
    
    - 不支持分布式备机读。
    
    - 不支持stream计划。
    
    - 不支持扩缩容，扩缩容回滚存在数据丢失风险，扩缩容结束数据清空。
    
    - 在DN主备切换、DN节点故障、CN故障的情况下，存在数据丢失的风险（全局临时表无Xlog，不做主备数据同步）。
     
    
- **IF NOT EXISTS**
  如果已经存在相同名称的表，不会产生错误，而会发出通知，告知该表已存在。
  
- **\[ ILM ADD POLICY ROW STORE COMPRESS** **{ ADVANCED \[ MEDIUM \| HIGH \] ROW AFTER n { day \| days \| month \| months \| year \| years } OF NO MODIFICATION \[ ON ( EXPR )\]** **\| TURBO \[ LOW \| MEDIUM \| HIGH \] UNIT AFTER n { hour \| hours \| day \| days \| month \| months \| year \| years } OF NO MODIFICATION** **\| NONE}\]**
  创建新表时，可以调用ILM ADD POLICY ROW STORE COMPRESS ADVANCED \[ MEDIUM \| HIGH \] ROW给行存添加高级压缩中/高级别策略。比如：
  ```
  CREATE TABLE t1 (a int) ILM ADD POLICY ROW STORE COMPRESS ADVANCED ROW AFTER 3 DAY OF NO MODIFICATION ON (a != 0);
  ```
  表示创建t1表并添加高级压缩策略：三天未修改并且a != 0的行。
  - AFTER n { day \| month \| year } OF NO MODIFICATION ：表示n天/月/年没有修改的行，高级压缩不支持hour。
  
  - ON ( EXPR )：行级表达式，用于判断行的冷热。
  
  - EXPR仅支持白名单函数，具体请参见[行表达式函数白名单](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0416.html)。
    ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
    - 在ILM策略的ON(EXPR)行级表达式支持的函数中，有部分函数的输出可能会受兼容性参数影响。例如，upper函数在MYSQL兼容模式下设置b_format_version='5.7'和b_format_dev_version='s2'后，将无法转换大写。
    
    - 压缩级别是可选项，不指定时默认使用MEDIUM级别。
      
  
  
  创建新表时，可以调用ILM ADD POLICY给行存添加跨页透明压缩策略。比如：
  ```
  CREATE TABLE t1 (a int) ILM ADD POLICY ROW STORE COMPRESS TURBO HIGH UNIT AFTER 3 HOUR OF NO MODIFICATION;
  ```
  表示创建t1表并添加跨页透明压缩策略：策略级别为high，冷热管理时间间隔为3小时。
  - AFTER n { hour \| day \| month \| year } OF NO MODIFICATION ：表示n小时/天/月/年没有修改的压缩组。
  
  - 压缩级别不指定时默认为MEDIUM。
   
- **table_name**
  要创建的表名。
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  物化视图的一些处理逻辑会通过表名的前缀来识别是不是物化视图日志表和物化视图关联表。因此，用户不要创建表名以mlog_或matviewmap_为前缀的表，否则会影响此表的一些功能。
  
- **column_name**
  新表中要创建的字段名。
  
- **data_type**
  字段的数据类型。
  
- **CHARACTER SET \| CHARSET charset**
  指定表字段的字符集。未单独指定COLLATE时，会将字段的字符序设置为指定的字符集的默认字符序。
  
- **COLLATE collation**
  指定列的字符序（数据类型需为支持排列的类型）。未单独指定时，则使用默认字符序。
  可通过SELECT \* FROM pg_collation;命令查看pg_collation系统表中显示的字符序信息，默认的字符序为查询结果中以default开始的行。
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  - 仅字符类型支持指定字符集。
  
  - 指定为binary字符集或字符序时，实际是将字符类型转化为对应的二进制类型，若类型映射不存在会产生报错，当前仅支持TEXT类型转化为BLOB的映射。
  
  - 除指定为binary字符集或字符序外，当前仅支持指定与数据库编码相同的字符集。
  
  - 未显式指定字段字符集或字符序时，若指定了表的默认字符集或字符序，字段字符集和字符序将从表上继承。若表的默认字符集或字符序不存在，当b_format_behavior_compat_options包含'default_collation'时，字段的字符集和字符序将继承当前数据库的字符集及其对应的默认字符序。
  
  - 对于MYSQL兼容模式下（即sql_compatibility = 'MYSQL'），还支持utf8mb4_bin、utf8mb4_general_ci、utf8mb4_unicode_ci、binary、gbk_chinese_ci、gbk_bin、gb18030_chinese_ci、gb18030_bin、utf8mb4_0900_ai_ci、utf8_general_ci以及utf8_bin字符序，具体介绍如[表1]所示。
   
   表1MYSQL兼容模式下（即sql_compatibility = 'MYSQL'）支持的字符集和字符序介绍 
  | 字符序名称                | 对应的字符集          | 描述                                                 |
  |:---|:---|:---|
  | utf8mb4_general_ci | utf8mb4（即utf8）  | 使用通用排序规则，不区分大小写。                                     |
  | utf8mb4_unicode_ci  | utf8mb4（即utf8）  | 使用通用排序规则，不区分大小写。                                 |
  | utf8mb4_bin         | utf8mb4（即utf8） | 使用二进制排序规则，区分大小写。                                   |
  | binary               | binary           | 使用二进制排序规则。                                           |
  | gbk_chinese_ci      | gbk            | 使用中文语言排序规则。                                       |
  | gbk_bin            | gbk            | 使用二进制排序规则，区分大小写。                                    |
  | gb18030_chinese_ci   | gb18030        | 使用中文语言排序规则。                                         |
  | gb18030_bin       | gb18030        | 使用二进制排序规则，区分大小写。                                  |
  | utf8mb4_0900_ai_ci | utf8mb4       | 使用UCA (Unicode collation algorithm) 算法规则，不区分大小写。 |
  | utf8_general_ci    | utf8         | 使用通用排序规则，不区分大小写。                                    |
  | utf8_bin          | utf8           | 使用二进制排序规则，区分大小写。                                  |
     
  
- **LIKE source_table \[ like_option ... \]**
  LIKE子句声明一个表，新表自动从这个表中继承所有字段名及其数据类型和非空约束，以及声明为serial的缺省表达式。
  新表与源表之间在创建动作完毕之后是相互独立的。在源表做的任何修改都不会被继承到也不会新表中，并且在扫描源表的时候，不包含新表的数据。
  被继承的列和约束并不使用相同的名称进行融合。如果明确地指定了相同的名称或者在另外一个LIKE子句中，将会报错。
  - 源表上除serial外的字段缺省表达式只有在指定INCLUDING DEFAULTS时，才会被继承到新表中。默认情况下，不包含缺省表达式，即新表中的所有字段的缺省值都是NULL。
  
  - 如果指定了INCLUDING UPDATE，则源表列的ON UPDATE CURRENT_TIMESTAMP属性会被继承到新表列中。默认不复制该属性。
  
  - 源表上的CHECK约束仅在指定INCLUDING CONSTRAINTS时，会被继承到新表中，而其他类型的约束将不会被继承到新表中。非空约束一直可以继承到新表中。此规则同时适用于表约束和列约束。
  
  - 如果指定了INCLUDING INDEXES，则源表上的索引也将在新表上创建，默认情况下，不建立索引。新表上的索引所在表空间和源表上的索引所在表空间保持一致。
  
  - 如果指定了INCLUDING STORAGE，则源表列的STORAGE设置会被继承到新表中，默认情况下，不包含STORAGE设置。
  
  - 如果指定了INCLUDING COMMENTS，则源表列、约束和索引的注释会复制到新表中。默认情况下，不对源表的注释进行继承。
  
  - 如果指定了INCLUDING PARTITION，则源表的分区定义会被继承到新表中，同时新表将不能再使用PARTITION BY子句。默认情况下，不对源表的分区定义进行继承。
  
  - 如果指定了INCLUDING RELOPTIONS，则源表的存储参数（即源表的WITH子句）将会被继承到新表中。默认情况下，不对源表的存储参数进行继承。
  
  - 如果指定了INCLUDING DISTRIBUTION，则源表的分布信息会被继承到新表中，包括分布类型和分布列，同时新表将不能再使用DISTRIBUTE BY子句。默认情况下，不对源表的分布信息进行继承。
  
  - 如果指定了INCLUDING ILM，则源表的ILM策略信息会被继承到新表中，如果需要同时复制源表上的分区对象的ILM策略信息，需要同时指定INCLUDING PARTITION。
  
  - INCLUDING ALL包含了INCLUDING DEFAULTS、INCLUDING UPDATE、INCLUDING CONSTRAINTS、INCLUDING INDEXES、INCLUDING STORAGE、INCLUDING COMMENTS、INCLUDING PARTITION、INCLUDING RELOPTIONS、INCLUDING DISTRIBUTION和INCLUDING ILM的内容。
  
  
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  - 如果指定了INCLUDING RELOPTIONS，且源表的存储参数（即源表的WITH子句）中不包含storage_type，则新表的存储引擎类型将由GUC参数enable_default_ustore_table的取值决定。
  
  - 如果源表包含serial、bigserial、smallserial类型，或者源表字段的默认值是SEQUENCE，且SEQUENCE属于源表（通过CREATE SEQUENCE ... OWNED BY创建），这些SEQUENCE不会关联到新表中，新表中会重新创建SEQUENCE。如果用户希望源表和新表共享SEQUENCE，需要首先创建一个共享的SEQUENCE（避免使用OWNED BY），并配置为源表字段默认值，这样创建的新表会和源表共享该SEQUENCE。
  
  - 不建议将其他表私有的SEQUENCE配置为源表字段的默认值，尤其是其他表只分布在特定的NodeGroup上，这可能导致CREATE TABLE ... LIKE执行失败。另外，如果源表配置其他表私有的SEQUENCE，当该表删除时SEQUENCE也会连带删除，这样源表的SEQUENCE将不可用。如果用户希望多个表共享SEQUENCE，建议创建共享的SEQUENCE。
  
  - 如果源表为rowid表，指定了INCLUDING ALL/INCLUDING RELOPTIONS后，新表也为rowid表；仅指定INCLUDING INDEXES时，新表为非rowid表，且不会复制源表的rowno索引。
  
  - CREATE TABLE table_name LIKE source_table;语法仅在MYSQL模式数据库（即sql_compatibility = 'MYSQL'）下，且参数b_format_version值为5.7、b_format_dev_version值为s2时支持。
  
  - 在MYSQL模式数据库下，且参数b_format_version值为5.7、b_format_dev_version值为s2时，不支持指定INCLUDING和EXCLUDING选项，默认情况下与指定INCLUDING ALL的行为一致。
  
  - 若source_table为系统表，则不支持指定INCLUDING ALL或INCLUDING DISTRIBUTION。
    
- **AUTO_INCREMENT \[ = \] value**
  这个子句为自动增长列指定一个初始值，value必须为正数，不得超过2^127^-1。
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  该子句仅在参数sql_compatibility='MYSQL'时有效。
  
- **COMMENT \[ = \] 'string'**
  - COMMENT \[ = \] 'string'子句表示给表添加注释。
  
  - 在column_constraint中的COMMENT 'string'表示给列添加注释。
  
  - 在table_constraint中的COMMENT 'string'表示给主键和唯一键对应的索引添加注释。
  
  
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  - 该子句仅在MYSQL模式数据库（即sql_compatibility = 'MYSQL'）下有效。
  
  - 表级注释支持的最大字符串长度为2048字符，列级和索引级注释支持的最大长度为1024字符。
  
  - table_constraint中的COMMENT仅支持主键和唯一键，其他约束不支持。
    
- **ENGINE**
  MYSQL兼容模式下支持，仅语法适配，且只支持设置InnoDB，无实际效果。
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  不支持CREATE TABLE table_name LIKE source_table;语法中使用ENGINE语法。
  
- **COLVIEW \| NOCOLVIEW**
  指定表、列、分区是否创建IMCV表元信息。其中创建IMCV表需要依赖于enable_htap参数打开。
  不支持与LIKE source_table语法同时使用。
  
- **PRIORITY**
  指定数据加载至IMCV表的优先级。分为：默认优先级、低优先级以及高优先级。
  
- **WITH ( { storage_parameter = value } \[, ... \] )**
  表示为表或为索引指定一个可选的存储参数。当WITH子句用于表时，还可以包含OIDS=FALSE，表示不分配OID。
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  - WITH子句不支持OIDS=TRUE语法。
  
  - 使用任意精度类型Numeric定义列时，建议指定精度p以及刻度s。在不指定精度p和刻度s时，按输入格式直接输出。
   
  参数的详细描述如下所示：
  - FILLFACTOR 一个表的填充因子（fillfactor）是一个介于10和100之间的百分数。100（完全填充）是默认值。在Ustore存储引擎下，该值的默认值为92。如果指定了较小的填充因子，INSERT操作仅按照填充因子指定的百分率填充表页。每个页上的剩余空间将用于在该页上更新行，这就使得UPDATE有机会在同一页上放置同一条记录的新版本，这比把新版本放置在其他页上更有效。对于一个从不更新的表将填充因子设为100是最佳选择，但是对于频繁更新的表，选择较小的填充因子则更加合适。
    取值范围：10\~100
    
  
  - ORIENTATION 指定表数据的存储方式，该参数设置成功后就不再支持修改。
    取值范围：
    - ROW，表示表的数据将以行式存储。 行存储适合于OLTP业务，此类型的表上交互事务比较多，一次交互会涉及表中的多个列，用行存查询效率较高。
      
    
    
    默认值：若指定表空间为普通表空间，默认值为ROW。
    
  
  - STORAGE_TYPE 指定存储引擎类型，该参数设置成功后就不再支持修改。
    取值范围：
    - USTORE，表示表支持Inplace-Update存储引擎。特别需要注意，使用UStore表，必须要开启track_counts和track_activities参数，否则会引起空间膨胀。
    
    - ASTORE，表示表支持Append-Only存储引擎。
    
    
    默认值：不指定时，由参数enable_default_ustore_table决定存储引擎方式，默认是Inplace-Update存储。
    
  
  - TOAST.TOAST_STORAGE_TYPE 指定Toast表的存储类型。当GUC参数"enable_enhance_toast_table=on"时，Toast表的存储类型支持通过Vacuum Full操作将Toast升级为Enhanced Toast结构。
    取值范围：
    - ENHANCED_TOAST，指定Toast表的存储类型为Enhanced Toast。
    
    - TOAST，指定Toast表的存储类型为Toast。
    
    
    默认值：
    建表时不指定TOAST.TOAST_STORAGE_TYPE，则Toast表的存储类型依赖于GUC参数enable_enhance_toast_table。若该参数值为on，则Toast表的存储类型为ENHANCED_TOAST；若该参数值为off，则Toast表的存储类型为TOAST。
    
  
  - INIT_TD 创建UStore表时，指定初始化的TD个数，该参数可以通过ALTER TABLE进行修改。特别需要注意，该参数会影响数据页面存放的单个元组的最大大小，具体换算方法为MAX_TUPLE_SIZE = BLCKSZ - INIT_TD \* TD_SIZE，例如用户将INIT_TD数量从4修改为8，单个元组最大大小会减小4 \* INIT_TD大小。
    取值范围：2\~128，默认值为4。
    
  
  - COMPRESSLEVEL 指定表数据同一压缩级别下的不同压缩水平，它决定了同一压缩级别下表数据的压缩比以及压缩时间。对同一压缩级别进行了更加详细的划分，为用户选择压缩比和压缩时间提供了更多的空间。总体来讲，此值越大，表示同一压缩级别下压缩比越大，压缩时间越长；反之亦然。
    取值范围：0\~3
    默认值：0
    
  
  - segment 使用段页式的方式存储。本参数仅支持行存表。不支持1\~5号物理文件非法删除破坏场景的防护，不支持在升级观察期创建。
    取值范围：on/off
    默认值：off
    
  
  - hashbucket 创建hash bucket存储。本参数仅支持行存表。
    取值范围：on/off
    默认值：off
    ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
    - 创建hashbucket表时当前数据库必须绑定到集群默认的node group上。数据库绑定node group请参见[ALTER DATABASE](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0184.html)。
    
    - 当前版本hashbucket表相关DDL操作性能受限，不建议频繁对hashbucket表进行DDL操作。
    
    - hashbucket表绑定段页式存储，即hashbucket=on隐含segment=on。
    
    - 小表（小于：普通表8M，分区表8M \* 分区数量）不建议创建成hashbucket表，顺序扫描性能较普通表劣化2倍。
      
  
  - enable_tde 指定该表为加密表。数据库会自动将加密表中的数据先加密再存储。使用该参数前，请确保已通过GUC参数enable_tde开启透明加密功能，并通过GUC参数tde_key_info设置访问密钥服务的信息，在《开发指南》中"特性使用指导 \> 透明数据加密"章节可获取该参数的详细使用方法。本参数仅支持行存表、段页式表、hashbucket表、临时表和unlogged表。
    取值范围：on/off。设置enable_tde=on时，key_type、cmk_id、dek_cipher参数由数据库自动生成，用户无法手动指定或更改。
    默认值：off
    
  
  - encrypt_algo 指定加密表的加密算法，需与enable_tde结合使用。
    取值范围：字符串，有效值为：AES_128_CTR、SM4_CTR、AES_128_CTR_SHA256_HMAC、SM4_CTR_SM3_HMAC或AES_128_GCM。
    默认值：
    - 如果enable_tde=on：
      - GUC参数tde_encrypt_config中的子参数table_algorithm不为空，默认值与table_algorithm相同。
      
      - GUC参数tde_encrypt_config中的子参数table_algorithm为空，默认值为AES_128_CTR。
       
    
    - 如果enable_tde=off，默认值为空。
     
  
  - parallel_workers 表示创建索引时，启动的bgworker线程数量，例如2就表示将会起2个bgworker线程并发创建索引。
    取值范围：\[0,32\]，int类型，0表示关闭并行建索引。
    默认值：不设置该参数，表示不开启并行建索引功能。
    
  
  - dek_cipher 数据密钥的密文。该存储参数不支持用户手动设置或更改。当用户为表设置enable_tde参数后，数据库自动生成数据密钥。
    取值范围：字符串
    默认值：空
    
  
  - key_type 主密钥的类型。该存储参数不支持用户手动设置或更改。当用户为表设置enable_tde参数后，数据库自动从GUC参数tde_key_info中获取主密钥的类型。
    取值范围：字符串
    默认值：空
    
  
  - cmk_id 主密钥的ID。该存储参数不支持用户手动设置或更改。当用户为表设置enable_tde参数后，数据库自动从GUC参数tde_key_info中获取主密钥的ID。
    取值范围：字符串
    默认值：空
    
  
  - hasuids 参数开启：更新表元组时，为元组分配表级唯一标识id。
    取值范围：on/off
    默认值：off
    
  
  - logical_repl_node 复制表逻辑解码时，向CN返回逻辑日志的DN节点名。对于复制表，如用户不指定，则默认为当前表所在node group的第一个节点。对该选项进行RESET操作时，会重置为当前表的第一个节点。
    取值范围：字符串
    默认值：非复制表默认为空，复制表默认为第一个节点名。
    
  
  - skip_logical_deparse 当数据库进行处理逻辑解码时，跳过对该表的处理。不建议用户使用，若使用不当，会造成逻辑解码缺失内容。
    取值范围：on/off
    默认值：off
    
  
  - STAT_STATE 该表的统计信息是否被锁定的标识符，如果被锁定了，该表的统计信息无法更新。当前形态下该参数不生效。
    取值范围：locked/unlock
    默认值：unlock
    
  
  - statistic_granularity
    记录该表在分析统计信息时的默认partition_mode。partition_mode说明请参见[ANALYZE \| ANALYSE](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0221.html)章节中的[PARTITION_MODE](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0221.html#ZH-CN_TOPIC_0000002793707189__li18855132617161)。此参数对非分区表设置无效。
    取值范围：请参见[ANALYZE \| ANALYSE](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0221.html)章节中的[PARTITION_MODE](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0221.html#ZH-CN_TOPIC_0000002793707189__li18855132617161)。
    默认值：AUTO
    
  
  - autovacuum_enabled 表示是否开启表的自动清理功能。
    取值范围：on/off
    默认值：on
    
  
  - autovacuum_vacuum_threshold 开启自动清理功能，指定在该表中触发VACUUM所需的更新或删除的最小元组数（仅对Astore表生效）。
    取值范围：0\~2147483647
    默认值：缺省时与GUC参数autovacuum_vacuum_threshold一致。
    
  
  - autovacuum_analyze_threshold 自动清理功能中，指定在该表中触发ANALYZE所需的插入、更新或删除的最小元组数。
    取值范围：0\~2147483647
    默认值：缺省时与GUC参数autovacuum_analyze_threshold一致。
    
  
  - autovacuum_vacuum_scale_factor 自动清理功能中，指定在该表中触发VACUUM所需的插入、更新或删除元组的比例（仅对Astore表生效）。
    取值范围：0.0\~100.0
    默认值：缺省时与GUC参数autovacuum_vacuum_scale_factor一致。
    
  
  - autovacuum_analyze_scale_factor 自动清理功能中，指定在该表中触发ANALYZE所需的插入、更新或删除元组的比例。
    取值范围：0.0\~100.0
    默认值：缺省时与GUC参数autovacuum_analyze_scale_factor一致。
    
  
  - autovacuum_freeze_min_age 自动清理功能中，在该表参数指定了一个行版本的最小年龄，超过这个年龄的行才会被冻结。
    取值范围：0\~576460752303423487
    默认值：缺省时与GUC参数vacuum_freeze_min_age一致。
    
  
  - autovacuum_freeze_max_age 自动清理功能中，该表pg_class.relfrozenxid字段在超过多少个事务后，就会强制执行VACUUM操作。即使自动清理被禁用，系统也会启动AUTOVACUUM进程。清理操作还允许从pg_clog/子目录中删除旧文件（仅对Astore表生效）。
    取值范围：100000\~576460752303423487
    默认值：缺省时与GUC参数autovacuum_freeze_max_age一致。
    
  
  - autovacuum_freeze_table_age 自动清理功能中，该表被标记为不需要自动清理时，将保持不变的时间。（仅对Astore表生效）。
    取值范围：0\~576460752303423487
    默认值：缺省时与GUC参数vacuum_freeze_table_age一致。
    
  
  - vacuum_truncate 表示是否开启表的VACUUM TRUNCATE功能，在VACUUM时截断末尾空页。
    取值范围：on/off
    默认值：on
    ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
    - 该参数仅对Astore生效，对hashbucket表和segment表不生效。
    
    - 从不支持该参数版本升级至支持该参数版本时，不支持在升级观察期创建、修改该参数。
    
    - 支持通过toast.vacuum_truncate参数单独控制TOAST表是否截断末尾空页。
      
  
  - skip_logical_deparse 在内核处理逻辑解码时跳过对该表的处理，用于内核处理过程，不建议用户使用。若使用不当，会造成逻辑解码缺失内容。
    取值范围：on/off
    默认值：off
    
  
  - enable_update_distkey 标记该表是否支持更新（UPDATE）分布列的操作。仅当表的该属性设置为on，且在约束条件下时，才支持更新（UPDATE）分布列的操作。否则，分布列不支持更新（UPDATE）操作。
    取值范围：on/off
    默认值：off
    ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
    支持更新（UPDATE）分布列操作的约束请参见[注意事项]。
    
  
  - hasrowid 指定该表是否为rowid表。设置hasrowid = on时，该表会增加rowid系统列和rowno系统列，且会在rowno系统列上关联创建序列和索引。
    取值范围：on、off
    默认值：off
    ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
    - 此参数只支持ORA兼容模式数据库（即sql_compatibility = 'ORA'）。
    
    - 此参数不支持本地临时表、Unlogged表、全局临时表、物化视图、hashbucket表、复制表。
    
    - 此参数不支持和hasuids参数、oids参数同时指定。
    
    - 开启此参数时，不支持定义普通列名为rowno、rowid。
    
    - rowid表数据量不能超过9223372036854775807。
    
    - rowid表在GUC参数opt_behavior_knob开启ROWID_OPT选项时，支持ROWID系统列谓词条件改写、order by语句改写、max/min优化、分布剪枝和分区剪枝。详情请参见[opt_behavior_knob](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0783.html#ZH-CN_TOPIC_0000002764468986__section426055411380)内容。
      
  
  - partition_statistics_min_rows 对分区表执行ANALYZE命令时，用于确定分区级最小采样行数的参数值。
    取值范围：\[0, 10000\]
    默认值：50
    ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
    - 此参数仅对分区表有效。
    
    - 此参数仅在ANALYZE命令的PARTITION_MODE = ALL时，且GUC参数enable_partition_statistics_min_rows启用时生效，PARTITION_MODE说明请参见[ANALYZE \| ANALYSE](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0221.html)章节中的[PARTITION_MODE](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0221.html#ZH-CN_TOPIC_0000002793707189__li18855132617161)。
    
    - 上限约束：最终的分区表整表采样行数不超过GUC参数maintenance_work_mem可容纳的行数。
      
   
- **WITHOUT OIDS**
  等价于WITH（OIDS=FALSE）的语法，表示不分配OID。
  
- **ON COMMIT { PRESERVE ROWS \| DELETE ROWS }**
  ON COMMIT选项决定在事务中执行创建临时表操作，当事务提交时，此临时表的后续操作。当前支持PRESERVE ROWS和DELETE ROWS选项。
  - PRESERVE ROWS（缺省值）：提交时不对临时表做任何操作，临时表及其表数据保持不变。
  
  - DELETE ROWS：提交时删除临时表中数据。
   
- **TABLESPACE tablespace_name**
  创建新表时指定此关键字，表示新表将要在指定表空间tablespace_name内创建。如果没有声明，将使用默认表空间。
  
- **DISTRIBUTE BY**
  指定表如何在节点之间分布或者复制。
  取值范围：
  - REPLICATION：表的每一行存在所有数据节点（DN）中，即每个数据节点都有完整的表数据。
  
  - HASH ( column_name ) ：对指定的列进行Hash操作，通过映射，将数据分布到对应DN。
  
  - MURMURHASH ( diskey_expr ) ：对指定的列进行Hash操作，Hash算法指定为MURMURHASH算法，通过映射，将数据分布到对应DN上。diskey_expr可以是单个列名，也可以是[lpad_s(string text, length int \[, fill text\])](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0041.html#ZH-CN_TOPIC_0000002764309246__li12550172464816)函数修饰的列名，使用该函数进行修饰时，只有第一个参数可以为列名，形如lpad_s(a,10,'0')。lpad_s作为分布列表达式时不能省略第三个参数。
  
  - RANGE( column_name ) 对指定列按照范围进行映射，把数据分布到对应DN。
  
  - LIST( column_name ) 对指定列按照具体值进行映射，把数据分布到对应DN。
  
  
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  - 对于HASH分布，分布键最多个数与列最多个数一致，最多支持1600个；对于MURMURHASH分布，分布键只支持一列（一个表达式或一个表中的列）；对于RANGE（VALUE LESS THAN）分布和LIST分布，分布键最多支持四列；对于RANGE（START END）分布，分布键只支持一列。
  
  - 只有MURMURHASH分布支持分布列表达式，分布列表达式中只支持[lpad_s(string text, length int \[, fill text\])](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0041.html#ZH-CN_TOPIC_0000002764309246__li12550172464816)函数。
  
  - 对于MURMURHASH分布，有以下约束：
    - 不支持stream计划，支持FQS计划和PGXC计划。
    
    - 不支持扩缩容、hashbucket表、GSI及物化视图。
    
    - 两个HASH表做关联，在分布键上有等值关联条件时，目前暂不支持FQS计划。
    
    - MURMURHASH分布表必须指定nodegroup（自定义的nodegroup）且该nodegroup为非installation的nodegroup建表。
    
    - 不支持通过CREATE TABLE AS方式建表。
    
    - MURMURHASH分布表的分布键必须含有NOT NULL约束。
     
  
  - MURMURHASH分布是为了将采用MURMURHASH算法的遗留系统迁移时，保证数据分布不变而使用的分布算法。暂不支持扩容和stream计划，在选用分布算法时，建议优先选择HASH分布算法。
  
  - 对于从句是VALUE LESS THAN语法格式的RANGE分布策略，分布规则如下：
    - 从插入值的第一列开始比较。
    
    
    
    - 如果插入值的第一列小于待插入的分片的当前列的边界值，则直接插入。
    
    - 如果插入值的第一列等于待插入的分片的当前列 的边界值，则比较插入值的下一列与待插入的分片的下一列的边界值，如果小于，则直接插入。如果相等，继续比较插入值的下一列与待插入的分片的下一列的边界值，直至小于并插入。
    
    - 如果插入值的所有列大于待插入的分片的所有列的边界值，则比较下一分片。
     
  
  - 如果RANGE分布表的分片对应多个DN，会计算分布键的hash值，之后在这些DN中用hash值对DN个数取模，重新映射一个DN。详情见示例。
  
  - 如果LIST分布表的分片对应多个DN，对于default分片，会计算分布键的hash值，之后在这些DN中用hash值对DN个数取模，重新映射一个DN。对于非default分片，会使用Round Robin方式，把values列表中的值和DN进行映射。详情见示例。
  
  - RANGE/LIST分布表只支持扩容不支持缩容，slice扩容规则请联系管理员。
  
  - 对于复制表，存在以下下推充要条件：
    - 窗口函数场景：根据不同的窗口函数类型，有不同的下推充要条件：
      - 对于rank系列函数以及ratio_to_report函数：无限制条件，均支持下推。
      
      - 因为对于相同的PARTITION BY和ORDER BY值，窗口函数计算结果相同，并不依赖数据的相对顺序。
      
      - 对于row_number函数以及ntile函数，满足以下任一条件即可下推：
        - 投影列中仅包含窗口函数投影列。
        
        - 投影列中仅包含OVER子句中PARTITION BY的字段或ORDER BY的字段（无其他字段）+窗口函数投影列。
        
        - 当OVER子句仅存在PARTITION BY或ORDER BY时，PARTITION BY或ORDER BY对应列为主键。
        
        - 当OVER子句同时存在PARTITION BY和ORDER BY时，PARTITION BY和ORDER BY对应列均为主键。
         
      
      - 因为当窗口函数PARTITION BY或ORDER BY的列值相同但其他列值不同时，若其他列出现在窗口函数投影列中，可能导致不同数据节点（DN）上数据顺序不一致，引发窗口函数结果差异和数据不一致问题。
      
      - 对于lag函数以及lead函数：offset参数为0时支持下推。
      
      - 因为当offset参数为0时，相当于查询某一列，不依赖数据相对顺序；如果offset大于0时，由于相对顺序不同问题，会导致具有相同值的不同元组获取到NULL值。
      
      - 对于first_value函数、last_value函数以及nth_value函数，满足条件之一即可下推：
        - 参数表达式中的字段必须是OVER子句中PARTITION BY或ORDER BY的字段。
        
        - 当OVER子句仅存在PARTITION BY或ORDER BY时，PARTITION BY或ORDER BY对应列为主键。
        
        - 当OVER子句同时存在PARTITION BY和ORDER BY时，PARTITION BY和ORDER BY对应列均为主键。
         
       
    
    - 对复制表的查询包含系统列及volatile函数时不进行下推。
    
    - 拼接聚集函数场景：下推充要条件为拼接列等于ORDER BY列或者ORDER BY的字段为主键。
    
    - UPDATE/DELETE语句使用WHERE CURRENT OF cursor_name语法时，不进行下推。
     
   
  - 对于HASH分布，column_name的数据类型如下：
    - INTEGER TYPES：TINYINT、SMALLINT、INT、BIGINT、NUMERIC/DECIMAL
    
    - CHARACTER TYPES：CHAR、BPCHAR、VARCHAR、VARCHAR2、NVARCHAR2、TEXT
    
    - DATE/TIME TYPES：DATE、DATEA（仅在ORA兼容性生效）、TIME、TIMETZ、TIMESTAMP、TIMESTAMPTZ、INTERVAL、SMALLDATETIME
     
  
  - 对于MURMURHASH分布，diskey_expr中的列名的数据类型如下：
    - INTEGER TYPES：TINYINT、SMALLINT、INT、BIGINT
      
    
    - CHARACTER TYPES：CHAR、BPCHAR、VARCHAR、VARCHAR2、NVARCHAR2
     
  
  - 对于RANGE（VALUES LESS THAN）/LIST分布，column_name的数据类型如下：
    - INTEGER TYPES：TINYINT、SMALLINT、INT、BIGINT、NUMERIC/DECIMAL
    
    - CHARACTER TYPES：CHAR、BPCHAR、VARCHAR、VARCHAR2、NVARCHAR2、TEXT
    
    - DATE/TIME TYPES：DATE、DATEA（仅在ORA兼容性生效）、TIMESTAMP、TIMESTAMPTZ
     
  
  - 对于RANGE（START END）分布，column_name的数据类型如下：
    - INTEGER TYPES：TINYINT、SMALLINT、INT、BIGINT、NUMERIC/DECIMAL
    
    - DATE/TIME TYPES：DATE、DATEA（仅在ORA兼容性生效）、TIMESTAMP、TIMESTAMPTZ
     
  
  
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  在建表时，选择分布列和分区键可对SQL查询性能产生重大影响。因此，需要根据一定策略选择合适的分布列和分区键。
  - 选择合适的分布列：
    对于采用散列（HASH）方式的数据分布表，一个合适的分布列应将一个表内的数据，均匀分散存储在多个DN内，避免出现数据倾斜现象（即多个DN内数据分布不均）。请按照如下原则判定合适的分布列：
    1. 判断是否已发生数据倾斜现象。 连接数据库，执行如下语句，查看各DN内元组数目。其中tablename为待分析的表名。
       ```
       gaussdb=# SELECT a.count,b.node_name FROM (SELECT count(*) AS count,xc_node_id FROM tablename GROUP BY xc_node_id) a, pgxc_node b WHERE a.xc_node_id=b.node_id ORDER BY a.count DESC;
       ```
       如果各DN内元组数目相差较大（如相差数倍、数十倍），则表明已发生数据倾斜现象，请按照[2]调整分布列。
       
    
    2. 重新选择分布列并重新建表。由于当前不支持通过ALTER TABLE语句调整分布列，因此调整分布列时需要重新建表。
       选择原则如下：
       分布列的列值应比较离散，以便数据能够均匀分布到各个DN。例如，考虑选择表的主键为分布列，如在人员信息表中选择身份证号码为分布列。
       在满足上面原则的情况下，考虑选择查询中的连接条件为分布列，以便JOIN任务能够下推到DN中执行，且减少DN之间的通信数据量。
       
      
  
  - 选择合适的分区键： 数据分区功能，可根据表的一列或者多列，将要插入表的记录分为若干个范围（这些范围在不同的分区里没有重叠），然后为每个范围创建一个分区，用来存储相应的数据。
    调整分区键，使每次查询结果尽可能存储在相同或者最少的分区内（称为"分区剪枝"），通过获取连续I/O大幅度提升查询性能。实际业务中，经常将时间作为查询对象的过滤条件。因此，可考虑选择时间列为分区键，键值范围可根据总数据量、单次查询数据量调整。
    
  
  - RANGE/LIST分布： 当没有为RANGE/LIST分布表的分片显示指定DN时，数据库内部为分片分配DN是采用roundrobin的算法。另外，在使用RANGE/LIST分布的场景中，考虑到后续扩容的需要，建议用户在建表时定义尽可能多的分片数，因为如果定义的分片数小于扩容前的DN节点数，数据重分布时则无法落入新的DN节点。需要特别注意的是，由于是由用户自行设计分片规则，在某些极端情况下，扩容也可能无法解决存储空间不足的问题。
    
    
- **TO { GROUP groupname \| NODE ( nodename \[, ... \] ) }**
  TO GROUP指定创建表所在的Node Group。
  TO NODE主要供内部扩容工具使用，一般用户不应该使用。
  
- **CONSTRAINT \[constraint_name\]**
  列约束或表约束的名称。可选的约束子句用于声明约束，新行或者更新的行必须满足这些约束才能成功插入或更新。
  定义约束有两种方法：
  - 列约束：作为一个列定义的一部分，仅影响该列。不支持为AUTO_INCREMENT \| COMMENT 'string' \| ENCRYPTED WITH ( COLUMN_ENCRYPTION_KEY = column_encryption_key, ENCRYPTION_TYPE = encryption_type_value )子句添加约束名。
  
  - 表约束：不和某个列绑在一起，可以作用于多个列。
    ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
    表约束在MYSQL模式数据库下（即sql_compatibility = 'MYSQL'）constraint_name为可选项，在其他模式数据库下，必须加上constraint_name。
    
   
- **NOT NULL**
  字段值不允许为NULL。
  
- **NULL**
  字段值允许为NULL ，这是缺省值。
  这个子句只是为和非标准SQL数据库兼容。不建议使用。
  
- **CHECK ( expression )**
  CHECK约束声明一个布尔表达式，每次插入或者更新的行必须使表达式结果为真或未知才能成功，否则会抛出一个异常并且不会修改数据库。
  声明为字段约束的检查约束应该只引用该字段的数值，而在表约束里出现的表达式可以引用多个字段。
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  - expression表达式中，如果存在"\<\>NULL"或"！=NULL"，这种写法是无效的，需要修改为"IS NOT NULL"。
  
  - 不支持在系统列上添加CHECK约束。系统列请参见《开发指南》中"基础概念 \> 系统列"章节。
    
- **DEFAULT default_expr**
  DEFAULT子句给字段指定缺省值。该数值可以是任何不含变量的表达式（不允许使用子查询和对本表中的其他字段的交叉引用）。缺省表达式的数据类型必须和字段类型匹配。
  缺省表达式将被用于任何未声明该字段数值的插入操作。如果没有指定缺省值则缺省值为NULL 。
  
- **ON UPDATE update_expr**
  ON UPDATE子句为字段的一种属性约束。
  当对表中某元组执行UPDATE操作时，
  若更新字段的新值和表中旧值不相同，则表中该元组上具有该属性且不在更新字段内的字段值，将被自动更新为当前时间戳。若更新字段的新值和表中旧值相同，则表中该元组上具有该属性且不在更新字段内的字段值不变，将保持原有值；若具有该属性的字段在更新字段内，则对应这些字段值直接按指定更新的值更新。
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  - 该属性支持在MYSQL模式数据库中的5.7版本下指定（即sql_compatibility = 'MYSQL'、b_format_version='5.7'、b_format_dev_version='s1'）和PG模式数据库模式中指定（升级观察期间不支持该语法）。
  
  - 语法上update_expr支持CURRENT_TIMESTAMP、LOCALTIMESTAMP、NOW()三种关键字，也支持关键字带括号指定或不指定精度。三种关键字互为同义词，属性效果相同。例如：ON UPDATE CURRENT_TIMESTAMP()、ON UPDATE CURRENT_TIMESTAMP(5)、ON UPDATE LOCALTIMESTAMP()、ON UPDATE LOCALTIMESTAMP(6)等。不带括号或空括号时精度为0，其中NOW关键字不支持不带括号。PG兼容模式下不支持ON UPDATE CURRENT_TIMESTAMP()、ON UPDATE LOCALTIMESTAMP()和ON UPDATE NOW(5)。
  
  - 该属性仅支持在如下类型的列上指定：timestamp、datetime、date、time without time zone、smalldatetime、abstime。
  
  - CREATE TABLE AS语法不会继承该列属性。
  
  - CREATE TABLE LIKE语法可通过INCLUDING UPDATE或EXCLUDING UPDATE来选择继承或排除该约束，PG兼容模式下只支持EXCLUDING UPDATE选项排除该约束。新增INCLUDING ILM选项复制旧表的ilm策略信息，结合INCLUDING PARTITION选项使用可以复制旧表上分区对象的策略信息。
  
  - 该属性指定的精度和对应列上类型指定的精度可以不一致，通过该属性更新字段值后显示结果按最小精度显示。例如：CREATE TABLE t1 (col1 timestamp(6) ON UPDATE CURRENT_TIMESTAMP(3)); 若UPDATE语法触发该属性生效，则本次更新后col1字段值小数位显示3位。
  
  - 该属性和生成列约束不能同时指定同一列。
  
  - 分区表中的分区键不支持指定该属性。
  
  - 分布式场景中，分布列和主键不支持指定该属性。
    
- **AUTO_INCREMENT**
  该关键字将字段指定为自动增长列。
  目前自动增长列默认为本地自动增长列，在各个DN上独立增长，互不影响，自增值全局不唯一。
  若在插入时不指定此列的值（或指定此列的值为0、NULL或DEFAULT），此列的值将由自增计数器自动增长得到。
  若插入或更新此列为一个大于当前自增计数器的值，执行成功后，自增计数器将刷新为此值。
  自增初始值由AUTO_INCREMENT \[ = \] value子句设置，若不设置，默认为1。
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  - 仅在参数sql_compatibility='MYSQL'时可以指定自动增长列。
  
  - 自动增长列数据类型只能为整数类型、4字节或8字节浮点类型、布尔类型。 当自增值已经达到字段数据类型的最大值时，继续自增将产生错误。
    
  
  - 每个表只能有一个自动增长列。
  
  - 本地自动增长列建议为索引（非全局二级索引）的第一个字段，否则含有自动增长列的表进行某些操作时会产生错误，例如：ALTER TABLE EXCHANGE PARTITION。
  
  - 自动增长列不能指定DEFAULT缺省值。
  
  - CHECK约束的表达式中不能含有自动增长列。
  
  - 可以指定自动增长列允许NULL，若不指定，默认自动增长列含有NOT NULL约束。
  
  - 含有本地自动增长列的表创建时，会在每个DN上创建一个依赖于此列的本地序列作为自增计数器，不允许通过序列相关功能修改或删除此序列，可以查看序列的值。请勿使其他序列依赖或关联此自动增长列。
  
  - 自增计数器自增和刷新操作不会回滚。
    - 数据插入到表之前，0/NULL会触发自增。数据插入或更新到表之后，会更新自增计数器。如果在自增之后出现了报错，导致数据没有插入或更新到表中，此时自增计数器不会回滚。后续插入语句基于自增计数器触发自增，会出现表中自动增长列的值不连续的情况。
    
    - 批量插入或导入预留自增缓存值也有可能产生自动增长列的值不连续的情况，详见auto_increment_cache参数说明。
     
  
  - 自动增长列不支持作为分布列。
  
  - 本地临时表暂不支持自动增长列。
    
  
  - 复制表（DISTRIBUTE BY REPLICATION）暂不支持自动增长列。
    
    
- **UNIQUE \[KEY\] index_parameters**
  UNIQUE约束表示表里的一个字段或多个字段的组合必须在全表范围内唯一。
  对于唯一约束，NULL被认为是互不相等的。
  UNIQUE KEY仅在MYSQL模式数据库下（即sql_compatibility = 'MYSQL'）支持使用，与UNIQUE语义相同。
  
- **UNIQUE \[ index_name \]\[ USING method \] ( { {column_name \| ( expression ) } \[ ASC \| DESC \] }\[, ... \] ) index_parameters**
  UNIQUE约束表示表里的一个字段或多个字段的组合必须在全表范围内唯一。
  对于唯一约束，NULL被认为是互不相等的。
  index_name为索引名。
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  - index_name仅在MYSQL模式数据库下（即sql_compatibility = 'MYSQL'）支持，其他模式数据库下不支持。
  
  - 对于唯一键约束，constraint_name和index_name同时指定时，索引名为index_name。
    
- **PRIMARY KEY index_parameters**
  **PRIMARY KEY \[ USING method \] ( { column_name \[ ASC \| DESC \] } \[, ... \] ) index_parameters**
  主键约束声明表中的一个或者多个字段只能包含唯一的非NULL值。
  一个表只能声明一个主键。
  
- **REFERENCES**
  当前版本暂不支持REFERENCES子句。
  
- **USING method**
  指定创建索引的方法。
  取值范围请参见[CREATE INDEX](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0253.html)章节中的[USING method](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0253.html#ZH-CN_TOPIC_0000002764308654__zh-cn_topic_0059777455_l65a9e951f55e4496a0e630692d227532)
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  - USING method仅在MYSQL兼容模式数据库下（即sql_compatibility = 'MYSQL'）支持，其他模式数据库下不支持。
  
  - 在MYSQL模式下，未指定USING method时，对于ASTORE的存储方式，默认索引方法为btree；对于USTORE的存储方式，默认索引方法为ubtree。
  
  - 对于默认建立全局二级索引的约束，由于全局二级索引底层使用ubtree存储，即使用户指定存储方式为btree，底层也会建立为ubtree。
  
  - 当表的存储方式为USTORE时，SQL语句中约束指定为using btree，底层会自动将约束建立为using ubtree。
    
- **ASC \| DESC**
  ASC表示指定按升序排序（默认）。DESC指定按降序排序。
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  ASC \| DESC只在MYSQL模式数据库下（即sql_compatibility = 'MYSQL'）支持，其他模式数据库不支持。
  
- **expression**
  创建一个基于该表的一个或多个字段的表达式索引约束，必须写在圆括号中。
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  UNIQUE约束中的表达式索引只在MYSQL模式数据库下支持（即sql_compatibility = 'MYSQL'），其他模式数据库不支持。
  
- **DEFERRABLE \| NOT DEFERRABLE**
  这两个关键字用于设置约束是否可推迟。不可推迟的约束将在每条命令执行后立即检查。可推迟约束可以延迟到事务结尾通过SET CONSTRAINTS命令检查，缺省值为NOT DEFERRABLE。目前UNIQUE约束和主键约束可以接受该子句，其他约束类型均不可推迟。
  
- **INITIALLY IMMEDIATE \| INITIALLY DEFERRED**
  若约束可推迟，该子句声明检查约束的缺省时间。不可推迟的约束始终为INITIALLY IMMEDIATE且不可声明为INITIALLY DEFERRED。
  - 如果约束是INITIALLY IMMEDIATE（缺省），则在每条语句执行后立即检查。
  
  - 如果约束是INITIALLY DEFERRED ，则仅在事务结束时进行检查。
  
  
  约束检查的时间可以用SET CONSTRAINTS命令修改。
  
- **USING INDEX TABLESPACE tablespace_name**
  为UNIQUE约束或PRIMARY KEY约束相关的索引声明一个表空间。如果没有提供这个子句，这个索引将在default_tablespace中创建，如果default_tablespace为空，将使用数据库的缺省表空间。
  
- DATATYPE_CL = client_logic_type 为可选参数，用于指定加密列的类型。
  取值范围：BYTEAWITHOUTORDER或者BYTEAWITHOUTORDERWITHEQUAL。
  
- **COLUMN_ENCRYPTION_KEY = column_encryption_key**
  为ENCRYPTED WITH约束中列加密密钥的名称。
  取值范围：字符串，要符合[标识符命名规范](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0003.html#ZH-CN_TOPIC_0000002793787739__section14873217506)。
  
- **ENCRYPTION_TYPE = encryption_type_value**
  为ENCRYPTED WITH约束中的加密类型，encryption_type_value的值为\[ DETERMINISTIC \| RANDOMIZED \]。
  
- **\[DEFAULT\] CHARACTER SET \| CHARSET \[ = \] default_charset**
  指定表的默认字符集，单独指定时会将表的默认字符序设置为指定的字符集的默认字符序。
  
- **\[DEFAULT\] COLLATE \[ = \] default_collation**
  指定表的默认字符序，单独指定时会将表的默认字符集设置为指定的字符序对应的字符集。
  仅在MYSQL模式数据库下（即sql_compatibility = 'MYSQL'）支持该语法。字符序参见[表1]。
  ![](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  表的字符集或字符序未显式指定时，若指定了模式的默认字符集或字符序，表字符集和字符序将从模式上继承。若模式的默认字符集或字符序不存在，当b_format_behavior_compat_options包含'default_collation'时，表的字符集和字符序将继承当前数据库的字符集及其对应的默认字符序。
  
 
#### 建表示例
- **创建普通表**
  ```
  gaussdb=# CREATE TABLE tbl_test1(
      id       int,
      name     varchar(50),
      province varchar (60), --省
      country  varchar (60) DEFAULT 'China' --国籍
  );
  gaussdb=# DROP TABLE tbl_test1;
  ```
  
- **WITH子句为表或者索引增加存储参数**
  ```
  --建表指定填充因子。
  gaussdb=# CREATE TABLE tbl_test2(
      id       int,
      name     varchar(50),
      province varchar (60), --省
      country  varchar (60) DEFAULT 'China' --国籍
  ) WITH (FILLFACTOR = 70);
  --建表指定存储引擎。
  gaussdb=# CREATE TABLE tbl_test3(
      id       int,
      name     varchar(50),
      province varchar (60), --省
      country  varchar (60) DEFAULT 'China' --国籍
  ) WITH (STORAGE_TYPE = ASTORE);
  --删除。
  gaussdb=# DROP TABLE tbl_test2;
  gaussdb=# DROP TABLE tbl_test3;
  ```
  
- **加密表**
  使用该参数前，请确保已通过GUC参数enable_tde开启透明加密功能，并通过GUC参数tde_key_info设置访问密钥服务的信息，在《开发指南》中"特性使用指导 \> 透明数据加密"章节可获取该参数的详细使用方法。
  ```
  gaussdb=# CREATE TABLE  t1 (c1 TEXT) WITH (enable_tde=on);
  --删除表。
  gaussdb=# DROP TABLE t1;
  ```
  
- **临时表**
  ```
  --创建临时表，并指定提交事务时删除该临时表数据。
  gaussdb=# CREATE TEMPORARY TABLE test_t2(
      id       CHAR(7),
      name     VARCHAR(20),
      province VARCHAR(60),                       --省
      country   VARCHAR(30) DEFAULT 'China'        --国籍
  ) ON COMMIT DELETE ROWS;
  gaussdb=# DROP TABLE test_t2;
  ```
  
- **建表时指定字符集字符序**
  ```
  --创建前置数据库。
  gaussdb=# CREATE DATABASE testdb1 ENCODING = 'UTF8';
  gaussdb=# \c testdb1
  --创建t1表，设置t1的默认字符集为utf8mb4，默认字符序为utf8mb4_bin，设置c1字段为表的默认字符集字符序，设置c2字段的字符集为utf8mb4，字符序为utf8mb4_unicode_ci。
  testdb1=# CREATE TABLE t1(c1 text, c2 text charset utf8mb4 collate utf8mb4_unicode_ci) charset utf8mb4 collate utf8mb4_bin;
  --删除。
  testdb1=# DROP TABLE t1;
  testdb1=# \c postgres
  gaussdb=# DROP DATABASE testdb1;
  ```
  
- **IF NOT EXISTS关键字**
  使用该关键字，表不存在时报NOTICE；如不用该关键字，则报ERROR。两种情况下表都不会创建成功。
  ```
  gaussdb=# CREATE TABLE test_t3(id INT);
  --创建一个已经存在同名的表test_t3。
  gaussdb=# CREATE TABLE test_t3(id INT);
  ERROR:  Relation "test_t3" already exists in schema "public".
  DETAIL:  Creating new table with existing name in the same schema.
  --使用IF NOT EXISTS关键字。
  gaussdb=# CREATE TABLE IF NOT EXISTS test_t3(id INT);
  NOTICE:  Relation test_t3 already exists, skipping.
  CREATE TABLE
  --删除表。
  gaussdb=# DROP TABLE test_t3;
  ```
  
- **建表时指定表空间**
  ```
  --创建表空间。
  gaussdb=# CREATE TABLESPACE ds_tbs1 RELATIVE LOCATION 'tablespace/tablespace_1';
  --创建表时，指定表空间。
  gaussdb=# CREATE TABLE test(id CHAR(7), name VARCHAR(20)) TABLESPACE ds_tbs1;
  --删除表和表空间。
  gaussdb=# DROP TABLE test;
  gaussdb=# DROP TABLESPACE ds_tbs1;
  ```
  
 
- **建表时指定AUTO_INCREMENT自增列**
  ```
  --本地自增列不作为分布列，每个DN从10开始自增（根据实际情况修改DATANODE名字，SELECT node_name FROM pgxc_node WHERE node_type = 'D';）。
  gaussdb=# CREATE TABLE local_autoinc(col int AUTO_INCREMENT, col1 int) AUTO_INCREMENT = 10
  DISTRIBUTE BY LIST(col1)(
      SLICE s1 VALUES (1) DATANODE datanode1,
      SLICE s2 VALUES (2) DATANODE datanode2
  );
  --建议自增列作为索引首列，创建一个索引。
  gaussdb=# CREATE INDEX local_autoinc_ai ON local_autoinc(col);
  --数据分布到DN1上，NULL触发自增，自增值为10。
  gaussdb=# INSERT INTO local_autoinc(col, col1) VALUES(NULL,1);
  --数据分布到DN2上，0触发自增，自增值为10。
  gaussdb=# INSERT INTO local_autoinc(col, col1) VALUES(1 - 1,2);
  --数据分布到DN1上，100不触发自增，插入成功后，自增计数更新为100。
  gaussdb=# INSERT INTO local_autoinc(col, col1) VALUES(100,1);
  --数据分布到DN1上，0触发自增，自增值为101。
  gaussdb=# INSERT INTO local_autoinc(col, col1) VALUES(0,1);
  --数据分布到DN2上，DEFAULT触发自增，自增值为11。
  gaussdb=# INSERT INTO local_autoinc(col, col1) VALUES(DEFAULT,2);
  gaussdb=# SELECT col,col1 FROM local_autoinc ORDER BY 2,1;
   col | col1
  -----+------
    10 |    1
   100 |    1
   101 |    1
    10 |    2
    11 |    2
  (5 rows)
  --删除。
  gaussdb=# DROP TABLE local_autoinc;
  ```
  
- **CREATE TABLE ... LIKE建表**
  ```
  --创建源表t1。
  gaussdb=# CREATE TABLE t1(col INT);
  CREATE TABLE
  gaussdb=# \d t1
        Table "public.t1"
   Column |  Type   | Modifiers 
  --------+---------+-----------
   col    | integer |
  --创建目标表t2。
  gaussdb=# CREATE TABLE t2(LIKE t1);
  CREATE TABLE
  gaussdb=# \d t2
        Table "public.t2"
   Column |  Type   | Modifiers 
  --------+---------+-----------
   col    | integer | 
  --删除。
  gaussdb=# DROP TABLE t1,t2;
  ```
  
#### 建表添加约束示例
- **非空约束**
  非空约束的字段，如果在添加数据时没有指定值，就会报错。可以为表中多个字段添加非空约束。
  ```
  --建表并给id字段添加非空约束。
  gaussdb=# CREATE TABLE test_t4(
      id       CHAR(7) NOT NULL,
      name     VARCHAR(20),
      province VARCHAR(60),                       --省
      country   VARCHAR(30) DEFAULT 'China'        --国籍
  );
  --插入数据时,如果不指定id的值或者id为NULL，会触发非空约束,导致插入失败。
  gaussdb=# INSERT INTO test_t4 (name,province) VALUES ('scott','Shanghai');
  ERROR: The null value in column "id" violates the not-null constraint.
  DETAIL: Failing row contains (null, scott, Shanghai, China).
  --删除表。
  gaussdb=# DROP TABLE test_t4;
  ```
  
- **唯一约束**
  关键字UNIQUE给字段添加一个唯一约束，插入数据时该字段如有重复则触发约束，多个NULL不算重复，添加唯一约束时，会自动增加一个唯一索引。可以为表中多个字段添加唯一约束。
  ```
  --建表添加唯一约束。
  gaussdb=# CREATE TABLE test_t5(
      id       CHAR(7) UNIQUE USING INDEX TABLESPACE pg_default,
      name     VARCHAR(20),
      province VARCHAR(60),                       --省
      country   VARCHAR(30) DEFAULT 'China'        --国籍
  );
  --也可以用如下写法，为唯一约束命名，以及为多个字段添加约束。
  gaussdb=# CREATE TABLE test_t6(
      id       CHAR(7),
      name     VARCHAR(20),
      province VARCHAR(60),                        --省
      country   VARCHAR(30) DEFAULT 'China',        --国籍
      CONSTRAINT unq_test_id UNIQUE (id,name)
  );
  --插入id重复的数据，触发约束，导致插入失败。
  gaussdb=# INSERT INTO test_t5(id) VALUES('0000010');
  INSERT 0 1
  gaussdb=# INSERT INTO test_t5(id) VALUES('0000010');
  ERROR:  Duplicate key value violates unique constraint "test_t5_id_key".
  DETAIL:  Key (id)=(0000010) already exists.
  --多次插入id是NULL的数据不会触发约束。
  gaussdb=# INSERT INTO test_t5(id) VALUES (NULL);
  INSERT 0 1
  gaussdb=# INSERT INTO test_t5(id) VALUES (NULL);
  INSERT 0 1
  --删除表。
  gaussdb=# DROP TABLE test_t5;
  gaussdb=# DROP TABLE test_t6;
  ```
  
- **主键约束**
  关键字PRIMARY KEY给字段添加唯一约束，要求字段唯一且不为空。添加主键约束时自动为该表创建唯一索引，也会为该字段自动增加一个非空约束。
  每个表里面只能定义一个主键约束，不能定义多个。
  ```
  --建表添加主键约束。
  gaussdb=# CREATE TABLE test_t6(
      id       CHAR(7) PRIMARY KEY,
      name     VARCHAR(20),
      province VARCHAR(60),                       --省
      country   VARCHAR(30) DEFAULT 'China'        --国籍
  );
  gaussdb=# INSERT INTO test_t6 (id,name,province) VALUES ('0000001','july','Beijing');
  --也可以用如下写法，人工为唯一约束命名，以及为多个字段添加约束。
  gaussdb=# CREATE TABLE test_t7(
      id       CHAR(7),
      name     VARCHAR(20),
      province VARCHAR(60),                       --省
      country   VARCHAR(30) DEFAULT 'China',        --国籍
      CONSTRAINT pk_test_t6_id PRIMARY KEY (id,name)
  );
  --插入id为NULL的数据，触发约束。
  gaussdb=# INSERT INTO test_t6 (id,name,province) VALUES (NULL,'july','Beijing'); 
  ERROR:  The null value in column "id" violates the not-null constraint.
  DETAIL:  Failing row contains (null, july, Beijing, China).
  --插入id重复的数据，触发约束。
  gaussdb=# INSERT INTO test_t6 (id,name,province) VALUES ('0000001','ben','Shanghai');
  ERROR:  Duplicate key value violates unique constraint "test_t6_pkey"
  DETAIL:  Key (id)=(0000001) already exists.
  --删除表。
  gaussdb=# DROP TABLE test_t6;
  gaussdb=# DROP TABLE test_t7;
  ```
  
- **检查约束**
  关键字CHECK为字段添加检查约束，在检查约束中必须引用表中的一个或多个字段，并且表达式返回结果必须是一个布尔值。在表达式中不能包含子查询。对同一个字段可以同时定义检查约束和非空约束。
  ```
  --建表，添加检查约束。
  gaussdb=# CREATE TABLE test_t8 (
      id       CHAR(7),
      name     VARCHAR(20),
      age      INT CHECK(age > 0 AND age < 150)
  );
  --也可以使用如下SQL，人工为检查约束命名以及为一个或者多个字段添加检查约束。
  gaussdb=# CREATE TABLE test_t9 (
      id       CHAR(7),
      name     VARCHAR(20),
      age      INT,
      CONSTRAINT chek_test_t8_age CHECK(age > 0 AND age < 150)
  );
  --插入不符合表达式的值，会触发检查约束导致插入失败。
  gaussdb=# INSERT INTO test_t8 (id,name,age) VALUES ('0000007','scott',200);
  ERROR:  New row for relation test_t8 violates check constraint test_t8_age_check.
  DETAIL:  N/A
  --删除表。
  gaussdb=# DROP TABLE test_t8;
  gaussdb=# DROP TABLE test_t9;
  ```
  
 
#### 表数据分布示例
- **REPLICATION**
  ```
  gaussdb=# CREATE TABLE test_replication(
      id       CHAR(7),
      name     VARCHAR(20),
      province VARCHAR(60),                       --省
      country   VARCHAR(30) DEFAULT 'China'        --国籍
  )DISTRIBUTE BY REPLICATION;
  --查询表信息。
  gaussdb=# \d+ test_replication
                                          Table "public.test_replication"
    Column  |         Type          |             Modifiers              | Storage  | Stats target | Description 
  ----------+-----------------------+------------------------------------+----------+--------------+-------------
   id       | character(7)          |                                    | extended |              | 
   name     | character varying(20) |                                    | extended |              | 
   province | character varying(60) |                                    | extended |              | 
   country  | character varying(30) | default 'China'::character varying | extended |              | 
  Has OIDs: no
  Distribute By: REPLICATION
  Location Nodes: ALL DATANODES
  Options: orientation=row, logical_repl_node=-1, compression=no, storage_type=USTORE, segment=off
  --删除。
  gaussdb=# DROP TABLE test_replication;
  ```
  
- **HASH**
  ```
  --定义一个表，使用HASH分布。
  gaussdb=# CREATE TABLE test_hash(
      id       CHAR(7),
      name     VARCHAR(20),
      province VARCHAR(60),                       --省
      country   VARCHAR(30) DEFAULT 'China'        --国籍
  )DISTRIBUTE BY HASH(id);
  --插入数据。
  gaussdb=# INSERT INTO test_hash VALUES ('0000001', 'Bob',   'Shanghai', 'China'),
                              ('0000002', 'Jack',  'Beijing',  'China'), 
                              ('0000003', 'Scott', 'Beijing',  'China');
  ```
  ```
  --查看数据分布情况。
  gaussdb=# SELECT a.count,b.node_name 
  FROM (SELECT COUNT(*) AS count, xc_node_id FROM test_hash GROUP BY xc_node_id) a, 
       pgxc_node b 
  WHERE a.xc_node_id=b.node_id ORDER BY a.count DESC;
   
  count |     node_name     
  -------+-------------------
       2 | dn_6001_6002_6003
       1 | dn_6004_6005_6006
  (2 rows)
  ```
  ```
  --删除表。
  gaussdb=# DROP TABLE test_hash;
  ```
  
- **MURMURHASH**
  ```
  --测试环境包含1个CN和6个DN。
  --创建NODE GROUP，NODE GROUP中的DN名字可以通过语句SELECT node_name FROM PGXC_NODE WHERE node_type = 'D';查询，查询的结果按需替换CREATE NODE GROUP语句中WITH后的DN名。
  gaussdb=# CREATE NODE GROUP NG1 WITH(datanode1, datanode2, datanode3, datanode4, datanode5, datanode6);
  --定义一个表，使用MURMURHASH分布。
  gaussdb=# CREATE TABLE test_murmurhash1 (a int NOT NULL, b int) DISTRIBUTE BY MURMURHASH(a) TO GROUP NG1;
  gaussdb=# CREATE TABLE test_murmurhash2 (a int NOT NULL, b int) DISTRIBUTE BY MURMURHASH(lpad_s(a,10,'0')) TO GROUP NG1;
  --插入数据。
  gaussdb=# INSERT INTO test_murmurhash1 VALUES(0,1);
  gaussdb=# INSERT INTO test_murmurhash2 VALUES(1,2);
  --查询数据。
  gaussdb=# SELECT * FROM test_murmurhash1;
   a | b 
  ---+---
   0 | 1
  (1 row)
  gaussdb=# SELECT * FROM test_murmurhash2;
   a | b 
  ---+---
   1 | 2
  (1 row)
  --删除表。
  gaussdb=# DROP TABLE test_murmurhash1;
  gaussdb=# DROP TABLE test_murmurhash2;
  --删除NODE GROUP。
  gaussdb=# DROP NODE GROUP NG1;
  ```
  
- **RANGE**
  ```
  --定义一个表，使用RANGE分布（需要根据实际情况修改DN名字，查询DN节点名可以通过语句SELECT node_name FROM PGXC_NODE WHERE node_type = 'D';查询）。
  gaussdb=# CREATE TABLE test_range(
      id       INT,
      name     VARCHAR(20),
      province VARCHAR(60),                       --省
      country   VARCHAR(30) DEFAULT 'China'        --国籍
  )DISTRIBUTE BY RANGE(id)(
      SLICE s1 VALUES LESS THAN (100) DATANODE dn_6001_6002_6003,
      SLICE s2 VALUES LESS THAN (200) DATANODE dn_6004_6005_6006,
      SLICE s3 VALUES LESS THAN (MAXVALUE) DATANODE dn_6007_6008_6009
  );
  --插入数据。
  gaussdb=# INSERT INTO test_range VALUES (52,  'Bob',    'Beijing',   'China');
  gaussdb=# INSERT INTO test_range VALUES (100, 'Ben',    'Shanghai',  'China');
  gaussdb=# INSERT INTO test_range VALUES (150, 'Scott',  'Guangzhou', 'China');
  gaussdb=# INSERT INTO test_range VALUES (300, 'Jordan', 'Beijing',   'China');
  --查看数据分布情况。
  gaussdb=# SELECT a.count,b.node_name 
  FROM (SELECT COUNT(*) AS count, xc_node_id FROM test_range GROUP BY xc_node_id) a, 
       pgxc_node b 
  WHERE a.xc_node_id=b.node_id ORDER BY a.count DESC;
   count |     node_name     
  -------+-------------------
       2 | dn_6004_6005_6006
       1 | dn_6001_6002_6003
       1 | dn_6007_6008_6009
  (3 rows)
  --查询各DN上存储的数据。
  gaussdb=# SELECT b.node_name, a.* 
  FROM (SELECT *, xc_node_id FROM test_range) a, 
       pgxc_node b 
  WHERE a.xc_node_id=b.node_id order by node_name;
       node_name     | id  |  name  | province  | country | xc_node_id  
  -------------------+-----+--------+-----------+---------+-------------
   dn_6001_6002_6003 |  52 | Bob    | Beijing   | China   | -1072999043
   dn_6004_6005_6006 | 100 | Ben    | Shanghai  | China   |  -564789568
   dn_6004_6005_6006 | 150 | Scott  | Guangzhou | China   |  -564789568
   dn_6007_6008_6009 | 300 | Jordan | Beijing   | China   |  1532339558
  (4 rows)
  --删除表。
  gaussdb=# DROP TABLE test_range;
  ```
  
- **LIST**
  ```
  --定义一个表，使用LIST分布（需要根据实际情况修改DN名字，查询DN节点名可以通过语句SELECT node_name FROM PGXC_NODE WHERE node_type = 'D';查询）。
  gaussdb=# CREATE TABLE test_list(
      id       INT,
      name     VARCHAR(20),
      country   VARCHAR(30) DEFAULT 'China'        --国籍
  )DISTRIBUTE BY LIST(country)(
      SLICE s1 VALUES ('China') DATANODE dn_6001_6002_6003,
      SLICE s2 VALUES ('USA')   DATANODE dn_6004_6005_6006,
      SLICE s3 VALUES (DEFAULT) DATANODE dn_6007_6008_6009
  );
  --插入数据。
  gaussdb=# INSERT INTO test_list VALUES (1,'Scott','China');
  gaussdb=# INSERT INTO test_list VALUES (2,'Henry','USA');
  gaussdb=# INSERT INTO test_list VALUES (3,'Michael','France');
  gaussdb=# INSERT INTO test_list VALUES (4,'Jack','UK');
  --查询各DN上存储的数据。
  gaussdb=# SELECT b.node_name, a.* 
  FROM (SELECT *, xc_node_id FROM test_list) a, 
       pgxc_node b 
  WHERE a.xc_node_id=b.node_id order by node_name;
       node_name     | id |  name   | country | xc_node_id  
  -------------------+----+---------+--------+-------------
   dn_6001_6002_6003 |  1 | Scott   | China  | -1072999043
   dn_6004_6005_6006 |  2 | Henry   | USA    |  -564789568
   dn_6007_6008_6009 |  3 | Michael | France |  1532339558
   dn_6007_6008_6009 |  4 | Jack    | UK     |  1532339558
  (4 rows)
  --删除表。
  gaussdb=# DROP TABLE test_list;
  ```
  
 
#### 相关链接
[ALTER TABLE](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0211.html)，[DROP TABLE](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0322.html)，[CREATE TABLESPACE](https://support.huaweicloud.com/distributed-ref-v10-gaussdb/gaussdb-08-0272.html)
#### 优化建议
- UNLOGGED
  - UNLOGGED表和表上的索引因为数据写入时不通过WAL日志机制，写入速度远高于普通表。因此，可以用于缓冲存储复杂查询的中间结果集，增强复杂查询的性能。
  
  - UNLOGGED表无主备机制，在系统故障或异常断点等情况下，会有数据丢失风险，因此，不可用来存储基础数据。
   
- TEMPORARY \| TEMP
  - 临时表只在当前会话可见，会话结束后会自动删除。
  
  - 除了当前CN外，其他CN对于该临时表不可见。
   
- LIKE
  - 新表自动从这个表中继承所有字段名及其数据类型和非空约束，新表与源表之间在创建动作完毕之后是完全无关的。
   
- LIKE INCLUDING DEFAULTS
  - 源表上的字段缺省表达式仅在指定INCLUDING DEFAULTS时，才会复制到新表中。缺省是不包含缺省表达式的，即新表中的所有字段的缺省值都是NULL。
   
- LIKE INCLUDING CONSTRAINTS
  - 源表上的CHECK约束仅在指定INCLUDING CONSTRAINTS时，才会复制到新表中，其他类型的约束不会复制到新表中。非空约束总是复制到新表中。此规则同时适用于表约束和列约束。
   
- LIKE INCLUDING INDEXES
  - 如果指定了INCLUDING INDEXES，则源表上的索引也将在新表上创建，默认情况下，不建立索引。新表上的索引所在表空间和源表上的索引所在表空间保持一致。
   
- LIKE INCLUDING STORAGE
  - 如果指定了INCLUDING STORAGE，则复制列的STORAGE设置会复制到新表中，默认情况下，不包含STORAGE设置。
   
- LIKE INCLUDING COMMENTS
  - 如果指定了INCLUDING COMMENTS，则源表列、约束和索引的注释会复制到新表中。默认情况下，不复制源表的注释。
   
- LIKE INCLUDING PARTITION
  - 如果指定了INCLUDING PARTITION，则源表的分区定义会复制到新表中，同时新表将不能再使用PARTITION BY子句。默认情况下，不复制源表的分区定义。
   
- LIKE INCLUDING RELOPTIONS
  - 如果指定了INCLUDING RELOPTIONS，则源表的存储参数（即源表的WITH子句）会复制到新表中。默认情况下，不复制源表的存储参数。
   
- LIKE INCLUDING DISTRIBUTION
  - 如果指定了INCLUDING DISTRIBUTION，则源表的分布信息会复制到新表中，包括分布类型和分布列，同时新表将不能再使用DISTRIBUTE BY子句。默认情况下，不复制源表的分布信息。
   
- LIKE INCLUDING ALL
  - INCLUDING ALL包含了INCLUDING DEFAULTS、INCLUDING CONSTRAINTS、INCLUDING INDEXES、INCLUDING STORAGE、INCLUDING COMMENTS、INCLUDING PARTITION、INCLUDING RELOPTIONS、INCLUDING DISTRIBUTION和INCLUDING ILM的内容。
   
- ORIENTATION ROW
  - 创建行存表，行存储适合于OLTP业务，此类型的表上交互事务比较多，一次交互会涉及表中的多个列，用行存查询效率较高。
   
- DISTRIBUTE BY
  - 事实表或者数据量较大的维度表建议创建为分布表。对指定的列进行Hash操作，通过映射，把数据分布到指定DN。语法为：DISTRIBUTE BY HASH(column_name)。
  
  - 数据量较小的维度表建议创建为复制表。表的每条记录存在所有数据节点（DN）中，即每个数据节点都有完整的表数据。语法为：DISTRIBUTE BY REPLICATION。
   
 
