
# CREATE TABLE PARTITION
#### 功能描述
创建分区表。分区表是把逻辑上的一张表根据某种方案分成几张物理块进行存储，这张逻辑上的表称之为分区表，物理块称之为分区。分区表是一张逻辑表，不存储数据，数据实际是存储在分区上的。
常见的分区方案有范围分区（Range Partitioning）、哈希分区（Hash/Key Partitioning）、列表分区（List Partitioning）、列分区（Range/List Columns Partitioning）等。目前行存表支持范围分区、哈希分区、列表分区。
**范围分区（Range Partitioning）：**
- 范围分区是根据表的一列或者多列，将要插入表的记录分为若干个范围，这些范围在不同的分区里没有重叠。为每个范围创建一个分区，用来存储相应的数据。
- 范围分区的分区策略是指记录插入分区的方式。目前范围分区仅支持范围分区策略。

- 范围分区策略：最常用的分区策略为根据分区键值将记录映射到已创建的某个分区上，如果可以映射到已创建的某一分区上，则把记录插入到对应的分区上，否则返回报错和提示信息。
**哈希分区（Hash/Key Partitioning）：**
- 哈希分区是根据表的一列，为每个分区指定模数和余数，将要插入表的记录划分到对应的分区中，每个分区所持有的行都需要满足条件：分区键的值除以为其指定的模数将产生为其指定的余数。
- 哈希分区策略：根据分区键值将记录映射到已创建的某个分区上，如果可以映射到已创建的某一分区上，则把记录插入到对应的分区上，否则返回报错和提示信息。
**列表分区（List Partitioning）**：
- 列表分区是根据表的一列，将要插入表的记录通过每一个分区中出现的键值划分到对应的分区中，这些键值在不同的分区里没有重叠。为每组键值创建一个分区，用来存储相应的数据。
- 列表分区策略：根据分区键值将记录映射到已创建的某个分区上，如果可以映射到已创建的某一分区上，则把记录插入到对应的分区上，否则返回报错和提示信息。
分区存在以下优势：
- 某些类型的查询性能可以得到极大提升。特别是表中访问率较高的行位于一个单独分区或少数几个分区上的情况下。分区可以减少数据的搜索空间，提高数据访问效率。
- 当查询或更新一个分区的大部分记录时，连续扫描该分区而不是访问整个表可以获得巨大的性能提升。
- 如果需要大量加载或者删除的记录位于单独的分区上，则可以通过直接读取或删除该分区以获得巨大的性能提升，同时还可以避免由于大量DELETE导致的VACUUM超载（哈希分区不支持删除分区）。
 
#### 注意事项
- 当为分布表添加唯一约束或主键约束时，如果约束的约束键包含所有分区键，将为约束创建LOCAL索引，否则创建GLOBAL索引。
- 目前哈希分区仅支持单列构建分区键，暂不支持多列构建分区键。
- 对于分区表PARTITION FOR (values)语法，values只能是常量。
- 对于分区表PARTITION FOR (values)语法，values在需要数据类型转换时，建议使用强制类型转换，以防隐式类型转换结果与预期不符。
- 分区数最大值为1048575个，一般情况下业务不可能创建这么多分区，这样会导致内存不足。应参照参数local_syscache_threshold的值合理创建分区，分区表使用内存大致为（分区数 \* 3 / 1024）MB。理论上分区占用内存不允许大于local_syscache_threshold的值，同时还需要预留部分空间以供其他功能使用。
- 考虑性能影响，一般建议单表最大分区数不超过2000，子分区数 \*（local索引个数 + 1） 不超过10000。
- 当分区数太多导致内存不足时，会间接导致性能急剧下降。
- 指定分区语句目前不能走全局索引扫描。
- 不支持如下数据类型作为分区键、二级分区键：BLOB、TINYBLOB、MEDIUMBLOB、LONGBLOB、TEXT、TINYTEXT、MEDIUMTEXT、LONGTEXT、BIT。
- 对分区表并发执行UPDATE和DELETE操作时，可能会引发错误。以下为具体原因及行为分析： UPDATE和DELETE操作对于旧数据的行为都是标记为已删除。当更新分区键导致跨分区操作时，数据库会将旧分区中的旧数据标记为已删除，同时在新分区中新增一条数据。这种操作机制可能导致后续操作无法正确关联旧数据与新数据，进而引发错误。
  - UPDATE和UPDATE/DELETE并发：第一个UPDATE操作完成后，第二个UPDATE/DELETE操作无法成功定位到最新数据，导致操作失败并报错。
  
  - DELETE和UPDATE/DELETE并发：第一个DELETE操作完成后，第二个UPDATE/DELETE操作检测到数据已被删除且无法匹配到最新数据，由于无法判断删除操作是UPDATE的行为还是DELETE的行为，系统只能报错处理。
  
  
  优化建议：对于分区表的UPDATE以及DELETE操作，尽量使用串行执行的方式，以避免数据关联问题。查询时根据分区键过滤数据，避免全表扫描操作。避免超大事务，将涉及大量数据的UPDATE以及DELETE操作进行分批执行。
  
 
#### 语法格式
```
CREATE TABLE [ IF NOT EXISTS ] partition_table_name
 {( [ 
    { column_name data_type [ {CHARACTER SET | CHAR SET | CHARSET} charset ] [ COLLATE collation ] [ column_constraint [ ... ] ]
    | table_constraint
    | LIKE source_table [ TableLikeOptionList ]
] )       
    [ table_option [ [ , ] ... ] ]
    [ WITH ( {storage_parameter = value} [, ... ] ) ]
    [ TABLESPACE tablespace_name ]
    [ DISTRIBUTE BY 
        { REPLICATION 
        | HASH ( column_name [, ...] ) 
        | RANGE ( column_name [, ...] ) { SLICE REFERENCES tablename | ( slice_less_than_item [, ...] )
        | LIST ( column_name [, ...] ) { SLICE REFERENCES tablename | ( slice_values_item [, ...] ) }
        }
     [ TO { GROUP groupname | NODE ( nodename [, ... ] ) } ]
     PARTITION BY { 
        {RANGE [COLUMNS] (partition_key) [ PARTITIONS integer ] ( partition_less_than_item [, ... ] ) [partition_options] } |
        {RANGE [COLUMNS] (partition_key) [ PARTITIONS integer ] ( partition_start_end_item [, ... ] ) [partition_options] } |
        {LIST [COLUMNS] (partition_key)  [ PARTITIONS integer ] ( PARTITION partition_name VALUES [IN] (list_values)  [TABLESPACE [=] tablespace_name][, ... ] [partition_options] )} |
        {{ HASH | KEY } (partition_key) [ PARTITIONS integer ] ( PARTITION partition_name  [TABLESPACE [=] tablespace_name][partition_options] [, ... ])]}
    }
    INTERNAL DATA data_content];
```
- 其中table_option为：
  ```
  [DEFAULT] CHARACTER SET [=] charset_name
    | [DEFAULT] COLLATE [=] collation_name
    | COMMENT [=] 'string'
    | ENGINE [=] engine_name
    | ROW_FORMAT [=] {DEFAULT | DYNAMIC | FIXED | COMPRESSED | REDUNDANT | COMPACT}
  }
  ```
  ![](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  - 同一个地方多次设置COMMENT时仅最后一个生效。
  
  - 同一个地方多次设置COLLATE时仅最后一个生效。
  
  - ENGINE、ROW_FORMAT使用时语法不报错也没有提示，但实际不生效。
    
- 列约束column_constraint：
  ```
  [ CONSTRAINT constraint_name ]
  { NOT NULL |
    NULL | 
    CHECK ( expression ) | 
    DEFAULT default_expr | 
    ON UPDATE update_expr |
    COMMENT 'string' |
    UNIQUE [KEY] index_parameters | 
    PRIMARY KEY index_parameters |
   }
  ```
  
- 表约束table_constraint：
  ```
  [ CONSTRAINT [ constraint_name ] ]
  { CHECK ( expression ) | 
    UNIQUE [ index_name ][ USING method ] ( { column_name [ ASC | DESC ] } [, ... ] ) index_parameters | 
    PRIMARY KEY [ USING method ] ( { column_name [ ASC | DESC ] } [, ... ] ) index_parameters 
    
         }
  ```
  

- 其中TableLikeOptionList为：
  ```
  TableLikeOptionList包含TableLikeIncludingOption和TableLikeExcludingOption
  两者都可以是：
      DEFAULTS | CONSTRAINTS | INDEXES | STORAGE | COMMENTS
     | PARTITION | RELOPTIONS | DISTRIBUTION | OIDS | GENERATED   | UPDATE | IDENTITY | ALL
  ```
  
- 索引存储参数index_parameters：
  ```
  [ WITH ( {storage_parameter = value} [, ... ] ) ]
  [ USING method ]
  [ COMMENT 'string']
  ```
  
 
- partition_less_than_item：
  ```
  PARTITION partition_name VALUES LESS THAN {( { partition_value | MAXVALUE } [,...] ) | MAXVALUE }[TABLESPACE [=] tablespace_name]
  ```
  
- partition_start_end_item：
  ```
  PARTITION partition_name {
          {START(partition_value) END ({partition_value | MAXVALUE})} |
          {START(partition_value)} |
          {END({partition_value | MAXVALUE})}
  } [TABLESPACE [=] tablespace_name]
  ```
  
- partition_options为：
  ```
  ENGINE [=] ’string’ |
  STORAGE ENGINE [=] ’string’
  ```
  当前仅语法上不报错，但此语法无实际作用。
  
- 其中update_expr为：
  ```
  { CURRENT_TIMESTAMP | LOCALTIMESTAMP | NOW() }
  ```
  
#### 参数说明
- **IF NOT EXISTS**
  如果已经存在相同名称的表，不会抛出一个错误，而会发出一个通知，告知表关系已存在。
  
- **partition_table_name**
  分区表的名称。
  取值范围：字符串，要符合[标识符说明](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/gaussdb-81-0040.html#ZH-CN_TOPIC_0000002558805265)。
  
- **column_name**
  新表中要创建的字段名。
  取值范围：字符串，要符合[标识符说明](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/gaussdb-81-0040.html#ZH-CN_TOPIC_0000002558805265)。
  
- **data_type**
  字段的数据类型。
  
- **CONSTRAINT constraint_name**
  列约束或表约束的名称。可选的约束子句用于声明约束，新行或者更新的行必须满足这些约束才能成功插入或更新。
  定义约束有两种方法：
  - 列约束：作为一个列定义的一部分，仅影响该列。
  
  - 表约束：不和某个列绑在一起，可以作用于多个列。constraint_name为可选项
   
- **index_name**
  索引名。
  ![](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  对于唯一键约束，constraint_name和index_name同时指定时，索引名为index_name。
  
- **USING method**
  指定创建索引的方法。
  取值范围参考[参数说明](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/gaussdb-81-0073.html#ZH-CN_TOPIC_0000002558925201__zh-cn_topic_0000002526893586_zh-cn_topic_0000001736086436_zh-cn_topic_0283136578_zh-cn_topic_0237122106_zh-cn_topic_0059777455_s82e47e35c54c477094dcafdc90e5d85a)中的USING method。
  ![](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  目前只支持索引方法为btree。
  
- **ASC \| DESC**
  ASC表示指定按升序排序（默认）。DESC指定按降序排序。
  
- **LIKE source_table** \[like_option...\]
  LIKE子句声明一个表，新表自动从这个表里面继承所有字段名及其数据类型和非空约束。
  和INHERITS不同，新表与原来的表之间在创建动作完毕之后是完全无关的。在源表做的任何修改都不会传播到新表中，并且也不可能在扫描源表的时候包含新表的数据。
  - 字段缺省表达式只有在声明了INCLUDING DEFAULTS之后才会包含进来。缺省是不包含缺省表达式的，即新表中所有字段的缺省值都是NULL。
  
  - 非空约束将总是继承到新表中，CHECK约束则仅在指定了INCLUDING CONSTRAINTS的时候才继承，而其他类型的约束则永远也不会被继承。此规则同时适用于表约束和列约束。
  
  - 被继承的列和约束并不使用相同的名称进行融合。如果明确的指定了相同的名称或者在另外一个LIKE子句中，将会报错。
  
  - 如果指定了INCLUDING UPDATE，则原表列的ON UPDATE CURRENT_TIMESTAMP属性会继承到新表列中。默认不继承该属性。
  
  - 如果指定了INCLUDING INDEXES，则原表上的索引也将在新表上创建，默认不建立索引。
  
  - 如果指定了INCLUDING STORAGE，则原表列的STORAGE设置也将被继承，默认情况下不包含STORAGE设置。
  
  - 如果指定了INCLUDING COMMENTS，则原表列、约束和索引的注释也会被继承过来。默认情况下，不继承原表的注释。
  
  - 如果指定了INCLUDING RELOPTIONS，则原表的存储参数（即源表的WITH子句）也将继承至新表。默认情况下，不继承原表的存储参数。
  
  - 如果指定了INCLUDING DISTRIBUTION，则新表将继承原表的分布信息，包括分布类型和分布列，同时新表将不能再使用DISTRIBUTE BY子句。默认情况下，不继承原表的分布信息。
  
  - 如果指定了INCLUDING ILM选项，则原表的ilm策略信息会继承到新表上。
  
  - INCLUDING ALL是INCLUDING DEFAULTS、INCLUDING UPDATE、INCLUDING CONSTRAINTS、INCLUDING INDEXES、INCLUDING STORAGE、INCLUDING COMMENTS、INCLUDING RELOPTIONS和INCLUDING DISTRIBUTION的简写形式。
   
- **COMMENT \[ = \] 'string'**
  - COMMENT \[ = \] 'string'子句表示给表添加注释。
  
  - 在column_constraint中的COMMENT 'string'表示给列添加注释。
  
  - 在table_constraint中的COMMENT 'string'表示给主键和唯一键对应的索引添加注释。
  
  
  具体请参见：[•COMMENT\[=\]'string'](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/gaussdb-81-0077.html#ZH-CN_TOPIC_0000002527805472__zh-cn_topic_0000002527053368_zh-cn_topic_0000001783245797_li163951820153817)。
  
- **{CHARACTER SET \| CHAR SET \| CHARSET}** **charset**
  指定表字段的字符集。单独指定时会将字段的字符序设置为指定的字符集的默认字符序。
  
- **COLLATE collation**
  COLLATE子句指定列的排序规则（字符序）（该列必须是可排列的数据类型）。如果没有指定，则使用默认的排序规则。排序规则可以使用"select \* from pg_collation;"命令从pg_collation系统表中查询，默认的排序规则为查询结果中以default开始的行。支持utf8mb4_bin、utf8mb4_general_ci、utf8mb4_unicode_ci、binary、gbk_chinese_ci、gbk_bin、gb18030_chinese_ci、gb18030_bin字符序。具体请参见[表级字符集和字符序](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/gaussdb-81-0035.html#ZH-CN_TOPIC_0000002527965392)
  ![](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  - 仅字符类型支持指定字符集，指定为BINARY字符集或字符序实际是将字符类型转化为对应的二进制类型，若类型映射不存在则报错。当前仅有TEXT类型转化为BLOB的映射。
  
  - 除BINARY字符集、字符序外，当前仅支持指定与数据库编码相同的字符集。
  
  - 字段字符集或字符序未显式指定时，若指定了表的默认字符集或字符序，字段字符集和字符序将从表上继承。
    
- **WITH ( storage_parameter \[= value\] \[, ... \] )**
  这个子句为表或索引指定一个可选的存储参数。参数的详细描述如下所示：
  - FILLFACTOR 一个表的填充因子（fillfactor）是一个介于10\~100的百分数。在Ustore存储引擎下，该值的默认值为92，在Astore存储引擎下默认值为100（完全填充）。如果指定了较小的填充因子，INSERT操作仅按照填充因子指定的百分率填充表页。每个页上的剩余空间将用于在该页上更新行，这就使得UPDATE有机会在同一页上放置同一条记录的新版本，这比把新版本放置在其他页上更有效。对于一个从不更新的表将填充因子设为100是最佳选择，但是对于频繁更新的表，选择较小的填充因子则更加合适。
    取值范围：10\~100
    
  
  - ORIENTATION 决定了表的数据的存储方式。当前M-compatibility模式数据库下只支持行存储方式。
    取值范围：
    ROW（缺省值）：表的数据将以行式存储。
    ![](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
    orientation不支持修改。
    
  
  - STORAGE_TYPE 指定存储引擎类型，该参数设置成功后就不再支持修改。
    取值范围：
    - USTORE，表示表支持Inplace-Update存储引擎。特别需要注意，使用USTORE表，必须要开启track_counts和track_activities参数，否则会引起空间膨胀。
    
    - ASTORE，表示表支持Append-Only存储引擎。
    
    
    默认值：
    不指定表时，默认是Inplace-Update存储。
    
  
  - COMPRESSION 行存表不支持压缩。
    
  
  - segment 使用段页式的方式存储。本参数仅支持行存表。不支持临时表、unlog表。
    取值范围：on/off
    默认值：off
    
  
  - statistic_granularity 记录该表在分析统计信息时的默认PARTITION_MODE。此参数对非分区表设置无效。
    取值范围：请参见PARTITION_MODE选项说明。
    默认值：AUTO。
    表1PARTITION_MODE选项说明 
    | PARTITION_MODE选项     | 含义              |
    |:---|:---|
    | ALL                  | 收集整表、一级分区的统计信息。 |
    | GLOBAL               | 收集整表的统计信息。      |
    | PARTITION            | 收集一级分区的统计信息。    |
    | GLOBAL AND PARTITION | 收集整表、一级分区的统计信息。 |
    | ALL COMPLETE         | 收集整表、一级分区的统计信息。 |
    | AUTO                 | 缺省值。            |
       
    
   
- **TABLESPACE tablespace_name**
  指定新表将要在tablespace_name表空间内创建。如果没有声明，将使用默认表空间。
  注：需要在非M-Compatibility数据库中创建或删除tablespace。
  
- **DISTRIBUTE BY**
  指定表如何在节点之间分布或者复制。
  取值范围及详细信息见[•DISTRIBUTE BY](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/gaussdb-81-0077.html#ZH-CN_TOPIC_0000002527805472__zh-cn_topic_0000002527053368_zh-cn_topic_0059778169_l121f87065d6e427f931cdc1bda2f5e01)一节。
  
- **TO { GROUP groupname \| NODE ( nodename \[, ... \] ) }**
  TO GROUP指定创建表所在的Node Group用。TO NODE主要供内部扩容工具使用，一般用户不应该使用。
  
- **PARTITION BY RANGE \[COLUMNS\] (partition_key)**
  创建范围分区。partition_key为分区键的名称。
  "PARTITION BY RANGE COLUMNS" 语义同 "PARTITION BY RANGE"。
  （1）对于从句是VALUES LESS THAN的语法格式：
  ![](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  对于从句是VALUES LESS THAN的语法格式，范围分区策略的分区键最多支持16列。
  该情形下，分区键支持的数据类型为：TINYINT、SMALLINT、INTEGER、BIGINT、TINYINT UNSIGNED、SMALLINT UNSIGNED、INTEGER UNSIGNED、BIGINT UNSIGNED、DATE、YEAR、CHAR\[(n)\]、VARCHAR\[(n)\]、MEDIUMINT、MEDIUMINT UNSIGNED、BINARY\[(n)\]、VARBINARY(n)、DATETIME\[(p)\]、TIME\[(p)\]。
  （2）对于从句是START END的语法格式：
  ![](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  对于从句是START END的语法格式，范围分区策略的分区键仅支持1列。
  该情形下，分区键支持的数据类型为：TINYINT、SMALLINT、INTEGER、BIGINT、TINYINT UNSIGNED、SMALLINT UNSIGNED、INTEGER UNSIGNED、BIGINT UNSIGNED、DATE。
  
- **PARTITION partition_name VALUES LESS THAN {( { partition_value \| MAXVALUE } \[,...\] )** \| MAXVALUE } \[TABLESPACE tablespace_name\]
  指定各分区的信息。partition_name为范围分区的名称。partition_value为范围分区的上边界，取值依赖于partition_key的类型。MAXVALUE表示分区的上边界，它通常用于设置最后一个范围分区的上边界。
  ![](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  - 每个分区都需要指定一个上边界。
  
  - 分区上边界的类型应当和分区键的类型一致。
  
  - 分区列表是按照分区上边界升序排列的，值较小的分区位于值较大的分区之前。
  
  - 不在括号内的MAXVALUE只能有一个分区键。
  
  - partition_value不支持使用表达式。
    
- **PARTITION partition_name** ****{START (partition_value) END (partition_value\|MAXVALUE)} \| {START(partition_value)} \|**{END (partition_value \| MAXVALUE)** } \[TABLESPACE tablespace_name\]
  指定各分区的信息，各参数意义如下：
  - partition_name：范围分区的名称或名称前缀，除以下情形外（假定其中的partition_name是p1），均为分区的名称。 若该定义是第一个分区定义，且该定义有START值，则范围（MINVALUE, START）将自动作为第一个实际分区，其名称为p1_0，然后该定义语义描述的分区名称依次为p1_1, p1_2, ...。例如对于完整定义"PARTITION p1 START(1), PARTITION p2 START(2)"，则生成的分区是：(MINVALUE, 1), \[1, 2) 和 \[2, MAXVALUE)，其名称依次为p1_0, p1_1和p2，即此处p1是名称前缀，p2是分区名称。这里MINVALUE表示最小值。
    
  
  - partition_value：范围分区的端点值（起始或终点），取值依赖于partition_key的类型，不可是MAXVALUE。
  
  - MAXVALUE：表示最大值，它通常用于设置最后一个范围分区的上边界。
  
  
  ![](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  1. 在创建分区表若第一个分区定义含START值，则范围（MINVALUE，START）将自动作为实际的第一个分区。
  
  2. START END语法需要遵循以下限制：
     - 每个partition_start_end_item中的START值（如果有的话，下同）必须小于其END值；
     
     - 相邻的两个partition_start_end_item，第一个的END值必须等于第二个的START值；
     
     - 每个分区包含起始值，不包含终点值，即形如：\[起始值，终点值)，起始值是MINVALUE时则不包含；
     
     - 一个partition_start_end_item创建的每个分区所属的TABLESPACE一样；
     
     - partition_name作为分区名称前缀时，其长度不要超过57字节，超过时自动截断；
     
     - 在创建、修改分区表时请注意分区表的分区总数不可超过最大限制（1048575）；
      
  
  3. 在创建分区表时START END与LESS THAN语法不可混合使用。
  
  4. 即使创建分区表时使用START END语法，备份（gs_dump）出的SQL语句也是VALUES LESS THAN语法格式。
    
- **PARTITION BY LIST \[COLUMNS\] (partition_key)**
  创建列表分区。partition_key为分区键的名称。
  "PARTITION BY LIST COLUMNS" 语义同 "PARTITION BY LIST"。
  - 对于partition_key，不支持表达式。当不指定二级分区时，列表分区策略的分区键最多支持16列，当指定二级分区时，列表分区策略的分区键最多支持1列，且不支持表达式。
  
  - 对于从句是VALUES \[IN\] (list_values)的语法格式，list_values中包含了对应分区存在的键值，每个分区的键值数量不超过64个。
  
  - 从句"VALUES IN"语义同"VALUES"。
  
  
  分区键支持的数据类型为：TINYINT、SMALLINT、INTEGER、BIGINT、TINYINT UNSIGNED、SMALLINT UNSIGNED、INTEGER UNSIGNED、BIGINT UNSIGNED、DATE、YEAR、CHAR\[(n)\]、VARCHAR\[(n)\]、MEDIUMINT、MEDIUMINT UNSIGNED、BINARY\[(n)\]、VARBINARY(n)、DATETIME\[(p)\]、TIME\[(p)\]。分区个数不能超过1048575个。
  
- **PARTITION BY HASH(partition_key)**
  创建哈希分区。partition_key为分区键的名称。
  对于partition_key，哈希分区策略的分区键仅支持1列，且不支持表达式。
  分区键支持的数据类型为：TINYINT、SMALLINT、INTEGER、BIGINT、TINYINT UNSIGNED、SMALLINT UNSIGNED、INTEGER UNSIGNED、BIGINT UNSIGNED、DATE、YEAR、CHAR\[(n)\]、VARCHAR\[(n)\]、MEDIUMINT、MEDIUMINT UNSIGNED、BINARY\[(n)\]、VARBINARY(n)、DATETIME\[(p)\]、TIME\[(p)\]、TIMESTAMP\[(p)\]、NUMERIC\[(p\[,s\])\]、FLOAT4\[(p, s)\]、FLOAT8\[(p,s)\]。分区个数不能超过1048575个。
  
- **PARTITION BY KEY(partition_key)**
  语义同"PARTITION BY HASH(partition_key)"。
  
- **PARTITIONS integer**
  指定分区个数。
  integer为分区数，必须为大于0的整数，且不得大于1048575。
  - 当在RANGE和LIST分区后指定此子句时，必须显式定义每个分区，且定义分区的数量必须与integer值相等。只能在RANGE和LIST分区后指定此子句。
  
  - 当在HASH和KEY分区后指定此子句时，若不列出各个分区定义，将自动生成integer个分区，自动生成的分区名为"p+数字"，数字依次为0到integer-1，分区的表空间默认为此表的表空间；也可以显式列出每个分区定义，此时定义分区的数量必须与integer值相等。若既不列出分区定义，也不指定分区数量，将创建唯一一个分区。
   
 
- **NOT NULL**
  字段值不允许为NULL。ENABLE用于语法兼容，可省略。
  
- **NULL**
  字段值允许NULL ，这是缺省。
  这个子句只是为和非标准SQL数据库兼容。不建议使用。
  
- **CHECK (condition)**
  CHECK约束声明一个布尔表达式，每次要插入的新行或者要更新的行的新值必须使表达式结果为真或未知才能成功，否则会抛出一个异常并且不会修改数据库。
  声明为字段约束的检查约束应该只引用该字段的数值，而在表约束里出现的表达式可以引用多个字段。
  
- **DEFAULT default_expr**
  - 使用DEFAULT子句给字段指定缺省表达式，缺省表达式将被用于任何未声明该字段数值的插入操作。如果没有指定缺省值则缺省值为NULL 。
  
  - 支持指定以下内容：常量、带正负号的数值常量、[update_expr]。
  
  - 仅支持在TIMESTAMP、DATETIME类型的字段上指定update_expr作为默认值，且字段的精度与update_expr的精度须保持一致。
   
- **ON UPDATE update_expr**
  ON UPDATE子句为字段的一种属性约束。
  当对表中某元组执行UPDATE操作时，若更新字段的新值和表中旧值不相同，则表中该元组上具有该属性且不在更新字段内的字段值自动更新为当前时间戳；若更新字段的新值和表中旧值相同，则表中该元组上具有该属性且不在更新字段内的字段值不变，保持原有值；若具有该属性的字段在更新字段内，则对应这些字段值直接按指定更新的值更新。
  ![](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  - 语法上update_expr支持CURRENT_TIMESTAMP 、LOCALTIMESTAMP 、LOCALTIME、NOW()四种关键字，也支持关键字带括号指定或不指定精度。例如：ON UPDATE CURRENT_TIMESTAMP()、ON UPDATE CURRENT_TIMESTAMP(5)、ON UPDATE LOCALTIMESTAMP()、ON UPDATE LOCALTIMESTAMP(6)等。不带括号或空括号时精度为0，其中NOW关键字不支持不带括号。四种关键字互为同义词，属性效果相同。
  
  - 该属性支持在如下类型的列上指定: TIMESTAMP、DATETIME。
  
  - 该属性指定的精度和对应列上类型指定的精度必须一致，否则会触发报错。例如：CREATE TABLE t1 (col1 timestamp(6) ON UPDATE CURRENT_TIMESTAMP(6)); 若精度不一致，会产生ERROR: Invalid ON UPDATE clause for "col1" 报错。
  
  - 该属性和生成列约束不能同时指定同一列。
  
  - 分区表中的分区键不支持指定该属性。
    
- **列级唯一约束：UNIQUE \[KEY\] index_parameters**
  UNIQUE约束表示表里的一个或多个字段的组合必须在全表范围内唯一。
  UNIQUE KEY与UNIQUE语义相同。
  
- **表级唯一约束：UNIQUE \[INDEX \| KEY\]\[ index_name \]\[ USING method \]( {{ column_name \[ ( length ) \] \| ( expression ) } \[ ASC \| DESC \] }\[, ... \] ) index_parameters**
  UNIQUE约束表示表里的一个字段或多个字段的组合必须在全表范围内唯一。
  对于唯一约束，NULL被认为是互不相等的。
  column_name(length)是前缀键，详见：[•column_name ( length )](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/gaussdb-81-0073.html#ZH-CN_TOPIC_0000002558925201__zh-cn_topic_0000002526893586_zh-cn_topic_0000001736086436_li180174718324)。
  index_name为索引名。
  ![](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/public_sys-resources/notice_3.0-zh-cn.png)
  对于唯一键约束，constraint_name和index_name同时指定时，索引名为index_name。
  
- **列级主键约束：\[PRIMARY\] KEY index_parameters**
  **表级主键约束：PRIMARY KEY \[index_name\] \[ USING method \] ( { column_name \[ ASC \| DESC \] } \[, ... \] ） index_parameters**
  主键约束声明表中的一个或者多个字段只能包含唯一的非NULL值。
  一个表只能声明一个主键。
  
- INTERNAL DATA data_content INTERNAL DATA data_content 仅扩容内部用，一般用户不应该使用。
  
#### 范围分区
- VALUES LESS THAN
  ```
  --创建分区表test_range1。
  m_db=# CREATE TABLE test_range1(
      id INT, 
      info VARCHAR(20)
  ) PARTITION BY RANGE (id) (
      PARTITION p1 VALUES LESS THAN (200),
      PARTITION p2 VALUES LESS THAN (400),
      PARTITION p3 VALUES LESS THAN (600),
      PARTITION pmax VALUES LESS THAN (MAXVALUE)
  );
  --插入1000条数据
  m_db=# INSERT INTO test_range1 VALUES(GENERATE_SERIES(1,1000),'abcd');
  --查看p1分区的行数199条，[1,200)。
  m_db=# SELECT COUNT(*) FROM test_range1 PARTITION (p1);
   count 
  -------
     199
  (1 row)
  --查看p2分区的行数200条，[200,400)。
  m_db=# SELECT COUNT(*) FROM test_range1 PARTITION (p2);
   count 
  -------
     200
  (1 row)
  --查看分区信息。
  m_db=# SELECT a.relname, a.boundaries  
  FROM pg_partition a 
  WHERE a.parentid = 'test_range1'::regclass and a.parttype = 'p';
   relname | boundaries 
  ---------+------------
   pmax    | {NULL}
   p3      | {600}
   p2      | {400}
   p1      | {200}
  (4 rows)
  --删除
  m_db=# DROP TABLE test_range1;
  ```
  
- START END
  ```
  --创建分区表。
  m_db=# CREATE TABLE test_range2(
      id INT, 
      info VARCHAR(20)
  ) PARTITION BY RANGE (id) (
      PARTITION p1 START(1) END(600),    
      PARTITION p2 START(600) END(800),
      PARTITION pmax START(800) END(MAXVALUE)
  );
  --查看分区信息。
  m_db=# SELECT relname, boundaries FROM pg_partition WHERE parentid = 'test_range2'::regclass AND parttype = 'p' ORDER BY 1;
  relname | boundaries 
  ---------+------------
   p1_0    | {1}
   p1_1    | {600}
   p2      | {800}
   pmax    | {NULL}
  (4 rows)
  --删除。
  m_db=# DROP TABLE test_range2;
  ```
  
 
#### 列表分区
```
--创建列表分区表。
m_db=# CREATE TABLE test_list ( NAME VARCHAR ( 50 ), area VARCHAR ( 50 ) ) 
PARTITION BY LIST (area) (
    PARTITION p1 VALUES ('Beijing'),
    PARTITION p2 VALUES ('Shanghai'),
    PARTITION p3 VALUES ('Guangzhou'),
    PARTITION p4 VALUES ('Shenzhen'),
    PARTITION pdefault VALUES (DEFAULT)
);
--插入数据。
m_db=# INSERT INTO test_list VALUES ('bob', 'Shanghai'),('scott', 'Sichuan');
--查询分区数据。
m_db=# SELECT * FROM test_list PARTITION (p2);
 name |   area   
------+----------
 bob  | Shanghai
(1 row)
m_db=# SELECT * FROM test_list PARTITION (pdefault);
 name  |  area   
-------+---------
 scott | Sichuan
(1 row)
--删除。
m_db=# DROP TABLE test_list;
```
#### 哈希分区
```
--创建哈希分区表，指定分区数。
m_db=# CREATE TABLE test_hash1(c1 int) PARTITION BY HASH(c1) PARTITIONS 3;
--创建哈希分区表，并指定分区名。
m_db=# CREATE TABLE test_hash2(c1 int) PARTITION BY HASH(c1)(
    PARTITION pa,
    PARTITION pb,
    PARTITION pc
);
--查看分区信息。
m_db=# SELECT b.relname AS table_name,
       a.relname AS partition_name 
FROM pg_partition a, 
     pg_class b 
WHERE b.relname LIKE 'test_hash%' 
  AND a.parttype = 'p' 
  AND a.parentid = b.oid; 
 table_name | partition_name 
------------+----------------
 test_hash1 | p2
 test_hash1 | p1
 test_hash1 | p0
 test_hash2 | pc
 test_hash2 | pb
 test_hash2 | pa
(6 rows)
--删除。
m_db=# DROP TABLE test_hash1,test_hash2;
```
#### 相关链接
[ALTER TABLE PARTITION](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/gaussdb-81-0057.html#ZH-CN_TOPIC_0000002527965408)，[DROP TABLE](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/gaussdb-81-0095.html#ZH-CN_TOPIC_0000002527965432)
