diff --git "a/content/docs-lite/zh/docs/DatabaseReference/DCF\345\217\202\346\225\260\350\256\276\347\275\256.md" "b/content/docs-lite/zh/docs/DatabaseReference/DCF\345\217\202\346\225\260\350\256\276\347\275\256.md" index 79e27e5f75f742b73f1528b42537356ae5ddd8c2..5d21df238714d0a852b1d39e10131545df1108b5 100644 --- "a/content/docs-lite/zh/docs/DatabaseReference/DCF\345\217\202\346\225\260\350\256\276\347\275\256.md" +++ "b/content/docs-lite/zh/docs/DatabaseReference/DCF\345\217\202\346\225\260\350\256\276\347\275\256.md" @@ -6,7 +6,7 @@ ## enable\_dcf -**参数说明**: 是否开启DCF模式,该参数不允许修改。 +**参数说明**: 是否开启DCF模式,该参数不允许修改,该特性在金融版本下不支持。 该参数属于POSTMASTER类型参数,请参考[表1](../DatabaseAdministrationGuide/参数设置.md#zh-cn_topic_0283137176_zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 diff --git a/content/docs-lite/zh/docs/DatabaseReference/GAUSS-50600----GAUSS-50699.md b/content/docs-lite/zh/docs/DatabaseReference/GAUSS-50600----GAUSS-50699.md index 850fb9d4b8d9c8ff5732d74b738c55a0bc0a6834..ecc91ae476061dce4ad4dccfd5327c6a929839f1 100644 --- a/content/docs-lite/zh/docs/DatabaseReference/GAUSS-50600----GAUSS-50699.md +++ b/content/docs-lite/zh/docs/DatabaseReference/GAUSS-50600----GAUSS-50699.md @@ -1,146 +1,147 @@ -# GAUSS-50600 -- GAUSS-50699 - -GAUSS-50600: "The IP address cannot be pinged, which is caused by network faults." - -SQLSTATE: 无 - -错误原因:IP ping不通。 - -解决办法:检查并设置网络,使其相互能够ping通。 - -GAUSS-50601: "The port \[%s\] is occupied." - -SQLSTATE: 无 - -错误原因:端口被占用。 - -解决办法:1.检查占用端口号的资源是否有用,若闲置则释放端口号;2.指定其它端口号。 - -GAUSS-50602: "Failed to bind network adapters." - -SQLSTATE: 无 - -错误原因:网卡绑定错误。 - -解决办法:请联系技术支持工程师提供技术支持。 - -GAUSS-50603: "The IP address is invalid." - -SQLSTATE: 无 - -错误原因:IP 无效。 - -解决办法:检查并修改为正确的IP。 - -GAUSS-50604: "Failed to obtain network interface card of backIp\(%s\)." - -SQLSTATE: 无 - -错误原因:获取网卡失败。 - -解决办法:1.检查网络是否正常;2.检查网卡是否正常。 - -GAUSS-50605: "Failed to obtain back IP subnet mask." - -SQLSTATE: 无 - -错误原因:获取子网掩码失败。 - -解决办法:检查网络是否正常。 - -GAUSS-50606: "Back IP\(s\) do not have the same subnet mask." - -SQLSTATE: 无 - -错误原因:BackIP不能有相同的子网掩码。 - -解决办法:给BackIP设置一个子网掩码。 - -GAUSS-50607: "Failed to obtain configuring virtual IP line number position of network startup file." - -SQLSTATE: 无 - -错误原因:网卡启动文件中获取虚拟IP时失败。 - -解决办法:用户手动检查网卡配置文件,查看是否被破坏。 - -GAUSS-50608: "Failed to writing virtual IP setting cmds into init file." - -SQLSTATE: 无 - -错误原因:在初始化文件中写虚拟IP设置命令失败。 - -解决办法:用户手动检查网卡配置文件,查看是否被破坏。 - -GAUSS-50609: "Failed to check port: %s." - -SQLSTATE: 无 - -错误原因:检查端口失败。 - -解决办法:检查端口是否启用,是否被占用。 - -GAUSS-50610: "Failed to get the range of random port." - -SQLSTATE: 无 - -错误原因:获取端口范围失败。 - -解决办法:查看端口失败的原因,重新获取。 - -GAUSS-50611: "Failed to obtain network card bonding information." - -SQLSTATE: 无 - -错误原因:获取网卡绑定信息失败。 - -解决办法:检查文件/proc/net/bonding/\[网卡编号\]是否存在,文件中是否有“BONDING\_OPTS”\(redhat环境\)或者“BONDING\_MODULE\_OPTS”\(centOS环境\)字符串。 - -GAUSS-50612: "Failed to obtain network card %s value." - -SQLSTATE: 无 - -错误原因:获取网卡RTU/RX的值失败。 - -解决办法:检查网络是否正常,网卡是否正常。 - -GAUSS-50613: "Failed to set network card %s value." - -SQLSTATE: 无 - -错误原因:设置网卡信息失败。 - -解决办法:检查网络是否正常,网卡是否正常。 - -GAUSS-50614: "Failed to check network information." - -SQLSTATE: 无 - -错误原因:检查网卡信息失败 - -解决办法:查看ifconfig是否可用,可用状态下重新查询。 - -GAUSS-50615: "IP %s and IP %s are not in the same network segment." - -SQLSTATE: 无 - -错误原因:两个IP的网段不一致 - -解决办法:将两个IP的网段配在相同网段,重新执行。 - -GAUSS-50616: "Failed to get network interface." - -SQLSTATE: 无 - -错误原因:获取网络接口失败 - -解决办法:确保IP存在,ifconfig可用,网卡配置文件中有IP信息,重新执行。 - -GAUSS-50617: "The node of XML configure file has the same virtual IP." - -SQLSTATE: 无 - -错误原因:系统内部错误。 - -解决办法:请联系技术支持工程师提供技术支持。 - +# GAUSS-50600 -- GAUSS-50699 + +GAUSS-50600: "The IP address cannot be pinged, which is caused by network faults." + +SQLSTATE: 无 + +错误原因:IP ping不通。 + +解决办法:检查并设置网络,使其相互能够ping通。 + +GAUSS-50601: "The port \[%s\] is occupied." + +SQLSTATE: 无 + +错误原因:端口被占用。 + +解决办法:1.检查占用端口号的资源是否有用,若闲置则释放端口号;2.指定其它端口号。 + +GAUSS-50602: "Failed to bind network adapters." + +SQLSTATE: 无 + +错误原因:网卡绑定错误。 + +解决办法:请联系技术支持工程师提供技术支持。 + +GAUSS-50603: "The IP address is invalid." + +SQLSTATE: 无 + +错误原因:IP 无效。 + +解决办法:检查并修改为正确的IP。 + +GAUSS-50604: "Failed to obtain network interface card of backIp\(%s\)." + +SQLSTATE: 无 + +错误原因:获取网卡失败。 + +解决办法:1.检查网络是否正常;2.检查网卡是否正常。 + +GAUSS-50605: "Failed to obtain back IP subnet mask." + +SQLSTATE: 无 + +错误原因:获取子网掩码失败。 + +解决办法:检查网络是否正常。 + +GAUSS-50606: "Back IP\(s\) do not have the same subnet mask." + +SQLSTATE: 无 + +错误原因:BackIP不能有相同的子网掩码。 + +解决办法:给BackIP设置一个子网掩码。 + +GAUSS-50607: "Failed to obtain configuring virtual IP line number position of network startup file." + +SQLSTATE: 无 + +错误原因:网卡启动文件中获取虚拟IP时失败。 + +解决办法:用户手动检查网卡配置文件,查看是否被破坏。 + +GAUSS-50608: "Failed to writing virtual IP setting cmds into init file." + +SQLSTATE: 无 + +错误原因:在初始化文件中写虚拟IP设置命令失败。 + +解决办法:用户手动检查网卡配置文件,查看是否被破坏。 + +GAUSS-50609: "Failed to check port: %s." + +SQLSTATE: 无 + +错误原因:检查端口失败。 + +解决办法:检查端口是否启用,是否被占用。 + +GAUSS-50610: "Failed to get the range of random port." + +SQLSTATE: 无 + +错误原因:获取端口范围失败。 + +解决办法:查看端口失败的原因,重新获取。 + +GAUSS-50611: "Failed to obtain network card bonding information." + +SQLSTATE: 无 + +错误原因:获取网卡绑定信息失败。 + +解决办法:检查文件/proc/net/bonding/\[网卡编号\]是否存在,文件中是否有“BONDING\_OPTS”\(redhat环境\)或者“BONDING\_MODULE\_OPTS”\(centOS环境\)字符串。 +检查文件/etc/sysconfig/network-scripts/ifcfg-\[网卡编号\]是否存在,文件中是否有"DEVICE"字符串. + +GAUSS-50612: "Failed to obtain network card %s value." + +SQLSTATE: 无 + +错误原因:获取网卡RTU/RX的值失败。 + +解决办法:检查网络是否正常,网卡是否正常。 + +GAUSS-50613: "Failed to set network card %s value." + +SQLSTATE: 无 + +错误原因:设置网卡信息失败。 + +解决办法:检查网络是否正常,网卡是否正常。 + +GAUSS-50614: "Failed to check network information." + +SQLSTATE: 无 + +错误原因:检查网卡信息失败 + +解决办法:查看ifconfig是否可用,可用状态下重新查询。 + +GAUSS-50615: "IP %s and IP %s are not in the same network segment." + +SQLSTATE: 无 + +错误原因:两个IP的网段不一致 + +解决办法:将两个IP的网段配在相同网段,重新执行。 + +GAUSS-50616: "Failed to get network interface." + +SQLSTATE: 无 + +错误原因:获取网络接口失败 + +解决办法:确保IP存在,ifconfig可用,网卡配置文件中有IP信息,重新执行。 + +GAUSS-50617: "The node of XML configure file has the same virtual IP." + +SQLSTATE: 无 + +错误原因:系统内部错误。 + +解决办法:请联系技术支持工程师提供技术支持。 + diff --git "a/content/docs-lite/zh/docs/DatabaseReference/\344\274\230\345\214\226\345\231\250\346\226\271\346\263\225\351\205\215\347\275\256.md" "b/content/docs-lite/zh/docs/DatabaseReference/\344\274\230\345\214\226\345\231\250\346\226\271\346\263\225\351\205\215\347\275\256.md" index ad12c26333194642fd07a9a0197113d4cb1ea32f..c2417962f694ea1d37ef6cf6e01958c4af53ad41 100644 --- "a/content/docs-lite/zh/docs/DatabaseReference/\344\274\230\345\214\226\345\231\250\346\226\271\346\263\225\351\205\215\347\275\256.md" +++ "b/content/docs-lite/zh/docs/DatabaseReference/\344\274\230\345\214\226\345\231\250\346\226\271\346\263\225\351\205\215\347\275\256.md" @@ -353,7 +353,7 @@ ## try\_vector\_engine\_strategy -**参数说明**:设置行存表走向量化执行引擎的策略。通过设置该参数,可以使包含行存表的查询可以转换为向量化的执行计划执行计算,从而提升类AP场景的复杂查询的执行性能。 +**参数说明**:设置行存表走向量化执行引擎的策略。通过设置该参数,可以使包含行存表的查询可以转换为向量化的执行计划执行计算,从而提升类AP场景的复杂查询的执行性能,该特性在金融版本下不支持。 该参数属于USERSET类型参数,请参考[表1](../DatabaseAdministrationGuide/参数设置.md#zh-cn_topic_0283137176_zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 diff --git "a/content/docs-lite/zh/docs/DatabaseReference/\345\205\266\345\256\203\351\200\211\351\241\271.md" "b/content/docs-lite/zh/docs/DatabaseReference/\345\205\266\345\256\203\351\200\211\351\241\271.md" index b1010a3f8a202c9561be2f1a9abcd4b40b895055..14851987dd17d51a246a201c307e0c16067aa347 100644 --- "a/content/docs-lite/zh/docs/DatabaseReference/\345\205\266\345\256\203\351\200\211\351\241\271.md" +++ "b/content/docs-lite/zh/docs/DatabaseReference/\345\205\266\345\256\203\351\200\211\351\241\271.md" @@ -12,7 +12,7 @@ ## enable\_ustore -**参数说明**: 指定是否开启Ustore存储引擎,该参数为on时,支持创建Ustore表。特别需要注意,使用Ustore表,必须要开启track\_counts和track\_activities参数,否则会引起空间膨胀。 +**参数说明**: 指定是否开启Ustore存储引擎,该参数为on时,支持创建Ustore表。特别需要注意,使用Ustore表,必须要开启track\_counts和track\_activities参数,否则会引起空间膨胀,该特性在金融版本下不支持。 该参数属于POSTMASTER类型,请参考[表1](../DatabaseAdministrationGuide/参数设置.md#zh-cn_topic_0283137176_zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 diff --git "a/content/docs-lite/zh/docs/DatabaseReference/\345\256\211\345\205\250\351\205\215\347\275\256.md" "b/content/docs-lite/zh/docs/DatabaseReference/\345\256\211\345\205\250\351\205\215\347\275\256.md" index 1136b0ff1361395f11909c07fe99cc55f3b6ce50..c1508f22b745ba0dd806a664bbca28ee5d909839 100644 --- "a/content/docs-lite/zh/docs/DatabaseReference/\345\256\211\345\205\250\351\205\215\347\275\256.md" +++ "b/content/docs-lite/zh/docs/DatabaseReference/\345\256\211\345\205\250\351\205\215\347\275\256.md" @@ -54,7 +54,7 @@ off表示不是初始用户。 ## enable\_tde -**参数说明**: 透明数据加密功能开关。创建加密表前需要将此参数置为on。当前参数值为off时,禁止创建新的加密表,对于已经创建的加密表只在读取数据时解密,写入数据时不再加密。 +**参数说明**: 透明数据加密功能开关。创建加密表前需要将此参数置为on。当前参数值为off时,禁止创建新的加密表,对于已经创建的加密表只在读取数据时解密,写入数据时不再加密。该特性在金融版本下不支持。 该参数属于POSTMASTER类型参数,请参考[表1](../DatabaseAdministrationGuide/参数设置.md#zh-cn_topic_0283137176_zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 diff --git "a/content/docs-lite/zh/docs/DatabaseReference/\345\275\222\346\241\243.md" "b/content/docs-lite/zh/docs/DatabaseReference/\345\275\222\346\241\243.md" index 49fd860b489df118aee044cfdad94b1f66d60d0f..e5faf8cd318b8c1360de4d83183e224f55811466 100644 --- "a/content/docs-lite/zh/docs/DatabaseReference/\345\275\222\346\241\243.md" +++ "b/content/docs-lite/zh/docs/DatabaseReference/\345\275\222\346\241\243.md" @@ -11,6 +11,7 @@ >- 当[wal\_level](设置.md#zh-cn_topic_0283137354_zh-cn_topic_0237124707_zh-cn_topic_0059778393_s2c76f5957066407a959191148f2c780f)设置成minimal时,archive\_mode参数无法使用。 >- 无论是同步备机还是异步备机都能够开启归档,归档开启的方式与单机开启归档一致,将archive\_mode置为on,并设置正确的archive\_dest或者archive\_command即可。 >- 若未开启最大可用模式以及有同步备机与主机断开连接时,主机会因为业务阻塞的原因无法给备机发送归档的位置,从而导致归档失败。 +>- 该特性在金融版本下不支持 **取值范围**: 布尔型 diff --git "a/content/docs-lite/zh/docs/PerformanceTuningGuide/SMP\344\275\277\347\224\250\345\273\272\350\256\256.md" "b/content/docs-lite/zh/docs/PerformanceTuningGuide/SMP\344\275\277\347\224\250\345\273\272\350\256\256.md" index 8c86a537b6b44b288ae9ffdfcecc3e5d7b033a09..3d13d0620198a5ea71fe860c0c0f57febd320156 100644 --- "a/content/docs-lite/zh/docs/PerformanceTuningGuide/SMP\344\275\277\347\224\250\345\273\272\350\256\256.md" +++ "b/content/docs-lite/zh/docs/PerformanceTuningGuide/SMP\344\275\277\347\224\250\345\273\272\350\256\256.md" @@ -1,28 +1,30 @@ -# SMP使用建议 - -## 使用限制 - -想要利用SMP提升查询性能需要满足以下条件: - -系统的CPU、内存、I/O和网络带宽等资源充足。SMP架构是一种利用富余资源来换取时间的方案,计划并行之后必定会引起资源消耗的增加,当上述资源成为瓶颈的情况下,SMP无法提升性能,反而可能导致性能的劣化。在出现资源瓶颈的情况下,建议关闭SMP。 - -## 配置步骤 - -1. 观察当前系统负载情况,如果系统资源充足(资源利用率小于50%),执行[2](#li1174421213171);否则退出。 -2. 设置query\_dop=1(默认值),利用explain打出执行计划,观察计划是否符合[SMP适用场景与限制](SMP适用场景与限制.md)小节中的适用场景。如果符合,进入[3](#li998191911172)。 -3. 设置query\_dop=value,不考虑资源情况和计划特征,强制选取dop为1或value。 -4. 在符合条件的查询语句执行前设置合适的query\_dop值,在语句执行结束后关闭query\_dop。举例如下。 - - ``` - openGauss=# SET query_dop = 4; - openGauss=# SELECT COUNT(*) FROM t1 GROUP BY a; - ...... - openGauss=# SET query_dop = 1; - ``` - - >![](public_sys-resources/icon-note.gif) **说明:** - > - >- 资源许可的情况下,并行度越高,性能提升效果越好。 - >- SMP并行度支持会话级设置,推荐客户在执行符合要求的查询前,打开smp,执行结束后,关闭smp。以免在业务峰值时,对业务造成冲击。 - - +# SMP使用建议 + +## 使用限制 + +想要利用SMP提升查询性能需要满足以下条件: + +系统的CPU、内存、I/O和网络带宽等资源充足。SMP架构是一种利用富余资源来换取时间的方案,计划并行之后必定会引起资源消耗的增加,当上述资源成为瓶颈的情况下,SMP无法提升性能,反而可能导致性能的劣化。在出现资源瓶颈的情况下,建议关闭SMP。 + +该特性在金融版本下不支持 + +## 配置步骤 + +1. 观察当前系统负载情况,如果系统资源充足(资源利用率小于50%),执行[2](#li1174421213171);否则退出。 +2. 设置query\_dop=1(默认值),利用explain打出执行计划,观察计划是否符合[SMP适用场景与限制](SMP适用场景与限制.md)小节中的适用场景。如果符合,进入[3](#li998191911172)。 +3. 设置query\_dop=value,不考虑资源情况和计划特征,强制选取dop为1或value。 +4. 在符合条件的查询语句执行前设置合适的query\_dop值,在语句执行结束后关闭query\_dop。举例如下。 + + ``` + openGauss=# SET query_dop = 4; + openGauss=# SELECT COUNT(*) FROM t1 GROUP BY a; + ...... + openGauss=# SET query_dop = 1; + ``` + + >![](public_sys-resources/icon-note.gif) **说明:** + > + >- 资源许可的情况下,并行度越高,性能提升效果越好。 + >- SMP并行度支持会话级设置,推荐客户在执行符合要求的查询前,打开smp,执行结束后,关闭smp。以免在业务峰值时,对业务造成冲击。 + + diff --git a/content/docs-lite/zh/docs/SQLReference/CREATE-TABLE.md b/content/docs-lite/zh/docs/SQLReference/CREATE-TABLE.md index 7c6f702b0a62efe66d007fc2126d0bcbb95540f1..2d56ef05a9736d1aef5cea7095efe18baef9e57d 100644 --- a/content/docs-lite/zh/docs/SQLReference/CREATE-TABLE.md +++ b/content/docs-lite/zh/docs/SQLReference/CREATE-TABLE.md @@ -1,1305 +1,1305 @@ -# CREATE TABLE - -## 功能描述 - -在当前数据库中创建一个新的空白表,该表由命令执行者所有。 - -## 注意事项 - -- 列存表支持的数据类型请参考[列存表支持的数据类型](列存表支持的数据类型.md)。 -- 列存表不支持数组。 -- 列存表不支持生成列。 -- 列存表不支持创建全局临时表。 -- 创建列存表的数量建议不超过1000个。 -- 如果在建表过程中数据库系统发生故障,系统恢复后可能无法自动清除之前已创建的、大小为0的磁盘文件。此种情况出现概率小,不影响数据库系统的正常运行。 -- 列存表的表级约束只支持PARTIAL CLUSTER KEY、UNIQUE、PRIAMRY KEY,不支持外键等表级约束。 -- 列存表的字段约束只支持NULL、NOT NULL和DEFAULT常量值、UNIQUE和PRIMARY KEY。 -- 列存表支持delta表,受参数enable\_delta\_store控制是否开启,受参数deltarow\_threshold控制进入delta表的阀值。 -- 列存表的字段的字符集必须与数据库字符集一致。 -- 使用JDBC时,支持通过PrepareStatement对DEFAULT值进行参数化设置。 -- 每张表的列数最大为1600,具体取决于列的类型,所有列的大小加起来不能超过8192 byte(由于数据存储形式原因,实际上限略小于8192 byte),text、varchar、char等长度可变的类型除外。 -- 被授予CREATE ANY TABLE权限的用户,可以在public模式和用户模式下创建表。如果想要创建包含serial类型列的表,还需要授予CREATE ANY SEQUENCE创建序列的权限。 -- 不可与同一模式下已存在的synonym产生命名冲突。 -- 仅支持在B兼容性数据库下指定COMMENT和可见性VISIBLE\INVISIBLE。 - -## 语法格式 - -创建表。 - -``` -CREATE [ [ GLOBAL | LOCAL ] [ TEMPORARY | TEMP ] | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name - ({ column_name data_type [ CHARACTER SET | CHARSET charset ] [ compress_mode ] [ COLLATE collation ] [ column_constraint [ ... ] ] - | table_constraint - | LIKE source_table [ like_option [...] ] } - [, ... ]) - [ AUTO_INCREMENT [ = ] value ] - [ [DEFAULT] CHARACTER SET | CHARSET [ = ] default_charset ] [ [DEFAULT] COLLATE [ = ] default_collation ] - [ WITH ( {storage_parameter = value} [, ... ] ) ] - [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] - [ COMPRESS | NOCOMPRESS ] - [ TABLESPACE tablespace_name ] - [ COMMENT {=| } 'text' ]; -``` - -- 其中列约束column\_constraint为: - - ``` - [ CONSTRAINT constraint_name ] - { NOT NULL | - NULL | - CHECK ( expression ) | - DEFAULT default_expr | - GENERATED ALWAYS AS ( generation_expr ) [STORED] | - AUTO_INCREMENT | - UNIQUE [KEY] index_parameters | - ENCRYPTED WITH ( COLUMN_ENCRYPTION_KEY = column_encryption_key, ENCRYPTION_TYPE = encryption_type_value ) | - 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 ] - [ COMMENT {=| } 'text' ] - ``` - - -- 其中列的压缩可选项compress\_mode为: - - ``` - { DELTA | PREFIX | DICTIONARY | NUMSTR | NOCOMPRESS } - ``` - -- 其中表约束table\_constraint为: - - ``` - [ CONSTRAINT [ constraint_name ] ] - { CHECK ( expression ) | - UNIQUE [ index_name ][ USING method ] ( { { column_name | ( expression ) } [ ASC | DESC ] } [, ... ] ) index_parameters [ VISIBLE | INVISIBLE ] | - PRIMARY KEY [ USING method ] ( { column_name [ ASC | DESC ] } [, ... ] ) index_parameters [ VISIBLE | INVISIBLE ] | - FOREIGN KEY [ index_name ] ( column_name [, ... ] ) REFERENCES reftable [ (refcolumn [, ... ] ) ] - [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] | - PARTIAL CLUSTER KEY ( column_name [, ... ] ) } - [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] - [ COMMENT {=| } 'text' ] - ``` - - -- 其中like选项like\_option为: - - ``` - { INCLUDING | EXCLUDING } { DEFAULTS | GENERATED | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | PARTITION | RELOPTIONS | ALL } - ``` - -- 其中索引参数index\_parameters为: - - ``` - [ WITH ( {storage_parameter = value} [, ... ] ) ] - [ USING INDEX TABLESPACE tablespace_name ] - ``` - - -## 参数说明 - -- **UNLOGGED** - - 如果指定此关键字,则创建的表为非日志表。在非日志表中写入的数据不会被写入到预写日志中,这样就会比普通表快很多。但是非日志表在冲突、执行操作系统重启、强制重启、切断电源操作或异常关机后会被自动截断,会造成数据丢失的风险。非日志表中的内容也不会被复制到备服务器中。在非日志表中创建的索引也不会被自动记录。 - - 使用场景:非日志表不能保证数据的安全性,用户应该在确保数据已经做好备份的前提下使用,例如系统升级时进行数据的备份。 - - 故障处理:当异常关机等操作导致非日志表上的索引发生数据丢失时,用户应该对发生错误的索引进行重建。 - -- **GLOBAL | LOCAL** - - 创建临时表时可以在TEMP或TEMPORARY前指定GLOBAL或LOCAL关键字。如果指定GLOBAL关键字,openGauss会创建全局临时表,否则openGauss会创建本地临时表。 - -- **TEMPORARY | TEMP** - - 如果指定TEMP或TEMPORARY关键字,则创建的表为临时表。临时表分为全局临时表和本地临时表两种类型。创建临时表时如果指定GLOBAL关键字则为全局临时表,否则为本地临时表。 - - 全局临时表的元数据对所有会话可见,会话结束后元数据继续存在。会话与会话之间的用户数据、索引和统计信息相互隔离,每个会话只能看到和更改自己提交的数据。全局临时表有两种模式:一种是基于会话级别的\(ON COMMIT PRESERVE ROWS\), 当会话结束时自动清空用户数据;一种是基于事务级别的\(ON COMMIT DELETE ROWS\), 当执行commit或rollback时自动清空用户数据。建表时如果没有指定ON COMMIT选项,则缺省为会话级别。与本地临时表不同,全局临时表建表时可以指定非pg\_temp\_开头的schema。 - - 本地临时表只在当前会话可见,本会话结束后会自动删除。因此,在除当前会话连接的数据库节点故障时,仍然可以在当前会话上创建和使用临时表。由于临时表只在当前会话创建,对于涉及对临时表操作的DDL语句,会产生DDL失败的报错。因此,建议DDL语句中不要对临时表进行操作。TEMP和TEMPORARY等价。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - >- 本地临时表通过每个会话独立的以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并行执行一起使用。 - >- 临时表不支持主备切换。 - >- 全局临时表不响应自动清理,在长链接场景使用时尽量使用on commit delete rows的全局临时表,或定期手动执行vacuum,否则可能导致clog日志不回收。 - -- **IF NOT EXISTS** - - 如果已经存在相同名称的表,不会报出错误,而会发出通知,告知通知此表已存在。 - -- **table\_name** - - 要创建的表名。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - > - >- 物化视图的一些处理逻辑会通过表名的前缀来识别是不是物化视图日志表和物化视图关联表,因此,用户不要创建表名以mlog\_或matviewmap\_为前缀的表,否则会影响此表的一些功能。 - -- **column\_name** - - 新表中要创建的字段名。 - -- **constraint\_name** - - 建表时指定的约束名称。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - > - >在B模式数据库下(即sql\_compatibility = 'B')constraint\_name为可选项,在其他模式数据库下,必须加上constraint\_name。 - -- **index\_name** - - 索引名。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - > - >- index\_name仅在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库下不支持。 - >- 对于外键约束,constraint\_name和index\_name同时指定时,索引名为constraint\_name。 - >- 对于唯一键约束,constraint\_name和index\_name同时指定时,索引名以index\_name。 - -- **USING method** - - 指定创建索引的方法。 - - 取值范围参考[参数说明](CREATE-INDEX.md)中的USING method。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - > - >- USING method仅在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库下不支持。 - >- 在B模式下,未指定USING method时,对于ASTORE的存储方式,默认索引方法为btree;对于USTORE的存储方式,默认索引方法为ubtree。 - -- **ASC | DESC** - - ASC表示指定按升序排序(默认)。DESC指定按降序排序。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - > - >ASC|DESC只在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库不支持。 - -- **expression** - - >![](public_sys-resources/icon-notice.gif) **须知:** - > - >表达式索引只在B模式数据库下支持(即sql\_compatibility = 'B'),其他模式数据库不支持。 - -- **data\_type** - - 字段的数据类型。 - -- **compress\_mode** - - 表字段的压缩选项。该选项指定表字段优先使用的压缩算法。行存表不支持压缩。 - - 取值范围:DELTA、PREFIX、DICTIONARY、NUMSTR、NOCOMPRESS - - - DELTA压缩仅支持长度为1-8字节的数据类型(0 < pg_type.typlen <= 8)。 - - PREFIX、NUMSTR压缩仅支持变长数据类型(pg_type.typlen = -1)和NULL结尾的C字符串(pg_type.typlen = -2)。 - - 该压缩选项与列存表自适应压缩算法无关,后者为列存表内部数据存储采用的压缩算法,不支持用户指定。 - -- **CHARACTER SET | CHARSET charset** - - 只在B模式数据库下(即sql\_compatibility = 'B')支持该语法,其他模式数据库不支持。指定表字段的字符集,单独指定时会将字段的字符序设置为指定的字符集的默认字符序。 - -- **COLLATE collation** - - COLLATE子句指定列的排序规则(字符序)(该列必须是可排列的数据类型)。如果没有指定,则使用默认的排序规则。排序规则可以使用“select \* from pg\_collation;”命令从pg\_collation系统表中查询,默认的排序规则为查询结果中以default开始的行。对于B模式数据库下(即sql\_compatibility = 'B')还支持utf8mb4\_bin、utf8mb4\_general\_ci、utf8mb4\_unicode\_ci、binary字符序。 - - > ![](public_sys-resources/icon-note.gif)**说明:** - > - > - 仅字符类型支持指定字符集,指定为binary字符集或字符序实际是将字符类型转化为对应的二进制类型,若类型映射不存在则报错。当前仅有TEXT类型转化为BLOB的映射。 - > - 除binary字符集和字符序外,当前仅支持指定与数据库编码相同的字符集。 - > - 未显式指定字段字符集或字符序时,若指定了表的默认字符集或字符序,字段字符集和字符序将从表上继承。若表的默认字符集或字符序不存在,当b\_format\_behavior\_compat\_options = 'default\_collation'时,字段的字符集和字符序将继承当前数据库的字符集及其对应的默认字符序。 - - **表 1** B模式(即sql\_compatibility = 'B')下支持的字符集和字符序介绍 - - - - - - - - - - - - - - - - - - - - - - - - - -

字符序名称

-

对应的字符集

-

描述

-

utf8mb4_general_ci

-

utf8mb4(即utf8)

-

使用通用排序规则,不区分大小写。

-

utf8mb4_unicode_ci

-

utf8mb4(即utf8)

-

使用通用排序规则,不区分大小写。

-

utf8mb4_bin

-

utf8mb4(即utf8)

-

使用二进制排序规则,区分大小写。

-

binary

-

binary

-

使用二进制排序规则。

-
- - -- **LIKE source\_table \[ like\_option ... \]** - - LIKE子句声明一个表,新表自动从这个表中继承所有字段名及其数据类型和非空约束。 - - 新表与源表之间在创建动作完毕之后是完全无关的。在源表做的任何修改都不会传播到新表中,并且也不可能在扫描源表的时候包含新表的数据。 - - 被复制的列和约束并不使用相同的名称进行融合。如果明确的指定了相同的名称或者在另外一个LIKE子句中,将会报错。 - - - 源表上的字段缺省表达式只有在指定INCLUDING DEFAULTS时,才会复制到新表中。缺省是不包含缺省表达式的,即新表中的所有字段的缺省值都是NULL。 - - 源表上的CHECK约束仅在指定INCLUDING CONSTRAINTS时,会复制到新表中,而其他类型的约束永远不会复制到新表中。非空约束总是复制到新表中。此规则同时适用于表约束和列约束。 - - 如果指定了INCLUDING INDEXES,则源表上的索引也将在新表上创建,默认不建立索引。 - - 如果指定了INCLUDING STORAGE,则复制列的STORAGE设置会复制到新表中,默认情况下不包含STORAGE设置。 - - 如果指定了INCLUDING COMMENTS,则源表列、约束和索引的注释会复制到新表中。默认情况下,不复制源表的注释。 - - 如果指定了INCLUDING PARTITION,则源表的分区定义会复制到新表中,同时新表将不能再使用PARTITION BY子句。默认情况下,不拷贝源表的分区定义。如果源表上带有索引,可以使用INCLUDING PARTITION INCLUDING INDEXES语法实现。如果对分区表只使用INCLUDING INDEXES,目标表定义将是普通表,但是索引是分区索引,最后结果会报错,因为普通表不支持分区索引。 - - 如果指定了INCLUDING RELOPTIONS,则源表的存储参数(即源表的WITH子句)会复制到新表中。默认情况下,不复制源表的存储参数。 - - INCLUDING ALL包含了INCLUDING DEFAULTS、INCLUDING CONSTRAINTS、INCLUDING INDEXES、INCLUDING STORAGE、INCLUDING COMMENTS、INCLUDING PARTITION和INCLUDING RELOPTIONS的内容。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - > - >- 如果源表包含serial、bigserial、smallserial、largeserial类型,或者源表字段的默认值是sequence,且sequence属于源表(通过CREATE SEQUENCE ... OWNED BY创建),这些Sequence不会关联到新表中,新表中会重新创建属于自己的sequence。这和之前版本的处理逻辑不同。如果用户希望源表和新表共享Sequence,需要首先创建一个共享的Sequence(避免使用OWNED BY),并配置为源表字段默认值,这样创建的新表会和源表共享该Sequence。 - >- 不建议将其他表私有的Sequence配置为源表字段的默认值,尤其是其他表只分布在特定的NodeGroup上,这可能导致CREATE TABLE ... LIKE执行失败。另外,如果源表配置其他表私有的Sequence,当该表删除时Sequence也会连带删除,这样源表的Sequence将不可用。如果用户希望多个表共享Sequence,建议创建共享的Sequence。 - >- 对于分区表EXCLUDING,需要配合INCLUDING ALL使用,如INCLUDING ALL EXCLUDING DEFAULTS,除源分区表的DEFAULTS,其它全包含。 - -- **AUTO\_INCREMENT \[ = \] value** - - 这个子句为自动增长列指定一个初始值,value必须为正整数,不得超过2127-1。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - > - >该子句仅在参数sql\_compatibility=B时有效。 - -- **WITH \( \{ storage\_parameter = value \} \[, ... \] \)** - - 这个子句为表或索引指定一个可选的存储参数。用于表的WITH子句还可以包含OIDS=FALSE表示不分配OID。 - - >![](public_sys-resources/icon-note.gif) **说明:** - > - >使用任意精度类型Numeric定义列时,建议指定精度p以及刻度s。在不指定精度和刻度时,会按输入的显示出来。 - - 参数的详细描述如下所示。 - - - FILLFACTOR - - 一个表的填充因子(fillfactor)是一个介于10和100之间的百分数。100(完全填充)是默认值。如果指定了较小的填充因子,INSERT操作仅按照填充因子指定的百分率填充表页。每个页上的剩余空间将用于在该页上更新行,这就使得UPDATE有机会在同一页上放置同一条记录的新版本,这比把新版本放置在其他页上更有效。对于一个从不更新的表将填充因子设为100是最佳选择,但是对于频繁更新的表,选择较小的填充因子则更加合适。该参数对于列存表没有意义。 - - 取值范围:10\~100 - - - ORIENTATION - - 指定表数据的存储方式,即行存方式、列存方式,该参数设置成功后就不再支持修改。 - - 取值范围: - - - ROW,表示表的数据将以行式存储。 - - 行存储适合于OLTP业务,适用于点查询或者增删操作较多的场景。 - - - COLUMN,表示表的数据将以列式存储。 - - 列存储适合于数据仓库业务,此类型的表上会做大量的汇聚计算,且涉及的列操作较少。 - - 默认值: - - 若指定表空间为普通表空间,默认值为ROW。 - - - STORAGE\_TYPE - - 指定存储引擎类型,该参数设置成功后就不再支持修改。 - - 取值范围: - - - USTORE,表示表支持Inplace-Update存储引擎。特别需要注意,使用USTORE表,必须要开启track\_counts和track\_activities参数,否则会引起空间膨胀。 - - ASTORE,表示表支持Append-Only存储引擎。 - - 默认值: - - 不指定表时,默认是Append-Only存储。 - - - INIT\_TD - - 创建Ustore表时,指定初始化的TD个数,该参数只在创建Ustore表时才能设置生效。 - - 取值范围:2\~128,默认值为4。 - - - COMPRESSION - - 指定表数据的压缩级别,它决定了表数据的压缩比以及压缩时间。一般来讲,压缩级别越高,压缩比也越大,压缩时间也越长;反之亦然。实际压缩比取决于加载的表数据的分布特征。行存表默认增加COMPRESSION=NO字段。 - - 取值范围: - - 列存表的有效值为YES/NO/LOW/MIDDLE/HIGH,默认值为LOW。 - - - COMPRESSLEVEL - - 指定表数据同一压缩级别下的不同压缩水平,它决定了同一压缩级别下表数据的压缩比以及压缩时间。对同一压缩级别进行了更加详细的划分,为用户选择压缩比和压缩时间提供了更多的空间。总体来讲,此值越大,表示同一压缩级别下压缩比越大,压缩时间越长;反之亦然。 - - 取值范围:0\~3,默认值为0。 - - - COMPRESSTYPE - - 行存表参数,设置行存表压缩算法。1代表pglz算法(不推荐使用),2代表zstd算法,默认不压缩。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。(仅支持ASTORE和USTORE下的普通表和分区表) - - 取值范围:0\~2,默认值为0。 - - - COMPRESS\_LEVEL - - 行存表参数,设置行存表压缩算法等级,仅当COMPRESSTYPE为2时生效。压缩等级越高,表的压缩效果越好,表的访问速度越慢。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - - 取值范围:-31\~31,默认值为0。 - - - COMPRESS\_CHUNK_SIZE - - 行存表参数,设置行存表压缩chunk块大小,仅当COMPRESSTYPE不为0时生效。chunk数据块越小,预期能达到的压缩效果越好,同时数据越离散,影响表的访问速度。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - 取值范围:与页面大小有关。在页面大小为8k场景,取值范围为:512、1024、2048、4096。 - - 默认值:4096 - - - COMPRESS_PREALLOC_CHUNKS - - 行存表参数,设置行存表压缩chunk块预分配数量。预分配数量越大,表的压缩率相对越差,离散度越小,访问性能越好。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - - 取值范围:0\~7,默认值为0。 - - - 当COMPRESS\_CHUNK_SIZE为512和1024时,支持预分配设置最大为7。 - - 当COMPRESS\_CHUNK_SIZE为2048时,支持预分配设置最大为3。 - - 当COMPRESS\_CHUNK_SIZE为4096时,支持预分配设置最大为1。 - - - COMPRESS_BYTE_CONVERT - - 行存表参数,设置行存表压缩字节转换预处理,仅当COMPRESSTYPE不为0时生效。在一些场景下可以提升压缩效果,同时会导致一定性能劣化。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - - 取值范围:布尔值,默认关闭。 - - - COMPRESS_DIFF_CONVERT - - 行存表参数,设置行存表压缩字节差分预处理。只能与compress_byte_convert一起使用。在一些场景下可以提升压缩效果,同时会导致一定性能劣化。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - - 取值范围:布尔值,默认关闭。 - - - MAX\_BATCHROW - - 指定了在数据加载过程中一个存储单元可以容纳记录的最大数目。该参数只对列存表有效。 - - 取值范围:10000\~60000,默认60000。 - - - PARTIAL\_CLUSTER\_ROWS - - 指定了在数据加载过程中进行将局部聚簇存储的记录数目。该参数只对列存表有效。 - - 取值范围:大于等于MAX\_BATCHROW,建议取值为MAX\_BATCHROW的整数倍。 - - - DELTAROW\_THRESHOLD - - 指定列存表导入时小于多少行的数据进入delta表,只在GUC参数enable\_delta\_store开启时生效。该参数只对列存表有效。 - - 取值范围:0~9999,默认值为100 - - - segment - - 使用段页式的方式存储。本参数仅支持行存表。不支持列存表、临时表、unlog表。不支持ustore存储引擎。 - - 取值范围:on/off - - 默认值:off - - - dek\_cipher - - 透明数据加密密钥的密文。当开启enable\_tde选项时会自动申请创建,用户不可单独指定。通过密钥轮转功能可以对密钥进行更新。 - - 取值范围:字符串。 - - 默认值:不开启加密时默认为空。 - - - hasuids - - 参数开启:更新表元组时,为元组分配表级唯一标识id。 - - 取值范围:on/off。 - - 默认值:off。 - - - collate - - 在B模式数据库下(即sql\_compatibility = 'B')用于记录表的默认字符序,一般只用于内部存储和导入导出,不推荐用户指定或修改。 - - 取值范围:B模式数据库中独立支持的字符序的oid。 - - 默认值:0。 - -- **WITHOUT OIDS** - - 等价于WITH(OIDS=FALSE)的语法 - -- **ON COMMIT \{ PRESERVE ROWS | DELETE ROWS | DROP \}** - - ON COMMIT选项决定在事务中执行创建临时表操作,当事务提交时,此临时表的后续操作。有以下三个选项,当前支持PRESERVE ROWS和DELETE ROWS选项。 - - - PRESERVE ROWS(缺省值):提交时不对临时表做任何操作,临时表及其表数据保持不变。 - - DELETE ROWS:提交时删除临时表中数据。 - - DROP:提交时删除此临时表。只支持本地临时表,不支持全局临时表。 - -- **COMPRESS | NOCOMPRESS** - - 创建新表时,需要在CREATE TABLE语句中指定关键字COMPRESS,这样,当对该表进行批量插入时就会触发压缩特性。该特性会在页范围内扫描所有元组数据,生成字典、压缩元组数据并进行存储。指定关键字NOCOMPRESS则不对表进行压缩。行存表不支持压缩。 - - 缺省值:NOCOMPRESS,即不对元组数据进行压缩。 - -- **TABLESPACE tablespace\_name** - - 创建新表时指定此关键字,表示新表将要在指定表空间内创建。如果没有声明,将使用默认表空间。 - -- **COMMNET {=| } text** - - 创建新表时指定此关键字,表示新表的注释内容。如果没有声明,则不创建注释。 - -- **CONSTRAINT constraint\_name** - - 列约束或表约束的名称。可选的约束子句用于声明约束,新行或者更新的行必须满足这些约束才能成功插入或更新。 - - 定义约束有两种方法: - - - 列约束:作为一个列定义的一部分,仅影响该列。 - - 表约束:不和某个列绑在一起,可以作用于多个列。 - -- **NOT NULL** - - 字段值不允许为NULL。 - -- **NULL** - - 字段值允许为NULL ,这是缺省值。 - - 这个子句只是为和非标准SQL数据库兼容。不建议使用。 - -- **CHECK \( expression \)** - - CHECK约束声明一个布尔表达式,每次要插入的新行或者要更新的行的新值必须使表达式结果为真或未知才能成功,否则会抛出一个异常并且不会修改数据库。 - - 声明为字段约束的检查约束应该只引用该字段的数值,而在表约束里出现的表达式可以引用多个字段。 - - >![](public_sys-resources/icon-note.gif) **说明:** - > - >expression表达式中,如果存在“<\>NULL”或“!=NULL”,这种写法是无效的,需要写成“is NOT NULL”。 - -- **DEFAULT default\_expr** - - DEFAULT子句给字段指定缺省值。该数值可以是任何不含变量的表达式\(不允许使用子查询和对本表中的其他字段的交叉引用\)。缺省表达式的数据类型必须和字段类型匹配。 - - 缺省表达式将被用于任何未声明该字段数值的插入操作。如果没有指定缺省值则缺省值为NULL 。 - -- **GENERATED ALWAYS AS \( generation\_expr \) \[STORED\]** - - 该子句将字段创建为生成列,生成列的值在写入(插入或更新)数据时由generation\_expr计算得到,STORED表示像普通列一样存储生成列的值。 - - >![](public_sys-resources/icon-note.gif) **说明:** -> - >- STORED关键字可省略,与不省略STORED语义相同。 ->- 生成表达式不能以任何方式引用当前行以外的其他数据。生成表达式不能引用其他生成列,不能引用系统列。生成表达式不能返回结果集,不能使用子查询,不能使用聚集函数,不能使用窗口函数。生成表达式调用的函数只能是不可变(IMMUTABLE)函数。 - >- 不能为生成列指定默认值。 ->- 生成列不能作为分区键的一部分。 - >- 生成列不能和ON UPDATE约束字句的CASCADE,SET NULL,SET DEFAULT动作同时指定。生成列不能和ON DELETE约束字句的SET NULL,SET DEFAULT动作同时指定。 - >- 修改和删除生成列的方法和普通列相同。删除生成列依赖的普通列,生成列被自动删除。不能改变生成列所依赖的列的类型。 - >- 生成列不能被直接写入。在INSERT或UPDATE命令中, 不能为生成列指定值, 但是可以指定关键字DEFAULT。 - >- 生成列的权限控制和普通列一样。 - >- 列存表、内存表MOT不支持生成列。外表中仅postgres\_fdw支持生成列。 - -- **AUTO\_INCREMENT** - - 该关键字将字段指定为自动增长列。 - - 若在插入时不指定此列的值(或指定此列的值为0、NULL、DEFAULT),此列的值将由自增计数器自动增长得到。 - - 若插入或更新此列为一个大于当前自增计数器的值,执行成功后,自增计数器将刷新为此值。 - - 自增初始值由“AUTO\_INCREMENT \[ = \] value”子句设置,若不设置,默认为1。 - - >![](public_sys-resources/icon-note.gif) **说明:** - > - >- 仅在参数sql\_compatibility=B时可以指定自动增长列。 - >- 自动增长列数据类型只能为整数类型、4字节或8字节浮点类型、布尔类型。 - >- 每个表只能有一个自动增长列。 - >- 自动增长列必须是主键约束或唯一约束的第一个字段。 - >- 自动增长列不能指定DEFAULT缺省值。 - >- CHECK约束的表达式中不能含有自动增长列。 - >- 可以指定自动增长列允许NULL,若不指定,默认自动增长列含有NOT NULL约束。 - >- 含有自动增长列的表创建时,会创建一个依赖于此列的序列作为自增计数器,不允许通过序列相关功能修改 或删除此序列,可以查看序列的值。 - >- 本地临时表中的自动增长列不会创建序列。 - >- 自动增长列不支持列式存储。 - >- 自增计数器自增和刷新操作不会回滚。 - - -- **\[DEFAULT\] CHARACTER SET | CHARSET \[ = \] default\_charset** - - 仅在sql\_compatibility='B'时支持该语法。指定表的默认字符集,单独指定时会将表的默认字符序设置为指定的字符集的默认字符序。 - -- **\[DEFAULT\] COLLATE \[ = \] default\_collation** - - 仅在sql\_compatibility='B'时支持该语法。指定表的默认字符序,单独指定时会将表的默认字符集设置为指定的字符序对应的字符集。字符序参见[表1 B模式(即sql\_compatibility = 'B')下支持的字符集和字符序介绍](#table8163190152)。 - - >![](public_sys-resources/icon-note.gif) **说明:** - >未显式指定表的字符集或字符序时,若指定了模式的默认字符集或字符序,表字符集和字符序将从模式上继承。若模式的默认字符集或字符序不存在,当b\_format\_behavior\_compat\_options = 'default\_collation'时,表的字符集和字符序将继承当前数据库的字符集及其对应的默认字符序。 - -- **UNIQUE [KEY] index\_parameters** - - **UNIQUE \( column\_name \[, ... \] \) index\_parameters** - - UNIQUE约束表示表里的一个字段或多个字段的组合必须在全表范围内唯一。 - - 对于唯一约束,NULL被认为是互不相等的。 - - UNIQUE KEY只能在sql\_compatibility='B'时使用,与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** - - 这两个关键字设置该约束是否可推迟。一个不可推迟的约束将在每条命令之后马上检查。可推迟约束可以推迟到事务结尾使用SET CONSTRAINTS命令检查。缺省是NOT DEFERRABLE。目前,UNIQUE约束、主键约束、外键约束可以接受这个子句。所有其他约束类型都是不可推迟的。 - - >![](public_sys-resources/icon-note.gif) **说明:** - > - >Ustore表不支持**DEFERRABLE以及INITIALLY DEFERRED**关键字。 - -- **COMMENT text** - - 注释。 - -- **VISIBLE | INVISIBLE** - - 指定索引是否可见,如果没有声明则默认为VISIBLE。 - -- **PARTIAL CLUSTER KEY** - - 局部聚簇存储,列存表导入数据时按照指定的列\(单列或多列\),进行局部排序。 - -- **INITIALLY IMMEDIATE | INITIALLY DEFERRED** - - 如果约束是可推迟的,则这个子句声明检查约束的缺省时间。 - - - 如果约束是INITIALLY IMMEDIATE(缺省),则在每条语句执行之后就立即检查它; - - 如果约束是INITIALLY DEFERRED ,则只有在事务结尾才检查它。 - - 约束检查的时间可以用SET CONSTRAINTS命令修改。 - -- **USING INDEX TABLESPACE tablespace\_name** - - 为UNIQUE或PRIMARY KEY约束相关的索引声明一个表空间。如果没有提供这个子句,这个索引将在default\_tablespace中创建,如果default\_tablespace为空,将使用数据库的缺省表空间。 - -- **ENCRYPTION\_TYPE = encryption\_type\_value** - - 为ENCRYPTED WITH约束中的加密类型,encryption\_type\_value的值为\[ DETERMINISTIC | RANDOMIZED \] - - -## 示例 - -``` ---创建简单的表。 -openGauss=# CREATE TABLE tpcds.warehouse_t1 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); - -openGauss=# CREATE TABLE tpcds.warehouse_t2 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60), - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); -``` - -``` ---创建表,并指定W_STATE字段的缺省值为GA。 -openGauss=# CREATE TABLE tpcds.warehouse_t3 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) DEFAULT 'GA', - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); - ---创建表,并在事务结束时检查W_WAREHOUSE_NAME字段是否有重复。 -openGauss=# CREATE TABLE tpcds.warehouse_t4 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) UNIQUE DEFERRABLE, - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); -``` - -``` ---创建一个带有70%填充因子的表。 -openGauss=# CREATE TABLE tpcds.warehouse_t5 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2), - UNIQUE(W_WAREHOUSE_NAME) WITH(fillfactor=70) -); - ---或者用下面的语法。 -openGauss=# CREATE TABLE tpcds.warehouse_t6 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) UNIQUE, - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -) WITH(fillfactor=70); - ---创建表,并指定该表数据不写入预写日志。 -openGauss=# CREATE UNLOGGED TABLE tpcds.warehouse_t7 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); - ---创建表临时表。 -openGauss=# CREATE TEMPORARY TABLE warehouse_t24 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); - ---创建本地临时表,并指定提交事务时删除该临时表数据。 -openGauss=# CREATE TEMPORARY TABLE warehouse_t25 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -) ON COMMIT DELETE ROWS; - ---创建全局临时表,并指定会话结束时删除该临时表数据。当前Ustore存储引擎不支持全局临时表。 - -openGauss=# CREATE GLOBAL TEMPORARY TABLE gtt1 -( - ID INTEGER NOT NULL, - NAME CHAR(16) NOT NULL, - ADDRESS VARCHAR(50) , - POSTCODE CHAR(6) -) ON COMMIT PRESERVE ROWS; - ---创建表时,不希望因为表已存在而报错。 -openGauss=# CREATE TABLE IF NOT EXISTS tpcds.warehouse_t8 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); - ---创建普通表空间。 -openGauss=# CREATE TABLESPACE DS_TABLESPACE1 RELATIVE LOCATION 'tablespace/tablespace_1'; ---创建表时,指定表空间。 -openGauss=# CREATE TABLE tpcds.warehouse_t9 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -) TABLESPACE DS_TABLESPACE1; - ---创建表时,单独指定W_WAREHOUSE_NAME的索引表空间。 -openGauss=# CREATE TABLE tpcds.warehouse_t10 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) UNIQUE USING INDEX TABLESPACE DS_TABLESPACE1, - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); -``` - -``` ---创建一个有主键约束的表。 -openGauss=# CREATE TABLE tpcds.warehouse_t11 -( - W_WAREHOUSE_SK INTEGER PRIMARY KEY, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); - ----或是用下面的语法,效果完全一样。 -openGauss=# CREATE TABLE tpcds.warehouse_t12 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2), - PRIMARY KEY(W_WAREHOUSE_SK) -); - ---或是用下面的语法,指定约束的名称。 -openGauss=# CREATE TABLE tpcds.warehouse_t13 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2), - CONSTRAINT W_CSTR_KEY1 PRIMARY KEY(W_WAREHOUSE_SK) -); - ---创建一个有复合主键约束的表。 -openGauss=# CREATE TABLE tpcds.warehouse_t14 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2), - CONSTRAINT W_CSTR_KEY2 PRIMARY KEY(W_WAREHOUSE_SK, W_WAREHOUSE_ID) -); ---创建列存表。 -openGauss=# CREATE TABLE tpcds.warehouse_t15 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -) WITH (ORIENTATION = COLUMN); - ---创建局部聚簇存储的列存表。 -openGauss=# CREATE TABLE tpcds.warehouse_t16 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2), - PARTIAL CLUSTER KEY(W_WAREHOUSE_SK, W_WAREHOUSE_ID) -) WITH (ORIENTATION = COLUMN); - ---定义一个带压缩的列存表。 -openGauss=# CREATE TABLE tpcds.warehouse_t17 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -) WITH (ORIENTATION = COLUMN, COMPRESSION=HIGH); - - ---定义一个检查列约束。 -openGauss=# CREATE TABLE tpcds.warehouse_t19 -( - W_WAREHOUSE_SK INTEGER PRIMARY KEY CHECK (W_WAREHOUSE_SK > 0), - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) CHECK (W_WAREHOUSE_NAME IS NOT NULL), - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); - -openGauss=# CREATE TABLE tpcds.warehouse_t20 -( - W_WAREHOUSE_SK INTEGER PRIMARY KEY, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) CHECK (W_WAREHOUSE_NAME IS NOT NULL), - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2), - CONSTRAINT W_CONSTR_KEY2 CHECK(W_WAREHOUSE_SK > 0 AND W_WAREHOUSE_NAME IS NOT NULL) -); - ---创建一个有外键约束的表。 -openGauss=# CREATE TABLE tpcds.city_t23 -( - W_CITY VARCHAR(60) PRIMARY KEY, - W_ADDRESS TEXT -); -openGauss=# CREATE TABLE tpcds.warehouse_t23 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) REFERENCES tpcds.city_t23(W_CITY), - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); - ---或是用下面的语法,效果完全一样。 -openGauss=# CREATE TABLE tpcds.warehouse_t23 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) , - FOREIGN KEY(W_CITY) REFERENCES tpcds.city_t23(W_CITY) -); - ---或是用下面的语法,指定约束的名称。 -openGauss=# CREATE TABLE tpcds.warehouse_t23 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) , - CONSTRAINT W_FORE_KEY1 FOREIGN KEY(W_CITY) REFERENCES tpcds.city_t23(W_CITY) -); - ---向tpcds.warehouse_t19表中增加一个varchar列。 -``` - -``` -openGauss=# ALTER TABLE tpcds.warehouse_t19 ADD W_GOODS_CATEGORY varchar(30); - ---给tpcds.warehouse_t19表增加一个检查约束。 -openGauss=# ALTER TABLE tpcds.warehouse_t19 ADD CONSTRAINT W_CONSTR_KEY4 CHECK (W_STATE IS NOT NULL); - ---在一个操作中改变两个现存字段的类型。 -openGauss=# ALTER TABLE tpcds.warehouse_t19 - ALTER COLUMN W_GOODS_CATEGORY TYPE varchar(80), - ALTER COLUMN W_STREET_NAME TYPE varchar(100); - ---此语句与上面语句等效。 -openGauss=# ALTER TABLE tpcds.warehouse_t19 MODIFY (W_GOODS_CATEGORY varchar(30), W_STREET_NAME varchar(60)); - ---给一个已存在字段添加非空约束。 -openGauss=# ALTER TABLE tpcds.warehouse_t19 ALTER COLUMN W_GOODS_CATEGORY SET NOT NULL; - ---移除已存在字段的非空约束。 -openGauss=# ALTER TABLE tpcds.warehouse_t19 ALTER COLUMN W_GOODS_CATEGORY DROP NOT NULL; - ---如果列存表中还未指定局部聚簇,向在一个列存表中添加局部聚簇列。 -openGauss=# ALTER TABLE tpcds.warehouse_t17 ADD PARTIAL CLUSTER KEY(W_WAREHOUSE_SK); - ---查看约束的名称,并删除一个列存表中的局部聚簇列。 -openGauss=# \d+ tpcds.warehouse_t17 - Table "tpcds.warehouse_t17" - Column | Type | Modifiers | Storage | Stats target | Description --------------------+-----------------------+-----------+----------+--------------+------------- - w_warehouse_sk | integer | not null | plain | | - w_warehouse_id | character(16) | not null | extended | | - w_warehouse_name | character varying(20) | | extended | | - w_warehouse_sq_ft | integer | | plain | | - w_street_number | character(10) | | extended | | - w_street_name | character varying(60) | | extended | | - w_street_type | character(15) | | extended | | - w_suite_number | character(10) | | extended | | - w_city | character varying(60) | | extended | | - w_county | character varying(30) | | extended | | - w_state | character(2) | | extended | | - w_zip | character(10) | | extended | | - w_country | character varying(20) | | extended | | - w_gmt_offset | numeric(5,2) | | main | | -Partial Cluster : - "warehouse_t17_cluster" PARTIAL CLUSTER KEY (w_warehouse_sk) -Has OIDs: no -Location Nodes: ALL DATANODES -Options: compression=no, version=0.12 -openGauss=# ALTER TABLE tpcds.warehouse_t17 DROP CONSTRAINT warehouse_t17_cluster; - ---将表移动到另一个表空间。 -openGauss=# ALTER TABLE tpcds.warehouse_t19 SET TABLESPACE PG_DEFAULT; ---创建模式joe。 -openGauss=# CREATE SCHEMA joe; - ---将表移动到另一个模式中。 -openGauss=# ALTER TABLE tpcds.warehouse_t19 SET SCHEMA joe; - ---重命名已存在的表。 -openGauss=# ALTER TABLE joe.warehouse_t19 RENAME TO warehouse_t23; - ---从warehouse_t23表中删除一个字段。 -openGauss=# ALTER TABLE joe.warehouse_t23 DROP COLUMN W_STREET_NAME; - ---创建带INVISIBLE唯一索引的表,需要在B兼容性数据库下 -openGauss=# CREATE TABLE tpcds.warehouse_t26 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) UNIQUE, - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) , - UNIQUE uni_t26 (W_WAREHOUSE_SK) INVISIBLE -) WITH(fillfactor=70); - ---删除表空间、模式joe和模式表warehouse。 -openGauss=# DROP TABLE tpcds.warehouse_t1; -openGauss=# DROP TABLE tpcds.warehouse_t2; -openGauss=# DROP TABLE tpcds.warehouse_t3; -openGauss=# DROP TABLE tpcds.warehouse_t4; -openGauss=# DROP TABLE tpcds.warehouse_t5; -openGauss=# DROP TABLE tpcds.warehouse_t6; -openGauss=# DROP TABLE tpcds.warehouse_t7; -openGauss=# DROP TABLE tpcds.warehouse_t8; -openGauss=# DROP TABLE tpcds.warehouse_t9; -openGauss=# DROP TABLE tpcds.warehouse_t10; -openGauss=# DROP TABLE tpcds.warehouse_t11; -openGauss=# DROP TABLE tpcds.warehouse_t12; -openGauss=# DROP TABLE tpcds.warehouse_t13; -openGauss=# DROP TABLE tpcds.warehouse_t14; -openGauss=# DROP TABLE tpcds.warehouse_t15; -openGauss=# DROP TABLE tpcds.warehouse_t16; -openGauss=# DROP TABLE tpcds.warehouse_t17; -openGauss=# DROP TABLE tpcds.warehouse_t18; -openGauss=# DROP TABLE tpcds.warehouse_t20; -openGauss=# DROP TABLE tpcds.warehouse_t21; -openGauss=# DROP TABLE tpcds.warehouse_t22; -openGauss=# DROP TABLE joe.warehouse_t23; -openGauss=# DROP TABLE tpcds.warehouse_t24; -openGauss=# DROP TABLE tpcds.warehouse_t25; -openGauss=# DROP TABLE tpcds.warehouse_t26; -openGauss=# DROP TABLESPACE DS_TABLESPACE1; -openGauss=# DROP SCHEMA IF EXISTS joe CASCADE; -``` - -## 相关链接 - -[ALTER TABLE](ALTER-TABLE.md),[DROP TABLE](DROP-TABLE.md),[CREATE TABLESPACE](CREATE-TABLESPACE.md) - -## 优化建议 - -- UNLOGGED - - UNLOGGED表和表上的索引因为数据写入时不通过WAL日志机制,写入速度远高于普通表。因此,可以用于缓冲存储复杂查询的中间结果集,增强复杂查询的性能。 - - UNLOGGED表无主备机制,在系统故障或异常断点等情况下,会有数据丢失风险,因此,不可用来存储基础数据。 - -- TEMPORARY | TEMP - - - 临时表只在当前会话可见,会话结束后会自动删除。 - -- 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子句。默认情况下,不拷贝源表的分区定义。 - - >![](public_sys-resources/icon-notice.gif) **须知:** - >列表/哈希分区表暂不支持LIKE INCLUDING PARTITION。 - -- LIKE INCLUDING RELOPTIONS - - - 如果指定了INCLUDING RELOPTIONS,则源表的存储参数(即源表的WITH子句)会复制到新表中。默认情况下,不复制源表的存储参数。 - -- LIKE INCLUDING ALL - - - INCLUDING ALL包含了INCLUDING DEFAULTS、INCLUDING CONSTRAINTS、INCLUDING INDEXES、INCLUDING STORAGE、INCLUDING COMMENTS、INCLUDING PARTITION、INCLUDING RELOPTIONS的内容。 - -- ORIENTATION ROW - - - 创建行存表,行存储适合于OLTP业务,此类型的表上交互事务比较多,一次交互会涉及表中的多个列,用行存查询效率较高。 - -- ORIENTATION COLUMN - - - 创建列存表,列存储适合于数据仓库业务,此类型的表上会做大量的汇聚计算,且涉及的列操作较少。 - - +# CREATE TABLE + +## 功能描述 + +在当前数据库中创建一个新的空白表,该表由命令执行者所有。 + +## 注意事项 + +- 列存表支持的数据类型请参考[列存表支持的数据类型](列存表支持的数据类型.md)。 +- 列存表不支持数组。 +- 列存表不支持生成列。 +- 列存表不支持创建全局临时表。 +- 创建列存表的数量建议不超过1000个。 +- 如果在建表过程中数据库系统发生故障,系统恢复后可能无法自动清除之前已创建的、大小为0的磁盘文件。此种情况出现概率小,不影响数据库系统的正常运行。 +- 列存表的表级约束只支持PARTIAL CLUSTER KEY、UNIQUE、PRIAMRY KEY,不支持外键等表级约束。 +- 列存表的字段约束只支持NULL、NOT NULL和DEFAULT常量值、UNIQUE和PRIMARY KEY。 +- 列存表支持delta表,受参数enable\_delta\_store控制是否开启,受参数deltarow\_threshold控制进入delta表的阀值。 +- 列存表的字段的字符集必须与数据库字符集一致。 +- 使用JDBC时,支持通过PrepareStatement对DEFAULT值进行参数化设置。 +- 每张表的列数最大为1600,具体取决于列的类型,所有列的大小加起来不能超过8192 byte(由于数据存储形式原因,实际上限略小于8192 byte),text、varchar、char等长度可变的类型除外。 +- 被授予CREATE ANY TABLE权限的用户,可以在public模式和用户模式下创建表。如果想要创建包含serial类型列的表,还需要授予CREATE ANY SEQUENCE创建序列的权限。 +- 不可与同一模式下已存在的synonym产生命名冲突。 +- 仅支持在B兼容性数据库下指定COMMENT和可见性VISIBLE\INVISIBLE。 + +## 语法格式 + +创建表。 + +``` +CREATE [ [ GLOBAL | LOCAL ] [ TEMPORARY | TEMP ] | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name + ({ column_name data_type [ CHARACTER SET | CHARSET charset ] [ compress_mode ] [ COLLATE collation ] [ column_constraint [ ... ] ] + | table_constraint + | LIKE source_table [ like_option [...] ] } + [, ... ]) + [ AUTO_INCREMENT [ = ] value ] + [ [DEFAULT] CHARACTER SET | CHARSET [ = ] default_charset ] [ [DEFAULT] COLLATE [ = ] default_collation ] + [ WITH ( {storage_parameter = value} [, ... ] ) ] + [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] + [ COMPRESS | NOCOMPRESS ] + [ TABLESPACE tablespace_name ] + [ COMMENT {=| } 'text' ]; +``` + +- 其中列约束column\_constraint为: + + ``` + [ CONSTRAINT constraint_name ] + { NOT NULL | + NULL | + CHECK ( expression ) | + DEFAULT default_expr | + GENERATED ALWAYS AS ( generation_expr ) [STORED] | + AUTO_INCREMENT | + UNIQUE [KEY] index_parameters | + ENCRYPTED WITH ( COLUMN_ENCRYPTION_KEY = column_encryption_key, ENCRYPTION_TYPE = encryption_type_value ) | + 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 ] + [ COMMENT {=| } 'text' ] + ``` + + +- 其中列的压缩可选项compress\_mode为: + + ``` + { DELTA | PREFIX | DICTIONARY | NUMSTR | NOCOMPRESS } + ``` + +- 其中表约束table\_constraint为: + + ``` + [ CONSTRAINT [ constraint_name ] ] + { CHECK ( expression ) | + UNIQUE [ index_name ][ USING method ] ( { { column_name | ( expression ) } [ ASC | DESC ] } [, ... ] ) index_parameters [ VISIBLE | INVISIBLE ] | + PRIMARY KEY [ USING method ] ( { column_name [ ASC | DESC ] } [, ... ] ) index_parameters [ VISIBLE | INVISIBLE ] | + FOREIGN KEY [ index_name ] ( column_name [, ... ] ) REFERENCES reftable [ (refcolumn [, ... ] ) ] + [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] | + PARTIAL CLUSTER KEY ( column_name [, ... ] ) } + [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] + [ COMMENT {=| } 'text' ] + ``` + + +- 其中like选项like\_option为: + + ``` + { INCLUDING | EXCLUDING } { DEFAULTS | GENERATED | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | PARTITION | RELOPTIONS | ALL } + ``` + +- 其中索引参数index\_parameters为: + + ``` + [ WITH ( {storage_parameter = value} [, ... ] ) ] + [ USING INDEX TABLESPACE tablespace_name ] + ``` + + +## 参数说明 + +- **UNLOGGED** + + 如果指定此关键字,则创建的表为非日志表。在非日志表中写入的数据不会被写入到预写日志中,这样就会比普通表快很多。但是非日志表在冲突、执行操作系统重启、强制重启、切断电源操作或异常关机后会被自动截断,会造成数据丢失的风险。非日志表中的内容也不会被复制到备服务器中。在非日志表中创建的索引也不会被自动记录。 + + 使用场景:非日志表不能保证数据的安全性,用户应该在确保数据已经做好备份的前提下使用,例如系统升级时进行数据的备份。 + + 故障处理:当异常关机等操作导致非日志表上的索引发生数据丢失时,用户应该对发生错误的索引进行重建。 + +- **GLOBAL | LOCAL** + + 创建临时表时可以在TEMP或TEMPORARY前指定GLOBAL或LOCAL关键字。如果指定GLOBAL关键字,openGauss会创建全局临时表,否则openGauss会创建本地临时表。 + +- **TEMPORARY | TEMP** + + 如果指定TEMP或TEMPORARY关键字,则创建的表为临时表。临时表分为全局临时表和本地临时表两种类型。创建临时表时如果指定GLOBAL关键字则为全局临时表,否则为本地临时表。 + + 全局临时表的元数据对所有会话可见,会话结束后元数据继续存在。会话与会话之间的用户数据、索引和统计信息相互隔离,每个会话只能看到和更改自己提交的数据。全局临时表有两种模式:一种是基于会话级别的\(ON COMMIT PRESERVE ROWS\), 当会话结束时自动清空用户数据;一种是基于事务级别的\(ON COMMIT DELETE ROWS\), 当执行commit或rollback时自动清空用户数据。建表时如果没有指定ON COMMIT选项,则缺省为会话级别。与本地临时表不同,全局临时表建表时可以指定非pg\_temp\_开头的schema。 + + 本地临时表只在当前会话可见,本会话结束后会自动删除。因此,在除当前会话连接的数据库节点故障时,仍然可以在当前会话上创建和使用临时表。由于临时表只在当前会话创建,对于涉及对临时表操作的DDL语句,会产生DDL失败的报错。因此,建议DDL语句中不要对临时表进行操作。TEMP和TEMPORARY等价。 + + >![](public_sys-resources/icon-notice.gif) **须知:** + >- 本地临时表通过每个会话独立的以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并行执行一起使用。 + >- 临时表不支持主备切换。 + >- 全局临时表不响应自动清理,在长链接场景使用时尽量使用on commit delete rows的全局临时表,或定期手动执行vacuum,否则可能导致clog日志不回收。 + +- **IF NOT EXISTS** + + 如果已经存在相同名称的表,不会报出错误,而会发出通知,告知通知此表已存在。 + +- **table\_name** + + 要创建的表名。 + + >![](public_sys-resources/icon-notice.gif) **须知:** + > + >- 物化视图的一些处理逻辑会通过表名的前缀来识别是不是物化视图日志表和物化视图关联表,因此,用户不要创建表名以mlog\_或matviewmap\_为前缀的表,否则会影响此表的一些功能。 + +- **column\_name** + + 新表中要创建的字段名。 + +- **constraint\_name** + + 建表时指定的约束名称。 + + >![](public_sys-resources/icon-notice.gif) **须知:** + > + >在B模式数据库下(即sql\_compatibility = 'B')constraint\_name为可选项,在其他模式数据库下,必须加上constraint\_name。 + +- **index\_name** + + 索引名。 + + >![](public_sys-resources/icon-notice.gif) **须知:** + > + >- index\_name仅在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库下不支持。 + >- 对于外键约束,constraint\_name和index\_name同时指定时,索引名为constraint\_name。 + >- 对于唯一键约束,constraint\_name和index\_name同时指定时,索引名以index\_name。 + +- **USING method** + + 指定创建索引的方法。 + + 取值范围参考[参数说明](CREATE-INDEX.md)中的USING method。 + + >![](public_sys-resources/icon-notice.gif) **须知:** + > + >- USING method仅在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库下不支持。 + >- 在B模式下,未指定USING method时,对于ASTORE的存储方式,默认索引方法为btree;对于USTORE的存储方式,默认索引方法为ubtree。 + +- **ASC | DESC** + + ASC表示指定按升序排序(默认)。DESC指定按降序排序。 + + >![](public_sys-resources/icon-notice.gif) **须知:** + > + >ASC|DESC只在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库不支持。 + +- **expression** + + >![](public_sys-resources/icon-notice.gif) **须知:** + > + >表达式索引只在B模式数据库下支持(即sql\_compatibility = 'B'),其他模式数据库不支持。 + +- **data\_type** + + 字段的数据类型。 + +- **compress\_mode** + + 表字段的压缩选项。该选项指定表字段优先使用的压缩算法。行存表不支持压缩。 + + 取值范围:DELTA、PREFIX、DICTIONARY、NUMSTR、NOCOMPRESS + + - DELTA压缩仅支持长度为1-8字节的数据类型(0 < pg_type.typlen <= 8)。 + - PREFIX、NUMSTR压缩仅支持变长数据类型(pg_type.typlen = -1)和NULL结尾的C字符串(pg_type.typlen = -2)。 + - 该压缩选项与列存表自适应压缩算法无关,后者为列存表内部数据存储采用的压缩算法,不支持用户指定。 + +- **CHARACTER SET | CHARSET charset** + + 只在B模式数据库下(即sql\_compatibility = 'B')支持该语法,其他模式数据库不支持。指定表字段的字符集,单独指定时会将字段的字符序设置为指定的字符集的默认字符序。 + +- **COLLATE collation** + + COLLATE子句指定列的排序规则(字符序)(该列必须是可排列的数据类型)。如果没有指定,则使用默认的排序规则。排序规则可以使用“select \* from pg\_collation;”命令从pg\_collation系统表中查询,默认的排序规则为查询结果中以default开始的行。对于B模式数据库下(即sql\_compatibility = 'B')还支持utf8mb4\_bin、utf8mb4\_general\_ci、utf8mb4\_unicode\_ci、binary字符序。 + + > ![](public_sys-resources/icon-note.gif)**说明:** + > + > - 仅字符类型支持指定字符集,指定为binary字符集或字符序实际是将字符类型转化为对应的二进制类型,若类型映射不存在则报错。当前仅有TEXT类型转化为BLOB的映射。 + > - 除binary字符集和字符序外,当前仅支持指定与数据库编码相同的字符集。 + > - 未显式指定字段字符集或字符序时,若指定了表的默认字符集或字符序,字段字符集和字符序将从表上继承。若表的默认字符集或字符序不存在,当b\_format\_behavior\_compat\_options = 'default\_collation'时,字段的字符集和字符序将继承当前数据库的字符集及其对应的默认字符序。 + + **表 1** B模式(即sql\_compatibility = 'B')下支持的字符集和字符序介绍 + + + + + + + + + + + + + + + + + + + + + + + + + +

字符序名称

+

对应的字符集

+

描述

+

utf8mb4_general_ci

+

utf8mb4(即utf8)

+

使用通用排序规则,不区分大小写。

+

utf8mb4_unicode_ci

+

utf8mb4(即utf8)

+

使用通用排序规则,不区分大小写。

+

utf8mb4_bin

+

utf8mb4(即utf8)

+

使用二进制排序规则,区分大小写。

+

binary

+

binary

+

使用二进制排序规则。

+
+ + +- **LIKE source\_table \[ like\_option ... \]** + + LIKE子句声明一个表,新表自动从这个表中继承所有字段名及其数据类型和非空约束。 + + 新表与源表之间在创建动作完毕之后是完全无关的。在源表做的任何修改都不会传播到新表中,并且也不可能在扫描源表的时候包含新表的数据。 + + 被复制的列和约束并不使用相同的名称进行融合。如果明确的指定了相同的名称或者在另外一个LIKE子句中,将会报错。 + + - 源表上的字段缺省表达式只有在指定INCLUDING DEFAULTS时,才会复制到新表中。缺省是不包含缺省表达式的,即新表中的所有字段的缺省值都是NULL。 + - 源表上的CHECK约束仅在指定INCLUDING CONSTRAINTS时,会复制到新表中,而其他类型的约束永远不会复制到新表中。非空约束总是复制到新表中。此规则同时适用于表约束和列约束。 + - 如果指定了INCLUDING INDEXES,则源表上的索引也将在新表上创建,默认不建立索引。 + - 如果指定了INCLUDING STORAGE,则复制列的STORAGE设置会复制到新表中,默认情况下不包含STORAGE设置。 + - 如果指定了INCLUDING COMMENTS,则源表列、约束和索引的注释会复制到新表中。默认情况下,不复制源表的注释。 + - 如果指定了INCLUDING PARTITION,则源表的分区定义会复制到新表中,同时新表将不能再使用PARTITION BY子句。默认情况下,不拷贝源表的分区定义。如果源表上带有索引,可以使用INCLUDING PARTITION INCLUDING INDEXES语法实现。如果对分区表只使用INCLUDING INDEXES,目标表定义将是普通表,但是索引是分区索引,最后结果会报错,因为普通表不支持分区索引。 + - 如果指定了INCLUDING RELOPTIONS,则源表的存储参数(即源表的WITH子句)会复制到新表中。默认情况下,不复制源表的存储参数。 + - INCLUDING ALL包含了INCLUDING DEFAULTS、INCLUDING CONSTRAINTS、INCLUDING INDEXES、INCLUDING STORAGE、INCLUDING COMMENTS、INCLUDING PARTITION和INCLUDING RELOPTIONS的内容。 + + >![](public_sys-resources/icon-notice.gif) **须知:** + > + >- 如果源表包含serial、bigserial、smallserial、largeserial类型,或者源表字段的默认值是sequence,且sequence属于源表(通过CREATE SEQUENCE ... OWNED BY创建),这些Sequence不会关联到新表中,新表中会重新创建属于自己的sequence。这和之前版本的处理逻辑不同。如果用户希望源表和新表共享Sequence,需要首先创建一个共享的Sequence(避免使用OWNED BY),并配置为源表字段默认值,这样创建的新表会和源表共享该Sequence。 + >- 不建议将其他表私有的Sequence配置为源表字段的默认值,尤其是其他表只分布在特定的NodeGroup上,这可能导致CREATE TABLE ... LIKE执行失败。另外,如果源表配置其他表私有的Sequence,当该表删除时Sequence也会连带删除,这样源表的Sequence将不可用。如果用户希望多个表共享Sequence,建议创建共享的Sequence。 + >- 对于分区表EXCLUDING,需要配合INCLUDING ALL使用,如INCLUDING ALL EXCLUDING DEFAULTS,除源分区表的DEFAULTS,其它全包含。 + +- **AUTO\_INCREMENT \[ = \] value** + + 这个子句为自动增长列指定一个初始值,value必须为正整数,不得超过2127-1。 + + >![](public_sys-resources/icon-notice.gif) **须知:** + > + >该子句仅在参数sql\_compatibility=B时有效。 + +- **WITH \( \{ storage\_parameter = value \} \[, ... \] \)** + + 这个子句为表或索引指定一个可选的存储参数。用于表的WITH子句还可以包含OIDS=FALSE表示不分配OID。 + + >![](public_sys-resources/icon-note.gif) **说明:** + > + >使用任意精度类型Numeric定义列时,建议指定精度p以及刻度s。在不指定精度和刻度时,会按输入的显示出来。 + + 参数的详细描述如下所示。 + + - FILLFACTOR + + 一个表的填充因子(fillfactor)是一个介于10和100之间的百分数。100(完全填充)是默认值。如果指定了较小的填充因子,INSERT操作仅按照填充因子指定的百分率填充表页。每个页上的剩余空间将用于在该页上更新行,这就使得UPDATE有机会在同一页上放置同一条记录的新版本,这比把新版本放置在其他页上更有效。对于一个从不更新的表将填充因子设为100是最佳选择,但是对于频繁更新的表,选择较小的填充因子则更加合适。该参数对于列存表没有意义。 + + 取值范围:10\~100 + + - ORIENTATION + + 指定表数据的存储方式,即行存方式、列存方式,该参数设置成功后就不再支持修改。 + + 取值范围: + + - ROW,表示表的数据将以行式存储。 + + 行存储适合于OLTP业务,适用于点查询或者增删操作较多的场景。 + + - COLUMN,表示表的数据将以列式存储。 + + 列存储适合于数据仓库业务,此类型的表上会做大量的汇聚计算,且涉及的列操作较少。该特性在金融版本下不支持。 + + 默认值: + + 若指定表空间为普通表空间,默认值为ROW。 + + - STORAGE\_TYPE + + 指定存储引擎类型,该参数设置成功后就不再支持修改。 + + 取值范围: + + - USTORE,表示表支持Inplace-Update存储引擎。特别需要注意,使用USTORE表,必须要开启track\_counts和track\_activities参数,否则会引起空间膨胀。 + - ASTORE,表示表支持Append-Only存储引擎。 + + 默认值: + + 不指定表时,默认是Append-Only存储。 + + - INIT\_TD + + 创建Ustore表时,指定初始化的TD个数,该参数只在创建Ustore表时才能设置生效。 + + 取值范围:2\~128,默认值为4。 + + - COMPRESSION + + 指定表数据的压缩级别,它决定了表数据的压缩比以及压缩时间。一般来讲,压缩级别越高,压缩比也越大,压缩时间也越长;反之亦然。实际压缩比取决于加载的表数据的分布特征。行存表默认增加COMPRESSION=NO字段。 + + 取值范围: + + 列存表的有效值为YES/NO/LOW/MIDDLE/HIGH,默认值为LOW。 + + - COMPRESSLEVEL + + 指定表数据同一压缩级别下的不同压缩水平,它决定了同一压缩级别下表数据的压缩比以及压缩时间。对同一压缩级别进行了更加详细的划分,为用户选择压缩比和压缩时间提供了更多的空间。总体来讲,此值越大,表示同一压缩级别下压缩比越大,压缩时间越长;反之亦然。 + + 取值范围:0\~3,默认值为0。 + + - COMPRESSTYPE + + 行存表参数,设置行存表压缩算法。1代表pglz算法(不推荐使用),2代表zstd算法,默认不压缩。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。(仅支持ASTORE和USTORE下的普通表和分区表) + + 取值范围:0\~2,默认值为0。 + + - COMPRESS\_LEVEL + + 行存表参数,设置行存表压缩算法等级,仅当COMPRESSTYPE为2时生效。压缩等级越高,表的压缩效果越好,表的访问速度越慢。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + + 取值范围:-31\~31,默认值为0。 + + - COMPRESS\_CHUNK_SIZE + + 行存表参数,设置行存表压缩chunk块大小,仅当COMPRESSTYPE不为0时生效。chunk数据块越小,预期能达到的压缩效果越好,同时数据越离散,影响表的访问速度。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + 取值范围:与页面大小有关。在页面大小为8k场景,取值范围为:512、1024、2048、4096。 + + 默认值:4096 + + - COMPRESS_PREALLOC_CHUNKS + + 行存表参数,设置行存表压缩chunk块预分配数量。预分配数量越大,表的压缩率相对越差,离散度越小,访问性能越好。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + + 取值范围:0\~7,默认值为0。 + + - 当COMPRESS\_CHUNK_SIZE为512和1024时,支持预分配设置最大为7。 + - 当COMPRESS\_CHUNK_SIZE为2048时,支持预分配设置最大为3。 + - 当COMPRESS\_CHUNK_SIZE为4096时,支持预分配设置最大为1。 + + - COMPRESS_BYTE_CONVERT + + 行存表参数,设置行存表压缩字节转换预处理,仅当COMPRESSTYPE不为0时生效。在一些场景下可以提升压缩效果,同时会导致一定性能劣化。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + + 取值范围:布尔值,默认关闭。 + + - COMPRESS_DIFF_CONVERT + + 行存表参数,设置行存表压缩字节差分预处理。只能与compress_byte_convert一起使用。在一些场景下可以提升压缩效果,同时会导致一定性能劣化。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + + 取值范围:布尔值,默认关闭。 + + - MAX\_BATCHROW + + 指定了在数据加载过程中一个存储单元可以容纳记录的最大数目。该参数只对列存表有效。 + + 取值范围:10000\~60000,默认60000。 + + - PARTIAL\_CLUSTER\_ROWS + + 指定了在数据加载过程中进行将局部聚簇存储的记录数目。该参数只对列存表有效。 + + 取值范围:大于等于MAX\_BATCHROW,建议取值为MAX\_BATCHROW的整数倍。 + + - DELTAROW\_THRESHOLD + + 指定列存表导入时小于多少行的数据进入delta表,只在GUC参数enable\_delta\_store开启时生效。该参数只对列存表有效。 + + 取值范围:0~9999,默认值为100 + + - segment + + 使用段页式的方式存储。本参数仅支持行存表。不支持列存表、临时表、unlog表。不支持ustore存储引擎。 + + 取值范围:on/off + + 默认值:off + + - dek\_cipher + + 透明数据加密密钥的密文。当开启enable\_tde选项时会自动申请创建,用户不可单独指定。通过密钥轮转功能可以对密钥进行更新。 + + 取值范围:字符串。 + + 默认值:不开启加密时默认为空。 + + - hasuids + + 参数开启:更新表元组时,为元组分配表级唯一标识id。 + + 取值范围:on/off。 + + 默认值:off。 + + - collate + + 在B模式数据库下(即sql\_compatibility = 'B')用于记录表的默认字符序,一般只用于内部存储和导入导出,不推荐用户指定或修改。 + + 取值范围:B模式数据库中独立支持的字符序的oid。 + + 默认值:0。 + +- **WITHOUT OIDS** + + 等价于WITH(OIDS=FALSE)的语法 + +- **ON COMMIT \{ PRESERVE ROWS | DELETE ROWS | DROP \}** + + ON COMMIT选项决定在事务中执行创建临时表操作,当事务提交时,此临时表的后续操作。有以下三个选项,当前支持PRESERVE ROWS和DELETE ROWS选项。 + + - PRESERVE ROWS(缺省值):提交时不对临时表做任何操作,临时表及其表数据保持不变。 + - DELETE ROWS:提交时删除临时表中数据。 + - DROP:提交时删除此临时表。只支持本地临时表,不支持全局临时表。 + +- **COMPRESS | NOCOMPRESS** + + 创建新表时,需要在CREATE TABLE语句中指定关键字COMPRESS,这样,当对该表进行批量插入时就会触发压缩特性。该特性会在页范围内扫描所有元组数据,生成字典、压缩元组数据并进行存储。指定关键字NOCOMPRESS则不对表进行压缩。行存表不支持压缩。 + + 缺省值:NOCOMPRESS,即不对元组数据进行压缩。 + +- **TABLESPACE tablespace\_name** + + 创建新表时指定此关键字,表示新表将要在指定表空间内创建。如果没有声明,将使用默认表空间。 + +- **COMMNET {=| } text** + + 创建新表时指定此关键字,表示新表的注释内容。如果没有声明,则不创建注释。 + +- **CONSTRAINT constraint\_name** + + 列约束或表约束的名称。可选的约束子句用于声明约束,新行或者更新的行必须满足这些约束才能成功插入或更新。 + + 定义约束有两种方法: + + - 列约束:作为一个列定义的一部分,仅影响该列。 + - 表约束:不和某个列绑在一起,可以作用于多个列。 + +- **NOT NULL** + + 字段值不允许为NULL。 + +- **NULL** + + 字段值允许为NULL ,这是缺省值。 + + 这个子句只是为和非标准SQL数据库兼容。不建议使用。 + +- **CHECK \( expression \)** + + CHECK约束声明一个布尔表达式,每次要插入的新行或者要更新的行的新值必须使表达式结果为真或未知才能成功,否则会抛出一个异常并且不会修改数据库。 + + 声明为字段约束的检查约束应该只引用该字段的数值,而在表约束里出现的表达式可以引用多个字段。 + + >![](public_sys-resources/icon-note.gif) **说明:** + > + >expression表达式中,如果存在“<\>NULL”或“!=NULL”,这种写法是无效的,需要写成“is NOT NULL”。 + +- **DEFAULT default\_expr** + + DEFAULT子句给字段指定缺省值。该数值可以是任何不含变量的表达式\(不允许使用子查询和对本表中的其他字段的交叉引用\)。缺省表达式的数据类型必须和字段类型匹配。 + + 缺省表达式将被用于任何未声明该字段数值的插入操作。如果没有指定缺省值则缺省值为NULL 。 + +- **GENERATED ALWAYS AS \( generation\_expr \) \[STORED\]** + + 该子句将字段创建为生成列,生成列的值在写入(插入或更新)数据时由generation\_expr计算得到,STORED表示像普通列一样存储生成列的值。 + + >![](public_sys-resources/icon-note.gif) **说明:** +> + >- STORED关键字可省略,与不省略STORED语义相同。 +>- 生成表达式不能以任何方式引用当前行以外的其他数据。生成表达式不能引用其他生成列,不能引用系统列。生成表达式不能返回结果集,不能使用子查询,不能使用聚集函数,不能使用窗口函数。生成表达式调用的函数只能是不可变(IMMUTABLE)函数。 + >- 不能为生成列指定默认值。 +>- 生成列不能作为分区键的一部分。 + >- 生成列不能和ON UPDATE约束字句的CASCADE,SET NULL,SET DEFAULT动作同时指定。生成列不能和ON DELETE约束字句的SET NULL,SET DEFAULT动作同时指定。 + >- 修改和删除生成列的方法和普通列相同。删除生成列依赖的普通列,生成列被自动删除。不能改变生成列所依赖的列的类型。 + >- 生成列不能被直接写入。在INSERT或UPDATE命令中, 不能为生成列指定值, 但是可以指定关键字DEFAULT。 + >- 生成列的权限控制和普通列一样。 + >- 列存表、内存表MOT不支持生成列。外表中仅postgres\_fdw支持生成列。 + +- **AUTO\_INCREMENT** + + 该关键字将字段指定为自动增长列。 + + 若在插入时不指定此列的值(或指定此列的值为0、NULL、DEFAULT),此列的值将由自增计数器自动增长得到。 + + 若插入或更新此列为一个大于当前自增计数器的值,执行成功后,自增计数器将刷新为此值。 + + 自增初始值由“AUTO\_INCREMENT \[ = \] value”子句设置,若不设置,默认为1。 + + >![](public_sys-resources/icon-note.gif) **说明:** + > + >- 仅在参数sql\_compatibility=B时可以指定自动增长列。 + >- 自动增长列数据类型只能为整数类型、4字节或8字节浮点类型、布尔类型。 + >- 每个表只能有一个自动增长列。 + >- 自动增长列必须是主键约束或唯一约束的第一个字段。 + >- 自动增长列不能指定DEFAULT缺省值。 + >- CHECK约束的表达式中不能含有自动增长列。 + >- 可以指定自动增长列允许NULL,若不指定,默认自动增长列含有NOT NULL约束。 + >- 含有自动增长列的表创建时,会创建一个依赖于此列的序列作为自增计数器,不允许通过序列相关功能修改 或删除此序列,可以查看序列的值。 + >- 本地临时表中的自动增长列不会创建序列。 + >- 自动增长列不支持列式存储。 + >- 自增计数器自增和刷新操作不会回滚。 + + +- **\[DEFAULT\] CHARACTER SET | CHARSET \[ = \] default\_charset** + + 仅在sql\_compatibility='B'时支持该语法。指定表的默认字符集,单独指定时会将表的默认字符序设置为指定的字符集的默认字符序。 + +- **\[DEFAULT\] COLLATE \[ = \] default\_collation** + + 仅在sql\_compatibility='B'时支持该语法。指定表的默认字符序,单独指定时会将表的默认字符集设置为指定的字符序对应的字符集。字符序参见[表1 B模式(即sql\_compatibility = 'B')下支持的字符集和字符序介绍](#table8163190152)。 + + >![](public_sys-resources/icon-note.gif) **说明:** + >未显式指定表的字符集或字符序时,若指定了模式的默认字符集或字符序,表字符集和字符序将从模式上继承。若模式的默认字符集或字符序不存在,当b\_format\_behavior\_compat\_options = 'default\_collation'时,表的字符集和字符序将继承当前数据库的字符集及其对应的默认字符序。 + +- **UNIQUE [KEY] index\_parameters** + + **UNIQUE \( column\_name \[, ... \] \) index\_parameters** + + UNIQUE约束表示表里的一个字段或多个字段的组合必须在全表范围内唯一。 + + 对于唯一约束,NULL被认为是互不相等的。 + + UNIQUE KEY只能在sql\_compatibility='B'时使用,与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** + + 这两个关键字设置该约束是否可推迟。一个不可推迟的约束将在每条命令之后马上检查。可推迟约束可以推迟到事务结尾使用SET CONSTRAINTS命令检查。缺省是NOT DEFERRABLE。目前,UNIQUE约束、主键约束、外键约束可以接受这个子句。所有其他约束类型都是不可推迟的。 + + >![](public_sys-resources/icon-note.gif) **说明:** + > + >Ustore表不支持**DEFERRABLE以及INITIALLY DEFERRED**关键字。 + +- **COMMENT text** + + 注释。 + +- **VISIBLE | INVISIBLE** + + 指定索引是否可见,如果没有声明则默认为VISIBLE。 + +- **PARTIAL CLUSTER KEY** + + 局部聚簇存储,列存表导入数据时按照指定的列\(单列或多列\),进行局部排序。 + +- **INITIALLY IMMEDIATE | INITIALLY DEFERRED** + + 如果约束是可推迟的,则这个子句声明检查约束的缺省时间。 + + - 如果约束是INITIALLY IMMEDIATE(缺省),则在每条语句执行之后就立即检查它; + - 如果约束是INITIALLY DEFERRED ,则只有在事务结尾才检查它。 + + 约束检查的时间可以用SET CONSTRAINTS命令修改。 + +- **USING INDEX TABLESPACE tablespace\_name** + + 为UNIQUE或PRIMARY KEY约束相关的索引声明一个表空间。如果没有提供这个子句,这个索引将在default\_tablespace中创建,如果default\_tablespace为空,将使用数据库的缺省表空间。 + +- **ENCRYPTION\_TYPE = encryption\_type\_value** + + 为ENCRYPTED WITH约束中的加密类型,encryption\_type\_value的值为\[ DETERMINISTIC | RANDOMIZED \] + + +## 示例 + +``` +--创建简单的表。 +openGauss=# CREATE TABLE tpcds.warehouse_t1 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); + +openGauss=# CREATE TABLE tpcds.warehouse_t2 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60), + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); +``` + +``` +--创建表,并指定W_STATE字段的缺省值为GA。 +openGauss=# CREATE TABLE tpcds.warehouse_t3 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) DEFAULT 'GA', + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); + +--创建表,并在事务结束时检查W_WAREHOUSE_NAME字段是否有重复。 +openGauss=# CREATE TABLE tpcds.warehouse_t4 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) UNIQUE DEFERRABLE, + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); +``` + +``` +--创建一个带有70%填充因子的表。 +openGauss=# CREATE TABLE tpcds.warehouse_t5 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2), + UNIQUE(W_WAREHOUSE_NAME) WITH(fillfactor=70) +); + +--或者用下面的语法。 +openGauss=# CREATE TABLE tpcds.warehouse_t6 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) UNIQUE, + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +) WITH(fillfactor=70); + +--创建表,并指定该表数据不写入预写日志。 +openGauss=# CREATE UNLOGGED TABLE tpcds.warehouse_t7 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); + +--创建表临时表。 +openGauss=# CREATE TEMPORARY TABLE warehouse_t24 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); + +--创建本地临时表,并指定提交事务时删除该临时表数据。 +openGauss=# CREATE TEMPORARY TABLE warehouse_t25 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +) ON COMMIT DELETE ROWS; + +--创建全局临时表,并指定会话结束时删除该临时表数据。当前Ustore存储引擎不支持全局临时表。 + +openGauss=# CREATE GLOBAL TEMPORARY TABLE gtt1 +( + ID INTEGER NOT NULL, + NAME CHAR(16) NOT NULL, + ADDRESS VARCHAR(50) , + POSTCODE CHAR(6) +) ON COMMIT PRESERVE ROWS; + +--创建表时,不希望因为表已存在而报错。 +openGauss=# CREATE TABLE IF NOT EXISTS tpcds.warehouse_t8 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); + +--创建普通表空间。 +openGauss=# CREATE TABLESPACE DS_TABLESPACE1 RELATIVE LOCATION 'tablespace/tablespace_1'; +--创建表时,指定表空间。 +openGauss=# CREATE TABLE tpcds.warehouse_t9 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +) TABLESPACE DS_TABLESPACE1; + +--创建表时,单独指定W_WAREHOUSE_NAME的索引表空间。 +openGauss=# CREATE TABLE tpcds.warehouse_t10 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) UNIQUE USING INDEX TABLESPACE DS_TABLESPACE1, + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); +``` + +``` +--创建一个有主键约束的表。 +openGauss=# CREATE TABLE tpcds.warehouse_t11 +( + W_WAREHOUSE_SK INTEGER PRIMARY KEY, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); + +---或是用下面的语法,效果完全一样。 +openGauss=# CREATE TABLE tpcds.warehouse_t12 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2), + PRIMARY KEY(W_WAREHOUSE_SK) +); + +--或是用下面的语法,指定约束的名称。 +openGauss=# CREATE TABLE tpcds.warehouse_t13 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2), + CONSTRAINT W_CSTR_KEY1 PRIMARY KEY(W_WAREHOUSE_SK) +); + +--创建一个有复合主键约束的表。 +openGauss=# CREATE TABLE tpcds.warehouse_t14 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2), + CONSTRAINT W_CSTR_KEY2 PRIMARY KEY(W_WAREHOUSE_SK, W_WAREHOUSE_ID) +); +--创建列存表。 +openGauss=# CREATE TABLE tpcds.warehouse_t15 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +) WITH (ORIENTATION = COLUMN); + +--创建局部聚簇存储的列存表。 +openGauss=# CREATE TABLE tpcds.warehouse_t16 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2), + PARTIAL CLUSTER KEY(W_WAREHOUSE_SK, W_WAREHOUSE_ID) +) WITH (ORIENTATION = COLUMN); + +--定义一个带压缩的列存表。 +openGauss=# CREATE TABLE tpcds.warehouse_t17 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +) WITH (ORIENTATION = COLUMN, COMPRESSION=HIGH); + + +--定义一个检查列约束。 +openGauss=# CREATE TABLE tpcds.warehouse_t19 +( + W_WAREHOUSE_SK INTEGER PRIMARY KEY CHECK (W_WAREHOUSE_SK > 0), + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) CHECK (W_WAREHOUSE_NAME IS NOT NULL), + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); + +openGauss=# CREATE TABLE tpcds.warehouse_t20 +( + W_WAREHOUSE_SK INTEGER PRIMARY KEY, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) CHECK (W_WAREHOUSE_NAME IS NOT NULL), + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2), + CONSTRAINT W_CONSTR_KEY2 CHECK(W_WAREHOUSE_SK > 0 AND W_WAREHOUSE_NAME IS NOT NULL) +); + +--创建一个有外键约束的表。 +openGauss=# CREATE TABLE tpcds.city_t23 +( + W_CITY VARCHAR(60) PRIMARY KEY, + W_ADDRESS TEXT +); +openGauss=# CREATE TABLE tpcds.warehouse_t23 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) REFERENCES tpcds.city_t23(W_CITY), + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); + +--或是用下面的语法,效果完全一样。 +openGauss=# CREATE TABLE tpcds.warehouse_t23 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) , + FOREIGN KEY(W_CITY) REFERENCES tpcds.city_t23(W_CITY) +); + +--或是用下面的语法,指定约束的名称。 +openGauss=# CREATE TABLE tpcds.warehouse_t23 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) , + CONSTRAINT W_FORE_KEY1 FOREIGN KEY(W_CITY) REFERENCES tpcds.city_t23(W_CITY) +); + +--向tpcds.warehouse_t19表中增加一个varchar列。 +``` + +``` +openGauss=# ALTER TABLE tpcds.warehouse_t19 ADD W_GOODS_CATEGORY varchar(30); + +--给tpcds.warehouse_t19表增加一个检查约束。 +openGauss=# ALTER TABLE tpcds.warehouse_t19 ADD CONSTRAINT W_CONSTR_KEY4 CHECK (W_STATE IS NOT NULL); + +--在一个操作中改变两个现存字段的类型。 +openGauss=# ALTER TABLE tpcds.warehouse_t19 + ALTER COLUMN W_GOODS_CATEGORY TYPE varchar(80), + ALTER COLUMN W_STREET_NAME TYPE varchar(100); + +--此语句与上面语句等效。 +openGauss=# ALTER TABLE tpcds.warehouse_t19 MODIFY (W_GOODS_CATEGORY varchar(30), W_STREET_NAME varchar(60)); + +--给一个已存在字段添加非空约束。 +openGauss=# ALTER TABLE tpcds.warehouse_t19 ALTER COLUMN W_GOODS_CATEGORY SET NOT NULL; + +--移除已存在字段的非空约束。 +openGauss=# ALTER TABLE tpcds.warehouse_t19 ALTER COLUMN W_GOODS_CATEGORY DROP NOT NULL; + +--如果列存表中还未指定局部聚簇,向在一个列存表中添加局部聚簇列。 +openGauss=# ALTER TABLE tpcds.warehouse_t17 ADD PARTIAL CLUSTER KEY(W_WAREHOUSE_SK); + +--查看约束的名称,并删除一个列存表中的局部聚簇列。 +openGauss=# \d+ tpcds.warehouse_t17 + Table "tpcds.warehouse_t17" + Column | Type | Modifiers | Storage | Stats target | Description +-------------------+-----------------------+-----------+----------+--------------+------------- + w_warehouse_sk | integer | not null | plain | | + w_warehouse_id | character(16) | not null | extended | | + w_warehouse_name | character varying(20) | | extended | | + w_warehouse_sq_ft | integer | | plain | | + w_street_number | character(10) | | extended | | + w_street_name | character varying(60) | | extended | | + w_street_type | character(15) | | extended | | + w_suite_number | character(10) | | extended | | + w_city | character varying(60) | | extended | | + w_county | character varying(30) | | extended | | + w_state | character(2) | | extended | | + w_zip | character(10) | | extended | | + w_country | character varying(20) | | extended | | + w_gmt_offset | numeric(5,2) | | main | | +Partial Cluster : + "warehouse_t17_cluster" PARTIAL CLUSTER KEY (w_warehouse_sk) +Has OIDs: no +Location Nodes: ALL DATANODES +Options: compression=no, version=0.12 +openGauss=# ALTER TABLE tpcds.warehouse_t17 DROP CONSTRAINT warehouse_t17_cluster; + +--将表移动到另一个表空间。 +openGauss=# ALTER TABLE tpcds.warehouse_t19 SET TABLESPACE PG_DEFAULT; +--创建模式joe。 +openGauss=# CREATE SCHEMA joe; + +--将表移动到另一个模式中。 +openGauss=# ALTER TABLE tpcds.warehouse_t19 SET SCHEMA joe; + +--重命名已存在的表。 +openGauss=# ALTER TABLE joe.warehouse_t19 RENAME TO warehouse_t23; + +--从warehouse_t23表中删除一个字段。 +openGauss=# ALTER TABLE joe.warehouse_t23 DROP COLUMN W_STREET_NAME; + +--创建带INVISIBLE唯一索引的表,需要在B兼容性数据库下 +openGauss=# CREATE TABLE tpcds.warehouse_t26 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) UNIQUE, + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) , + UNIQUE uni_t26 (W_WAREHOUSE_SK) INVISIBLE +) WITH(fillfactor=70); + +--删除表空间、模式joe和模式表warehouse。 +openGauss=# DROP TABLE tpcds.warehouse_t1; +openGauss=# DROP TABLE tpcds.warehouse_t2; +openGauss=# DROP TABLE tpcds.warehouse_t3; +openGauss=# DROP TABLE tpcds.warehouse_t4; +openGauss=# DROP TABLE tpcds.warehouse_t5; +openGauss=# DROP TABLE tpcds.warehouse_t6; +openGauss=# DROP TABLE tpcds.warehouse_t7; +openGauss=# DROP TABLE tpcds.warehouse_t8; +openGauss=# DROP TABLE tpcds.warehouse_t9; +openGauss=# DROP TABLE tpcds.warehouse_t10; +openGauss=# DROP TABLE tpcds.warehouse_t11; +openGauss=# DROP TABLE tpcds.warehouse_t12; +openGauss=# DROP TABLE tpcds.warehouse_t13; +openGauss=# DROP TABLE tpcds.warehouse_t14; +openGauss=# DROP TABLE tpcds.warehouse_t15; +openGauss=# DROP TABLE tpcds.warehouse_t16; +openGauss=# DROP TABLE tpcds.warehouse_t17; +openGauss=# DROP TABLE tpcds.warehouse_t18; +openGauss=# DROP TABLE tpcds.warehouse_t20; +openGauss=# DROP TABLE tpcds.warehouse_t21; +openGauss=# DROP TABLE tpcds.warehouse_t22; +openGauss=# DROP TABLE joe.warehouse_t23; +openGauss=# DROP TABLE tpcds.warehouse_t24; +openGauss=# DROP TABLE tpcds.warehouse_t25; +openGauss=# DROP TABLE tpcds.warehouse_t26; +openGauss=# DROP TABLESPACE DS_TABLESPACE1; +openGauss=# DROP SCHEMA IF EXISTS joe CASCADE; +``` + +## 相关链接 + +[ALTER TABLE](ALTER-TABLE.md),[DROP TABLE](DROP-TABLE.md),[CREATE TABLESPACE](CREATE-TABLESPACE.md) + +## 优化建议 + +- UNLOGGED + - UNLOGGED表和表上的索引因为数据写入时不通过WAL日志机制,写入速度远高于普通表。因此,可以用于缓冲存储复杂查询的中间结果集,增强复杂查询的性能。 + - UNLOGGED表无主备机制,在系统故障或异常断点等情况下,会有数据丢失风险,因此,不可用来存储基础数据。 + +- TEMPORARY | TEMP + + - 临时表只在当前会话可见,会话结束后会自动删除。 + +- 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子句。默认情况下,不拷贝源表的分区定义。 + + >![](public_sys-resources/icon-notice.gif) **须知:** + >列表/哈希分区表暂不支持LIKE INCLUDING PARTITION。 + +- LIKE INCLUDING RELOPTIONS + + - 如果指定了INCLUDING RELOPTIONS,则源表的存储参数(即源表的WITH子句)会复制到新表中。默认情况下,不复制源表的存储参数。 + +- LIKE INCLUDING ALL + + - INCLUDING ALL包含了INCLUDING DEFAULTS、INCLUDING CONSTRAINTS、INCLUDING INDEXES、INCLUDING STORAGE、INCLUDING COMMENTS、INCLUDING PARTITION、INCLUDING RELOPTIONS的内容。 + +- ORIENTATION ROW + + - 创建行存表,行存储适合于OLTP业务,此类型的表上交互事务比较多,一次交互会涉及表中的多个列,用行存查询效率较高。 + +- ORIENTATION COLUMN + + - 创建列存表,列存储适合于数据仓库业务,此类型的表上会做大量的汇聚计算,且涉及的列操作较少。 + + diff --git a/content/docs-lite/zh/docs/SQLReference/CREATE-TABLESPACE.md b/content/docs-lite/zh/docs/SQLReference/CREATE-TABLESPACE.md index b0d365569279efb011628ddefe5b2e2348067f88..26d97afb67b9f2431b1b5a2231bb84e0bfa74be0 100644 --- a/content/docs-lite/zh/docs/SQLReference/CREATE-TABLESPACE.md +++ b/content/docs-lite/zh/docs/SQLReference/CREATE-TABLESPACE.md @@ -139,4 +139,6 @@ openGauss=# DROP ROLE jay; 不建议在事务内部创建表空间。 +- 创建表空间在金融版本下不支持 + diff --git "a/content/zh/docs/AboutopenGauss/\351\200\217\346\230\216\346\225\260\346\215\256\345\212\240\345\257\206.md" "b/content/zh/docs/AboutopenGauss/\351\200\217\346\230\216\346\225\260\346\215\256\345\212\240\345\257\206.md" index a40c7d94c34c7fe0479d36066a9b9789a5f2668b..3bf19ad0c253677d9f8275e37ceb1e1e56f2e0c4 100644 --- "a/content/zh/docs/AboutopenGauss/\351\200\217\346\230\216\346\225\260\346\215\256\345\212\240\345\257\206.md" +++ "b/content/zh/docs/AboutopenGauss/\351\200\217\346\230\216\346\225\260\346\215\256\345\212\240\345\257\206.md" @@ -1,47 +1,48 @@ -# 透明数据加密 - -## 可获得性 - -本特性自openGauss 2.1.0版本开始引入。 - -## 特性简介 - -透明数据加密(Transparent Data Encryption),是数据库在将数据写入存储介质时对数据进行加密,从存储介质中读取数据时自动解密,防止攻击者绕过数据库认证机制直接读取数据文件中的数据,以解决静态数据泄露问题。该功能对于应用层几乎透明无感知,用户可根据需要决定是否启用透明数据加密功能。 - -## 客户价值 - -为了防止攻击者绕过数据库认证机制直接读取数据文件中的数据,可以通过透明数据加密功能对数据库的数据文件进行加密,保证用户必须在数据库启动后通过正常途径连接数据库,才可以读取解密后的数据,达到数据保护的目的。 - -## 特性描述 - -采用三层密钥结构实现密钥管理机制,即根密钥(RK)、主密钥(CMK)和数据加密密钥(DEK)。主密钥由根密钥加密保护,数据加密密钥由主密钥加密保护。数据加密密钥用于对用户数据进行加密和解密,每个表对应一个数据加密密钥。 - -支持表级加密,允许用户在创建表时指定是否对表进行加密和使用的加密算法,加密算法支持AES\_128\_CTR和SM4\_CTR两种算法,算法一旦指定不可更改。对于创建表时指定为加密的表,数据库会自动为该表申请创建数据加密密钥,并将加密算法、密钥密文和对应主密钥ID等参数使用"keyword=value"格式保存在pg\_class系统表中的reloptions字段中。 - -对于加密表,允许用户切换表的加密状态,即将加密表切换为非加密表,或将非加密表切换为加密表。如果在创建表时未使能加密功能,后续无法再切换为加密表。 - -对于加密表,支持数据加密密钥轮转。密钥轮转后,使用旧密钥加密的数据仍使用旧密钥解密,新写入的数据使用新密钥加密。密钥轮转时不更换加密算法。 - -## 特性增强 - -无。 - -## 特性约束 - -当前版本主要实现对接华为云KMS服务,支持表级密钥存储,实现对行存表加密,规格约束如下: - -- 支持heap存储行存表加密。 -- 不支持列存加密,不支持物化视图加密,不支持ustore存储引擎加密。 -- 不支持索引和Sequence加密,不支持XLOG日志加密,不支持MOT内存表加密,不支持系统表加密。 -- 用户在创建表时可以指定加密算法,加密算法一旦指定不可更改。如果创建表时设置enable\_tde为on,但是不指定加密算法encrypt\_algo,则默认使用AES\_128\_CTR加密算法。 -- 如果在创建表时未开启加密功能或指定加密算法,后续无法再切换为加密表。 -- 对于已分配加密密钥的表,切换表的加密和非加密状态,不会更换密钥和加密算法。 -- 数据密钥轮转只有开启表加密功能时才支持轮转。 -- 不支持单集群跨region的多副本主备同步,不支持单集群跨region的扩容,不支持跨region的备份恢复、集群容灾和数据迁移场景。 -- 混合云场景如果使用华为云KMS和管控面功能,则可以支持透明数据加密,其他KMS服务如果接口不兼容则无法支持。 -- 加密表的查询性能比不加密时会有所劣化,对于性能有较高要求的情况下需谨慎开启加密功能。 - -## 依赖关系 - -依赖外部KMS提供密钥管理服务,目前支持对接华为云KMS服务。 - +# 透明数据加密 + +## 可获得性 + +本特性自openGauss 2.1.0版本开始引入。 + +## 特性简介 + +透明数据加密(Transparent Data Encryption),是数据库在将数据写入存储介质时对数据进行加密,从存储介质中读取数据时自动解密,防止攻击者绕过数据库认证机制直接读取数据文件中的数据,以解决静态数据泄露问题。该功能对于应用层几乎透明无感知,用户可根据需要决定是否启用透明数据加密功能。 + +## 客户价值 + +为了防止攻击者绕过数据库认证机制直接读取数据文件中的数据,可以通过透明数据加密功能对数据库的数据文件进行加密,保证用户必须在数据库启动后通过正常途径连接数据库,才可以读取解密后的数据,达到数据保护的目的。 + +## 特性描述 + +采用三层密钥结构实现密钥管理机制,即根密钥(RK)、主密钥(CMK)和数据加密密钥(DEK)。主密钥由根密钥加密保护,数据加密密钥由主密钥加密保护。数据加密密钥用于对用户数据进行加密和解密,每个表对应一个数据加密密钥。 + +支持表级加密,允许用户在创建表时指定是否对表进行加密和使用的加密算法,加密算法支持AES\_128\_CTR和SM4\_CTR两种算法,算法一旦指定不可更改。对于创建表时指定为加密的表,数据库会自动为该表申请创建数据加密密钥,并将加密算法、密钥密文和对应主密钥ID等参数使用"keyword=value"格式保存在pg\_class系统表中的reloptions字段中。 + +对于加密表,允许用户切换表的加密状态,即将加密表切换为非加密表,或将非加密表切换为加密表。如果在创建表时未使能加密功能,后续无法再切换为加密表。 + +对于加密表,支持数据加密密钥轮转。密钥轮转后,使用旧密钥加密的数据仍使用旧密钥解密,新写入的数据使用新密钥加密。密钥轮转时不更换加密算法。 + +## 特性增强 + +无。 + +## 特性约束 + +当前版本主要实现对接华为云KMS服务,支持表级密钥存储,实现对行存表加密,规格约束如下: + +- 支持heap存储行存表加密。 +- 不支持列存加密,不支持物化视图加密,不支持ustore存储引擎加密。 +- 不支持索引和Sequence加密,不支持XLOG日志加密,不支持MOT内存表加密,不支持系统表加密。 +- 用户在创建表时可以指定加密算法,加密算法一旦指定不可更改。如果创建表时设置enable\_tde为on,但是不指定加密算法encrypt\_algo,则默认使用AES\_128\_CTR加密算法。 +- 如果在创建表时未开启加密功能或指定加密算法,后续无法再切换为加密表。 +- 对于已分配加密密钥的表,切换表的加密和非加密状态,不会更换密钥和加密算法。 +- 数据密钥轮转只有开启表加密功能时才支持轮转。 +- 不支持单集群跨region的多副本主备同步,不支持单集群跨region的扩容,不支持跨region的备份恢复、集群容灾和数据迁移场景。 +- 混合云场景如果使用华为云KMS和管控面功能,则可以支持透明数据加密,其他KMS服务如果接口不兼容则无法支持。 +- 加密表的查询性能比不加密时会有所劣化,对于性能有较高要求的情况下需谨慎开启加密功能。 +- 该特性在金融版本下不支持 + +## 依赖关系 + +依赖外部KMS提供密钥管理服务,目前支持对接华为云KMS服务。 + diff --git a/content/zh/docs/BriefTutorial/DCF.md b/content/zh/docs/BriefTutorial/DCF.md index 573af7c263eb3e39ac0a8efb770e1fbcc739b8a5..bd64b08bbd21ca37b8837eae5749949ef193e907 100644 --- a/content/zh/docs/BriefTutorial/DCF.md +++ b/content/zh/docs/BriefTutorial/DCF.md @@ -1,207 +1,209 @@ -# DCF - -DCF全称是Distributed Consensus Framework,即分布式一致性共识框架。DCF实现了Paxos、Raft等解决分布式一致性问题典型算法。使用DCF可以提供日志复制、集群高可用等能力。DCF提供了自选主能力,支持少数派强起能力,日志复制支持动态流量调整。同时也提供了基于Paxos多种角色节点类型,并能进行调整。 - -DCF是一款高性能、高度成熟可靠、易扩展、易使用的独立基础库,其他系统通过接口与DCF简单对接,就能够轻松拥有Paxos算法赋予的强一致、高可用、自动容灾等能力。 - -## 架构介绍 - -DCF功能架构如[图1](#fig31591049102410)所示,主要包括:功能模块、存储模块、通信模块、服务层等。 - -**图 1** DCF功能架构图 -![](figures/Diagram-Of-The-DCF-Functional-Architecture.png "DCF功能架构图") - -- **算法模块:** - - 算法模块是基于multi-paxos协议实现,同时结合自身业务场景、及高性能和生态的需求,DCF做了很多功能扩展和性能优化,使其相对于基础的multi-paxos,功能变的更加丰富,在多种部署场景下性能都有明显的提升。其主要包括:Leader选举模块,日志复制模块,元数据模块,以及集群管理模块等。 - -- **存储模块:** - - 出于特定业务场景和极致高性能考虑,DCF将日志存储单独抽取出一套公共接口,并实现了一个默认的高性能存储模块。有特定场景或极致高性能及成本需求的用户,可以结合已有的存储系统,对接DCF的日志存储接口来实现其特定需求,这也是DCF作为第三方独立库的优势之一。 - -- **通信模块:** - - 通信模块主要是基于MEC实现(Message Exchange Component),提供整个DCF组件实例间通信能力,以及异步事件处理框架。主要功能有:可扩展的多种通信协议,单播、广播、环回的发送接口,消息异步处理的框架,支持多channel机制和多优先级队列,支持压缩和批量发送等。 - -- **服务层:** - - 服务层是驱动整个DCF运行的基础,提供程序运行所需要的各种基础服务。例如:锁、任务异步调度、线程池服务、定时器能力等。 - - -## 功能介绍 - -- **支持在线添加、删除节点,在线转让Leader能力** - - DCF在标准的multi-paxos基础上,支持在线添加、删除节点,支持在线将leader能力转让给其他节点。这更适合广泛业务场景,构建开发的生态。 - -- **支持优先级选主和策略化多数派** - - **策略化多数派:** 经典Paxos 理论中,多数派达成一致后数据就可以提交,而多数派是非特定的,并不能保证某个或某些节点一定能得到完整的数据。在实际应用中,往往是地理位置较近的节点会拥有强一致的数据,而地理位置较远的节点,一直处于非强一致的状态,在发生城市级容灾的时候无法激活为主节点,形同虚设。策略化多数派能力,可以让用户通过动态配置,指定某个或某些节点必须保有强一致的数据,在出现容灾需求的时,可以立即激活为主节点。 - - **优先级选主:** 用户可以指定各个节点的优先级。DCF严格按照指定的优先级选主,只有在优先级高的节点全部不可用时,才会激活优先级低的节点。 - -- **支持节点角色多样性** - - DCF除了可以提供经典的Leader、Follow、Candidate角色外,还可以提供定制化的角色。例如Passive角色(有日志,有数据,没有被选举权,不参与多数派投票),log角色(有日志,没有数据,没有被选举权,参与多数派投票)。有了这些节点角色的支持,DCF可以支持节点同步、同异步混合部署等多集群部署方式。 - -- **Batch & Pipeline** - - **Batch:** DCF支持多级batch操作,主要包括: - - - 将多个日志合并成单个消息进行发送。 - - 将多个日志合并写磁盘。 - - 将多个日志合并复制。 - - Batch可以有效的降低消息粒度带来的额外损耗,提升吞吐。 - - - **Pipeline:** 是指在上一个消息返回结果以前,并发的发送下一个消息到对应节点的机制,通过提高并发发送消息数量(Pipeline数量),可以有效的降低并发单请求延迟,提升性能;DCF在日志持久化、网络发送、日志复制等多个阶段采用纯异步方式,将Pipeline性能发挥至极致。 - -- **高效流控算法** - - Batching、Pipelining虽然能够提升系统整体吞吐量和性能,但是过大Batch也容易造成单请求时延过大,导致并发请求数过高,继而影响吞吐和请求时延,为此DCF设计实现了一套高效自适应的流控算法,自动探测网络带宽、网络发送时延、请求并发量等参数,并适时调整Batch和Pipeline参数,控制业务流量的注入。 - - 流控算法主要流程如[图2](#fig548518330404)所示: - - **图 2** 流控算法流程 - ![](figures/zh-011.PNG "流控算法流程") - - 核心算法流程如下: - - 1. DCF主节点周期性采样和计算共识信息:这里的共识信息主要是端到端达成共识的时延、端到端达成共识的日志带宽、系统整体日志回放带宽。 - 2. 计算控制量:主节点根据本次采样结果和历史结果,得出性能变化趋势,根据历史控制量的值和变化趋势调整本次控制方向和控制步长,朝更优性能方向计算得出新的控制量。 - 3. 控制周期到达后,更新控制量。 - 4. 控制量持续作用到业务流量,控制业务流量注入的频率。 - - -## 使用示例 - -假设集群三个节点,ip分别为,192.168.0.11,192.168.0.12,192.168.0.13。node id分别为1,2,3;节点角色分别为LEADER,FOLLOWER,FOLLOWER。 - -使用DCF组件能力需要在使用OM安装部署阶段,在配置文件中,开启开关enable\_dcf的值为on(默认是关闭的),并配置DCF config配置信息。 - -在script/gspylib/etc/conf/centralized/cluster\_config\_template\_HA.xml获取XML文件模板。 - -每行信息均有注释进行说明。加粗字体内容为DCF相关内容。示例如下: - -``` - - - - - - - - - - - - - - - - - - - - - - - - - -... -``` - -1. 安装完成后查询集群状态。 - - 使用gs\_ctl查询集群状态。 - - ``` - # gs_ctl query –D - # gs_ctl query -D /nvme0/gaussdb/cluster/nvme0/dn1 - HA state: - local role : Primary - static connections : 2 - db state : Normal - detail information : Normal - Paxos replication info: - paxos write location : 964/87134528 - paxos commit location : 964/87134528 - local write location : 964/87134528 - local flush location : 964/87134528 - local replay location : 964/87134528 - dcf replication info : {"stream_id":1,"local_node_id":1,"role":"LEADER","term":3,"run_mode":0,"work_mode":0,"hb_interval":1000,"elc_timeout":3000,"applied_index":14300633605."commit_index":14300633605,"first_index":14300625186,"last_index":14300633605,"cluster_min_apply_idx'14300633605,"leader_id":1,"leader_ip":"172.16.137.38","leader_port":17783,"nodes":[{"node_id":1,"id":"172.16.137.38","port":17783,"role":"LEADER","next_index":14300633606,"match_index":14300633605,"apply_index":14300633605},{"node_id":2,"ip":"172.16.137.40","port":17783,"role":"FOLLOWER","next_index":14300633606,"match_index":14300633605,"apply_index":14300633605},{"node_id":3,"ip":"172.16.137.42","port":17783,"role":"FOLLOWER","next_index":14300633606,"match_index":14300633605,"apply_index":14300633605}}} - ``` - - 其中: - - - dcf\_replication\_info:表示当前节点dcf信息。 - - role:表示当前节点角色,角色一共有如下几种,LEADER、FOLLOWER、LOGGER、PASSIVE、PRE\_CANDICATE、CANDIDATE、UNKNOW。从上图可以看出当前节点是LEADER节点。 - - term:选举任期。 - - run\_mode:DCF运行模式,当前0表示自动选举模式,2表示关闭自动选举模式。 - - work\_mode:DCF工作模式。0表示多数派模式;1表示少数派模式。 - - hb\_interval:DCF节点间心跳间隔时间,单位ms。 - - elc\_timeout:DCF选举超时时间,单位ms。 - - applied\_index:被应用到状态机的日志位置。 - - commit\_index:已被大多数DCF节点保存的日志位置,此commit\_index之前日志均已持久化。 - - first\_index:DCF节点保存的首条日志位置,此位置会随着DN调用dcf\_truncate而向后推进,之前的日志会被清理。 - - last\_index:DCF节点保存的最后一条日志位置,此日志位置包含DCF节点存储在内存里但是没有持久化的日志,故而last\_index \>= commit\_index。 - - cluster\_min\_apply\_idx:集群最小已应用的日志位置。 - - leader\_id:leader节点ID。 - - leader\_ip:leader节点IP。 - - leader\_port:leader节点端口,DCF内部使用 。 - - nodes:集群其他节点信息。 - -2. 集群规模在线调整。 - - 若在线增加副本,执行以下一条命令即可。 - - ``` - # gs_ctl member --operation=add --nodeid= --ip= --port= -D - ``` - - 若需在线降副本,执行下面命令: - - ``` - # gs_ctl member --operation=remove --nodeid= -D - ``` - - 在集群状态正常的情况下,5分钟就可以完成删除单个副本的任务。 - -3. 集群支持少数派强起功能。 - - 在多数派故障场景下,按正常的Paxos协议无法达成一致,系统无法继续提供服务。为了提供紧急服务能力,需在少数派情况下紧急启动提供服务。 - - 使用命令如下: - - ``` - # cm_ctl setrunmode -n -D --xmode=minority --votenum= - ``` - - 在集群3副本的情况下,2副本故障,只需1副本达成一致即可提交。 - - 加回命令为: - - ``` - # cm_ctl setrunmode -n -D --xmode=normal --votenum= - ``` - -4. 主动switchover操作。 - - 支持一主多备部署模式下切换数据库主备实例,实现AZ间的相互切换。switchover为维护操作,需确保数据库实例状态正常,所有业务结束并无主备追赶后,再进行switchover操作。 - - 例如节点备升主操作命令: - - ``` - # cm_ctl switchover –n -D - ``` - -5. 备机重建功能。 - - 支持主备模式下全量build能力。实现过程是当主DN收到全量build的请求后,阻塞主DN回收DCF日志,备DN从主DN复制xlog日志和数据文件,在备DN拉起后设置DCF开始复制日志点。 - - 命令示例如下: - - ``` - gs_ctl build -b full -D - ``` - - - +# DCF + +DCF全称是Distributed Consensus Framework,即分布式一致性共识框架。DCF实现了Paxos、Raft等解决分布式一致性问题典型算法。使用DCF可以提供日志复制、集群高可用等能力。DCF提供了自选主能力,支持少数派强起能力,日志复制支持动态流量调整。同时也提供了基于Paxos多种角色节点类型,并能进行调整。 + +DCF是一款高性能、高度成熟可靠、易扩展、易使用的独立基础库,其他系统通过接口与DCF简单对接,就能够轻松拥有Paxos算法赋予的强一致、高可用、自动容灾等能力。 + +## 架构介绍 + +DCF功能架构如[图1](#fig31591049102410)所示,主要包括:功能模块、存储模块、通信模块、服务层等。 + +**图 1** DCF功能架构图 +![](figures/Diagram-Of-The-DCF-Functional-Architecture.png "DCF功能架构图") + +- **算法模块:** + + 算法模块是基于multi-paxos协议实现,同时结合自身业务场景、及高性能和生态的需求,DCF做了很多功能扩展和性能优化,使其相对于基础的multi-paxos,功能变的更加丰富,在多种部署场景下性能都有明显的提升。其主要包括:Leader选举模块,日志复制模块,元数据模块,以及集群管理模块等。 + +- **存储模块:** + + 出于特定业务场景和极致高性能考虑,DCF将日志存储单独抽取出一套公共接口,并实现了一个默认的高性能存储模块。有特定场景或极致高性能及成本需求的用户,可以结合已有的存储系统,对接DCF的日志存储接口来实现其特定需求,这也是DCF作为第三方独立库的优势之一。 + +- **通信模块:** + + 通信模块主要是基于MEC实现(Message Exchange Component),提供整个DCF组件实例间通信能力,以及异步事件处理框架。主要功能有:可扩展的多种通信协议,单播、广播、环回的发送接口,消息异步处理的框架,支持多channel机制和多优先级队列,支持压缩和批量发送等。 + +- **服务层:** + + 服务层是驱动整个DCF运行的基础,提供程序运行所需要的各种基础服务。例如:锁、任务异步调度、线程池服务、定时器能力等。 + + +## 功能介绍 + +- **支持在线添加、删除节点,在线转让Leader能力** + + DCF在标准的multi-paxos基础上,支持在线添加、删除节点,支持在线将leader能力转让给其他节点。这更适合广泛业务场景,构建开发的生态。 + +- **支持优先级选主和策略化多数派** + - **策略化多数派:** 经典Paxos 理论中,多数派达成一致后数据就可以提交,而多数派是非特定的,并不能保证某个或某些节点一定能得到完整的数据。在实际应用中,往往是地理位置较近的节点会拥有强一致的数据,而地理位置较远的节点,一直处于非强一致的状态,在发生城市级容灾的时候无法激活为主节点,形同虚设。策略化多数派能力,可以让用户通过动态配置,指定某个或某些节点必须保有强一致的数据,在出现容灾需求的时,可以立即激活为主节点。 + - **优先级选主:** 用户可以指定各个节点的优先级。DCF严格按照指定的优先级选主,只有在优先级高的节点全部不可用时,才会激活优先级低的节点。 + +- **支持节点角色多样性** + + DCF除了可以提供经典的Leader、Follow、Candidate角色外,还可以提供定制化的角色。例如Passive角色(有日志,有数据,没有被选举权,不参与多数派投票),log角色(有日志,没有数据,没有被选举权,参与多数派投票)。有了这些节点角色的支持,DCF可以支持节点同步、同异步混合部署等多集群部署方式。 + +- **Batch & Pipeline** + - **Batch:** DCF支持多级batch操作,主要包括: + + - 将多个日志合并成单个消息进行发送。 + - 将多个日志合并写磁盘。 + - 将多个日志合并复制。 + + Batch可以有效的降低消息粒度带来的额外损耗,提升吞吐。 + + - **Pipeline:** 是指在上一个消息返回结果以前,并发的发送下一个消息到对应节点的机制,通过提高并发发送消息数量(Pipeline数量),可以有效的降低并发单请求延迟,提升性能;DCF在日志持久化、网络发送、日志复制等多个阶段采用纯异步方式,将Pipeline性能发挥至极致。 + +- **高效流控算法** + + Batching、Pipelining虽然能够提升系统整体吞吐量和性能,但是过大Batch也容易造成单请求时延过大,导致并发请求数过高,继而影响吞吐和请求时延,为此DCF设计实现了一套高效自适应的流控算法,自动探测网络带宽、网络发送时延、请求并发量等参数,并适时调整Batch和Pipeline参数,控制业务流量的注入。 + + 流控算法主要流程如[图2](#fig548518330404)所示: + + **图 2** 流控算法流程 + ![](figures/zh-011.PNG "流控算法流程") + + 核心算法流程如下: + + 1. DCF主节点周期性采样和计算共识信息:这里的共识信息主要是端到端达成共识的时延、端到端达成共识的日志带宽、系统整体日志回放带宽。 + 2. 计算控制量:主节点根据本次采样结果和历史结果,得出性能变化趋势,根据历史控制量的值和变化趋势调整本次控制方向和控制步长,朝更优性能方向计算得出新的控制量。 + 3. 控制周期到达后,更新控制量。 + 4. 控制量持续作用到业务流量,控制业务流量注入的频率。 + +- **该特性在金融版本下不支持** + + +## 使用示例 + +假设集群三个节点,ip分别为,192.168.0.11,192.168.0.12,192.168.0.13。node id分别为1,2,3;节点角色分别为LEADER,FOLLOWER,FOLLOWER。 + +使用DCF组件能力需要在使用OM安装部署阶段,在配置文件中,开启开关enable\_dcf的值为on(默认是关闭的),并配置DCF config配置信息。 + +在script/gspylib/etc/conf/centralized/cluster\_config\_template\_HA.xml获取XML文件模板。 + +每行信息均有注释进行说明。加粗字体内容为DCF相关内容。示例如下: + +``` + + + + + + + + + + + + + + + + + + + + + + + + + +... +``` + +1. 安装完成后查询集群状态。 + + 使用gs\_ctl查询集群状态。 + + ``` + # gs_ctl query –D + # gs_ctl query -D /nvme0/gaussdb/cluster/nvme0/dn1 + HA state: + local role : Primary + static connections : 2 + db state : Normal + detail information : Normal + Paxos replication info: + paxos write location : 964/87134528 + paxos commit location : 964/87134528 + local write location : 964/87134528 + local flush location : 964/87134528 + local replay location : 964/87134528 + dcf replication info : {"stream_id":1,"local_node_id":1,"role":"LEADER","term":3,"run_mode":0,"work_mode":0,"hb_interval":1000,"elc_timeout":3000,"applied_index":14300633605."commit_index":14300633605,"first_index":14300625186,"last_index":14300633605,"cluster_min_apply_idx'14300633605,"leader_id":1,"leader_ip":"172.16.137.38","leader_port":17783,"nodes":[{"node_id":1,"id":"172.16.137.38","port":17783,"role":"LEADER","next_index":14300633606,"match_index":14300633605,"apply_index":14300633605},{"node_id":2,"ip":"172.16.137.40","port":17783,"role":"FOLLOWER","next_index":14300633606,"match_index":14300633605,"apply_index":14300633605},{"node_id":3,"ip":"172.16.137.42","port":17783,"role":"FOLLOWER","next_index":14300633606,"match_index":14300633605,"apply_index":14300633605}}} + ``` + + 其中: + + - dcf\_replication\_info:表示当前节点dcf信息。 + - role:表示当前节点角色,角色一共有如下几种,LEADER、FOLLOWER、LOGGER、PASSIVE、PRE\_CANDICATE、CANDIDATE、UNKNOW。从上图可以看出当前节点是LEADER节点。 + - term:选举任期。 + - run\_mode:DCF运行模式,当前0表示自动选举模式,2表示关闭自动选举模式。 + - work\_mode:DCF工作模式。0表示多数派模式;1表示少数派模式。 + - hb\_interval:DCF节点间心跳间隔时间,单位ms。 + - elc\_timeout:DCF选举超时时间,单位ms。 + - applied\_index:被应用到状态机的日志位置。 + - commit\_index:已被大多数DCF节点保存的日志位置,此commit\_index之前日志均已持久化。 + - first\_index:DCF节点保存的首条日志位置,此位置会随着DN调用dcf\_truncate而向后推进,之前的日志会被清理。 + - last\_index:DCF节点保存的最后一条日志位置,此日志位置包含DCF节点存储在内存里但是没有持久化的日志,故而last\_index \>= commit\_index。 + - cluster\_min\_apply\_idx:集群最小已应用的日志位置。 + - leader\_id:leader节点ID。 + - leader\_ip:leader节点IP。 + - leader\_port:leader节点端口,DCF内部使用 。 + - nodes:集群其他节点信息。 + +2. 集群规模在线调整。 + + 若在线增加副本,执行以下一条命令即可。 + + ``` + # gs_ctl member --operation=add --nodeid= --ip= --port= -D + ``` + + 若需在线降副本,执行下面命令: + + ``` + # gs_ctl member --operation=remove --nodeid= -D + ``` + + 在集群状态正常的情况下,5分钟就可以完成删除单个副本的任务。 + +3. 集群支持少数派强起功能。 + + 在多数派故障场景下,按正常的Paxos协议无法达成一致,系统无法继续提供服务。为了提供紧急服务能力,需在少数派情况下紧急启动提供服务。 + + 使用命令如下: + + ``` + # cm_ctl setrunmode -n -D --xmode=minority --votenum= + ``` + + 在集群3副本的情况下,2副本故障,只需1副本达成一致即可提交。 + + 加回命令为: + + ``` + # cm_ctl setrunmode -n -D --xmode=normal --votenum= + ``` + +4. 主动switchover操作。 + + 支持一主多备部署模式下切换数据库主备实例,实现AZ间的相互切换。switchover为维护操作,需确保数据库实例状态正常,所有业务结束并无主备追赶后,再进行switchover操作。 + + 例如节点备升主操作命令: + + ``` + # cm_ctl switchover –n -D + ``` + +5. 备机重建功能。 + + 支持主备模式下全量build能力。实现过程是当主DN收到全量build的请求后,阻塞主DN回收DCF日志,备DN从主DN复制xlog日志和数据文件,在备DN拉起后设置DCF开始复制日志点。 + + 命令示例如下: + + ``` + gs_ctl build -b full -D + ``` + + + diff --git a/content/zh/docs/BriefTutorial/MOT.md b/content/zh/docs/BriefTutorial/MOT.md index 8359cf047cf3d777a2e568aac33033eeeed2226d..eece3104eb727e8120e798024aba98c4864e2ecc 100644 --- a/content/zh/docs/BriefTutorial/MOT.md +++ b/content/zh/docs/BriefTutorial/MOT.md @@ -1,272 +1,274 @@ -# MOT - -openGauss引入了MOT(Memory-Optimized Table,MOT)存储引擎,它是一种事务性行存储,针对多核和大内存服务器进行了优化。MOT是openGauss数据库最先进的生产级特性(Beta版本),它为事务性工作负载提供更高的性能。MOT完全支持ACID特性,并包括严格的持久性和高可用性支持。企业可以在关键任务、性能敏感的在线事务处理(OLTP)中使用MOT,以实现高性能、高吞吐、可预测低延迟以及多核服务器的高利用率。MOT尤其适合在多路和多核处理器的现代服务器上运行,例如基于Arm/鲲鹏处理器的华为TaiShan服务器,以及基于x86的戴尔或类似服务器。 - -## MOT特性及价值 - -MOT在高性能(查询和事务延迟)、高可扩展性(吞吐量和并发量)甚至在某些情况下成本(高资源利用率)这些方面拥有显著优势。 - -- 低延迟(Low Latency):提供快速的查询和事务响应时间。 -- 高吞吐量(High Throughput):支持峰值和持续高用户并发。 -- 高资源利用率(High Resource Utilization):充分利用硬件。 - -使用了MOT的应用程序可以达到2.5到4倍的吞吐量。例如,在基于Arm/鲲鹏的华为TaiShan服务器和基于英特尔至强的戴尔x86服务器上,执行TPC-C基准测试(交互事务和同步日志)。MOT提供的吞吐率增益在2路服务器上达到2.5倍,4路服务器上达到3.7倍,在4路256核Arm服务器上达到480万tpmC。 - -在TPC-C基准测试中可观察到,MOT提供更低的延迟将事务速度降低3至5.5倍。 - -此外,高负载和高争用的情况是所有领先的行业数据库都会遇到的公认问题,而MOT能够在这种情况下极高地利用服务器资源。使用MOT后,4路服务器的资源利用率达到99%,远远领先其他行业数据库。 - -这种能力在现代的多核服务器上尤为明显和重要。 - -## MOT关键技术 - -MOT的关键技术如下: - -- 内存优化数据结构:以实现高并发吞吐量和可预测的低延迟为目标,所有数据和索引都在内存中,不使用中间页缓冲区,并使用持续时间最短的锁。数据结构和所有算法都是专门为内存设计而优化的。 -- 免锁事务管理:MOT在保证严格一致性和数据完整性的前提下,采用乐观的策略实现高并发和高吞吐。在事务过程中,MOT不会对正在更新的数据行的任何版本加锁,从而大大降低了一些大内存系统中的争用。事务中的乐观并发控制(Optimistic Concurrency Control,OCC)语句是在没有锁的情况下实现的,所有的数据修改都是在内存中专门用于私有事务的部分(也称为私有事务内存)中进行的。这就意味着在事务过程中,相关数据在私有事务内存中更新,从而实现了无锁读写;而且只有在提交阶段才会短时间加锁。 -- 免锁索引:由于内存表的数据和索引完全存储在内存中,因此拥有一个高效的索引数据结构和算法非常重要。MOT索引机制基于最先进的Masstree,这是一种用于多核系统的快速和可扩展的键值(Key Value,KV)存储索引,以B+树的Trie实现。通过这种方式,高并发工作负载在多核服务器上可以获得卓越的性能。同时MOT应用了各种先进的技术以优化性能,如优化锁方法、高速缓存感知和内存预取。 -- NUMA-aware的内存管理:MOT内存访问的设计支持非统一内存访问(NUMA)感知。NUMA-aware算法增强了内存中数据布局的性能,使线程访问物理上连接到线程运行的核心的内存。这是由内存控制器处理的,不需要通过使用互连(如英特尔QPI)进行额外的跳转。MOT的智能内存控制模块,为各种内存对象预先分配了内存池,提高了性能,减少了锁,保证了稳定性。事务的内存对象的分配始终是NUMA本地的。本地处理的对象会返回到池中。同时在事务中尽量减少系统内存分配(OS malloc)的使用,避免不必要的锁。 -- 高效持久性:日志和检查点是实现磁盘持久化的关键能力,也是ACID的关键要求之一(D代表持久性)。目前所有的磁盘(包括SSD和NVMe)都明显慢于内存,因此持久化是基于内存数据库引擎的瓶颈。作为一个基于内存的存储引擎,MOT的持久化设计必须实现各种各样的算法优化,以确保持久化的同时还能达到设计时的速度和吞吐量目标。这些优化包括: - - 并行日志,所有openGauss磁盘表都支持。 - - 每个事务的日志缓冲和无锁事务准备。 - - 增量更新记录,即只记录变化。 - - 除了同步和异步之外,创新的NUMA感知组提交日志记录。 - - 最先进的数据库检查点(CALC,Checkpointing Asynchronously using Logical Consistency)使内存和计算开销降到最低。 - -- 高SQL覆盖率和功能集:MOT通过扩展的PostgreSQL外部数据封装(FDW)以及索引,几乎支持完整的SQL范围,包括存储过程、用户定义函数和系统函数调用。 -- 使用PREPARE语句的查询原生编译:通过使用PREPARE客户端命令,可以以交互方式执行查询和事务语句。这些命令已被预编译成原生执行格式,也称为Code-Gen或即时(Just-in-Time,JIT)编译。这样可以实现平均30%的性能提升。在可能的情况下,应用编译和轻量级执行;否则,使用标准执行路径处理适用的查询。Cache Plan模块已针对OLTP进行了优化,在整个会话中甚至使用不同的绑定设置以及在不同的会话中重用编译结果。 -- MOT和openGauss数据库的无缝集成:MOT是一个高性能的面向内存优化的存储引擎,已集成在openGauss包中。MOT的主内存引擎和基于磁盘的存储引擎并存,以支持多种应用场景,同时在内部重用数据库辅助服务,如WAL重做日志、复制、检查点和恢复高可用性等。用户可以从基于磁盘的表和MOT的统一部署、配置和访问中受益。根据特定需求,灵活且低成本地选择使用哪种存储引擎。例如,把会导致瓶颈的高度性能敏感数据放入内存中。 - -## MOT应用场景 - -MOT可以根据负载的特点,显著加快应用程序的整体性能。MOT通过提高数据访问和事务执行的效率,并通过消除并发执行事务之间的锁和锁存争用,最大程度地减少重定向,从而提高了事务处理的性能。 - -MOT的极速不仅因为它在内存中,还因为它围绕并发内存使用管理进行了优化。数据存储、访问和处理算法从头开始设计,以利用内存和高并发计算的最新先进技术。 - -openGauss允许应用程序随意组合MOT和基于标准磁盘的表。对于启用已证明是瓶颈的最活跃、高争用和对性能敏感的应用程序表,以及需要可预测的低延迟访问和高吞吐量的表来说,MOT特别有用。 - -MOT可用于各种应用,例如: - -- 高吞吐事务处理:这是使用MOT的主要场景,因为它支持海量事务,同时要求单个事务的延迟较低。这类应用的例子有实时决策系统、支付系统、金融工具交易、体育博彩、移动游戏、广告投放等。 -- 性能瓶颈加速:存在高争用现象的表可以通过使用MOT受益,即使该表是磁盘表。由于延迟更低、竞争和锁更少以及服务器吞吐量能力增加,此类表(除了相关表和在查询和事务中一起引用的表之外)的转换使得性能显著提升。 -- 消除中间层缓存:云计算和移动应用往往会有周期性或峰值的高工作负载。此外,许多应用都有80%以上负载是读负载,并伴有频繁的重复查询。为了满足峰值负载单独要求,以及降低响应延迟提供最佳的用户体验,应用程序通常会部署中间缓存层。这样的附加层增加了开发的复杂性和时间,也增加了运营成本。 MOT提供了一个很好的替代方案,通过一致的高性能数据存储来简化应用架构,缩短开发周期,降低CAPEX和OPEX成本。 -- 大规模流数据提取:MOT可以满足云端(针对移动、M2M和物联网)、事务处理(Transactional Processing,TP)、分析处理(Analytical Processing,AP)和机器学习(Machine Learning,ML)的大规模流数据的提取要求。MOT尤其擅长持续快速地同时提取来自许多不同来源的大量数据。这些数据可以在以后进行处理、转换,并在速度较慢的基于磁盘的表中进行移动。另外,MOT还可以查询到一致的、最新的数据,从而得出实时结果。在有许多实时数据流的物联网和云计算应用中,通常会有专门的数据摄取和处理。例如,一个Apache Kafka集群可以用来提取10万个事件/秒的数据,延迟为10ms。一个周期性的批处理任务会将收集到的数据收集起来,并将转换格式,放入关系型数据库中进行进一步分析。MOT可以通过将数据流直接存储在MOT关系表中,为分析和决策做好准备,从而支持这样的场景(同时消除单独的数据处理层)。这样可以更快地收集和处理数据,MOT避免了代价高昂的分层和缓慢的批处理,提高了一致性,增加了分析数据的实时性,同时降低了总拥有成本(Total Cost of Ownership,TCO)。 -- 降低TCO:提高资源利用率和消除中间层可以节省30%到90%的TCO。 - -## 不支持的数据类型 - -- UUID -- User-Defined Type \(UDF\) -- Array data type -- NVARCHAR2\(n\) -- Clob -- Name -- Blob -- Raw -- Path -- Circle -- Reltime -- Bit varying\(10\) -- Tsvector -- Tsquery -- JSON -- Box -- Text -- Line -- Point -- LSEG -- POLYGON -- INET -- CIDR -- MACADDR -- Smalldatetime -- BYTEA -- Bit -- Varbit -- OID -- Money -- 无限制的varchar/character varying -- HSTORE - -## 使用MOT - -1. 授予用户权限 - - 以授予数据库用户对MOT存储引擎的访问权限为例。每个数据库用户仅执行一次,通常在初始配置阶段完成。 - - >![](public_sys-resources/icon-note.png) **说明:** - >MOT通过外部数据封装器(Foreign Data Wrapper,FDW)机制与openGauss数据库集成,所以需要授权用户权限。 - - 要使特定用户能够创建和访问MOT(DDL、DML、SELECT),以下语句只执行一次: - - ``` - GRANT USAGE ON FOREIGN SERVER mot_server TO ; - ``` - - 所有关键字不区分大小写。 - -2. 创建/删除MOT - - 只有MOT中的创建和删除表语句与openGauss中基于磁盘的表的语句不同。SELECT、DML和DDL的所有其他命令的语法对于MOT表和openGauss基于磁盘的表是一样的。 - - - 创建MOT: - - ``` - create FOREIGN table test(x int) [server mot_server]; - ``` - - - 以上语句中: - - 始终使用FOREIGN关键字引用MOT。 - - 在创建MOT表时,\[server mot\_server\]部分是可选的,因为MOT是一个集成的引擎,而不是一个独立的服务器。 - - 上文以创建一个名为test的内存表(表中有一个名为x的整数列)为例。在下一节(创建索引)中将提供一个更现实的例子。 - - 如果postgresql.conf中开启了增量检查点,则无法创建MOT。因此请在创建MOT前将enable\_incremental\_checkpoint设置为off。 - - - 删除名为test的MOT: - - ``` - drop FOREIGN table test; - ``` - -3. 为MOT创建索引 - - 支持标准的openGauss创建和删除索引语句。 - - 例如: - - ``` - create index text_index1 on test(x) ; - ``` - - 创建一个用于TPC-C的ORDER表,并创建索引: - - ``` - create FOREIGN table bmsql_oorder ( - o_w_id integer not null, - o_d_id integer not null, - o_id integer not null, - o_c_id integer not null, - o_carrier_id integer, - o_ol_cnt integer, - o_all_local integer, - o_entry_d timestamp, - primary key (o_w_id, o_d_id, o_id) - ); - create index bmsql_oorder_index1 on bmsql_oorder(o_w_id, o_d_id, o_c_id, o_id) ; - ``` - - >![](public_sys-resources/icon-note.png) **说明:** - >在MOT名字之前不需要指定FOREIGN关键字,因为它仅用于创建和删除表的命令。 - - -## 将磁盘表转换为MOT - -磁盘表直接转换为MOT尚不能实现,这意味着尚不存在将基于磁盘的表转换为MOT的ALTER TABLE语句。 - -下面介绍如何手动将基于磁盘的表转换为MOT,如何使用gs\_dump工具导出数据,以及如何使用gs\_restore工具导入数据。 - -- 前置条件检查 - - 检查待转换为MOT的磁盘表是否包含所有需要的列。 - - 检查表中是否包含任何不支持的列数据类型,具体参见“不支持的数据类型”。 - - 如果不支持特定列数据类型,则建议首先创建一个更新了列数据类型的磁盘表。此表内容与原始表相同,只是所有不支持的数据类型都已转换为支持的数据类型。 - - 使用以下脚本导出该备磁盘表,然后导入到MOT中。 - -- 转换 - - 要将基于磁盘的表转换为MOT,请执行以下步骤: - - 1. 暂停应用程序活动。 - 2. 使用gs\_dump工具将表数据转储到磁盘的物理文件中。请确保使用data only。 - 3. 重命名原始基于磁盘的表。 - 4. 创建同名同模式的MOT。请确保使用创建FOREIGN关键字指定该表为MOT。 - 5. 使用gs\_restore将磁盘文件的数据加载/恢复到数据库表中。 - 6. 浏览或手动验证所有原始数据是否正确导入到新的MOT中。下面将举例说明。 - 7. 恢复应用程序活动。 - - >![](public_sys-resources/icon-notice.png) **须知:** - >由于表名称保持不变,应用程序查询和相关数据库存储过程将能够无缝访问新的MOT,而无需更改代码。请注意,MOT目前不支持跨引擎多表查询(如使用Join、Union和子查询)和跨引擎多表事务。因此,如果在多表查询、存储过程或事务中访问原始表,则必须将所有相关的磁盘表转换为MOT,或者更改应用程序或数据库中的相关代码。 - -- 转换示例 - - 假设要将数据库benchmarksql中一个基于磁盘的表customer迁移到MOT中。 - - 将customer表迁移到MOT,操作步骤如下: - - 1. 检查源表列类型。验证MOT支持所有类型,详情请参阅“不支持的数据类型”章节。 - - ``` - benchmarksql-# \d+ customer - Table "public.customer" - Column | Type | Modifiers | Storage | Stats target | Description - --------+---------+-----------+---------+--------------+------------- - x | integer | | plain | | - y | integer | | plain | | - Has OIDs: no - Options: orientation=row, compression=no - ``` - - 2. 请检查源表数据。 - - ``` - benchmarksql=# select * from customer; - x | y - ---+--- - 1 | 2 - 3 | 4 - (2 rows) - ``` - - 3. 只能使用gs\_dump转储表数据。 - - ``` - $ gs_dump -Fc benchmarksql -a --table customer -f customer.dump -p 16000 - gs_dump[port='15500'][benchmarksql][2020-06-04 16:45:38]: dump database benchmarksql successfully - gs_dump[port='15500'][benchmarksql][2020-06-04 16:45:38]: total time: 332 ms - ``` - - 4. 重命名源表。 - - ``` - benchmarksql=# alter table customer rename to customer_bk; - ALTER TABLE - ``` - - 5. 创建与源表完全相同的MOT。 - - ``` - benchmarksql=# create foreign table customer (x int, y int); - CREATE FOREIGN TABLE - benchmarksql=# select * from customer; - x | y - ---+--- - (0 rows) - ``` - - 6. 将源转储数据导入到新MOT中。 - - ``` - $ gs_restore -C -d benchmarksql customer.dump -p 16000 - restore operation successful - total time: 24 ms - Check that the data was imported successfully. - benchmarksql=# select * from customer; - x | y - ---+--- - 1 | 2 - 3 | 4 - (2 rows) - - benchmarksql=# \d - List of relations - Schema | Name | Type | Owner | Storage - --------+-------------+---------------+--------+---------------------------------- - public | customer | foreign table | aharon | - public | customer_bk | table | aharon | {orientation=row,compression=no} - (2 rows) - ``` - - - +# MOT + +openGauss引入了MOT(Memory-Optimized Table,MOT)存储引擎,它是一种事务性行存储,针对多核和大内存服务器进行了优化。MOT是openGauss数据库最先进的生产级特性(Beta版本),它为事务性工作负载提供更高的性能。MOT完全支持ACID特性,并包括严格的持久性和高可用性支持。企业可以在关键任务、性能敏感的在线事务处理(OLTP)中使用MOT,以实现高性能、高吞吐、可预测低延迟以及多核服务器的高利用率。MOT尤其适合在多路和多核处理器的现代服务器上运行,例如基于Arm/鲲鹏处理器的华为TaiShan服务器,以及基于x86的戴尔或类似服务器。 + +## MOT特性及价值 + +MOT在高性能(查询和事务延迟)、高可扩展性(吞吐量和并发量)甚至在某些情况下成本(高资源利用率)这些方面拥有显著优势。 + +- 低延迟(Low Latency):提供快速的查询和事务响应时间。 +- 高吞吐量(High Throughput):支持峰值和持续高用户并发。 +- 高资源利用率(High Resource Utilization):充分利用硬件。 + +使用了MOT的应用程序可以达到2.5到4倍的吞吐量。例如,在基于Arm/鲲鹏的华为TaiShan服务器和基于英特尔至强的戴尔x86服务器上,执行TPC-C基准测试(交互事务和同步日志)。MOT提供的吞吐率增益在2路服务器上达到2.5倍,4路服务器上达到3.7倍,在4路256核Arm服务器上达到480万tpmC。 + +在TPC-C基准测试中可观察到,MOT提供更低的延迟将事务速度降低3至5.5倍。 + +此外,高负载和高争用的情况是所有领先的行业数据库都会遇到的公认问题,而MOT能够在这种情况下极高地利用服务器资源。使用MOT后,4路服务器的资源利用率达到99%,远远领先其他行业数据库。 + +这种能力在现代的多核服务器上尤为明显和重要。 + +## MOT关键技术 + +MOT的关键技术如下: + +- 内存优化数据结构:以实现高并发吞吐量和可预测的低延迟为目标,所有数据和索引都在内存中,不使用中间页缓冲区,并使用持续时间最短的锁。数据结构和所有算法都是专门为内存设计而优化的。 +- 免锁事务管理:MOT在保证严格一致性和数据完整性的前提下,采用乐观的策略实现高并发和高吞吐。在事务过程中,MOT不会对正在更新的数据行的任何版本加锁,从而大大降低了一些大内存系统中的争用。事务中的乐观并发控制(Optimistic Concurrency Control,OCC)语句是在没有锁的情况下实现的,所有的数据修改都是在内存中专门用于私有事务的部分(也称为私有事务内存)中进行的。这就意味着在事务过程中,相关数据在私有事务内存中更新,从而实现了无锁读写;而且只有在提交阶段才会短时间加锁。 +- 免锁索引:由于内存表的数据和索引完全存储在内存中,因此拥有一个高效的索引数据结构和算法非常重要。MOT索引机制基于最先进的Masstree,这是一种用于多核系统的快速和可扩展的键值(Key Value,KV)存储索引,以B+树的Trie实现。通过这种方式,高并发工作负载在多核服务器上可以获得卓越的性能。同时MOT应用了各种先进的技术以优化性能,如优化锁方法、高速缓存感知和内存预取。 +- NUMA-aware的内存管理:MOT内存访问的设计支持非统一内存访问(NUMA)感知。NUMA-aware算法增强了内存中数据布局的性能,使线程访问物理上连接到线程运行的核心的内存。这是由内存控制器处理的,不需要通过使用互连(如英特尔QPI)进行额外的跳转。MOT的智能内存控制模块,为各种内存对象预先分配了内存池,提高了性能,减少了锁,保证了稳定性。事务的内存对象的分配始终是NUMA本地的。本地处理的对象会返回到池中。同时在事务中尽量减少系统内存分配(OS malloc)的使用,避免不必要的锁。 +- 高效持久性:日志和检查点是实现磁盘持久化的关键能力,也是ACID的关键要求之一(D代表持久性)。目前所有的磁盘(包括SSD和NVMe)都明显慢于内存,因此持久化是基于内存数据库引擎的瓶颈。作为一个基于内存的存储引擎,MOT的持久化设计必须实现各种各样的算法优化,以确保持久化的同时还能达到设计时的速度和吞吐量目标。这些优化包括: + - 并行日志,所有openGauss磁盘表都支持。 + - 每个事务的日志缓冲和无锁事务准备。 + - 增量更新记录,即只记录变化。 + - 除了同步和异步之外,创新的NUMA感知组提交日志记录。 + - 最先进的数据库检查点(CALC,Checkpointing Asynchronously using Logical Consistency)使内存和计算开销降到最低。 + +- 高SQL覆盖率和功能集:MOT通过扩展的PostgreSQL外部数据封装(FDW)以及索引,几乎支持完整的SQL范围,包括存储过程、用户定义函数和系统函数调用。 +- 使用PREPARE语句的查询原生编译:通过使用PREPARE客户端命令,可以以交互方式执行查询和事务语句。这些命令已被预编译成原生执行格式,也称为Code-Gen或即时(Just-in-Time,JIT)编译。这样可以实现平均30%的性能提升。在可能的情况下,应用编译和轻量级执行;否则,使用标准执行路径处理适用的查询。Cache Plan模块已针对OLTP进行了优化,在整个会话中甚至使用不同的绑定设置以及在不同的会话中重用编译结果。 +- MOT和openGauss数据库的无缝集成:MOT是一个高性能的面向内存优化的存储引擎,已集成在openGauss包中。MOT的主内存引擎和基于磁盘的存储引擎并存,以支持多种应用场景,同时在内部重用数据库辅助服务,如WAL重做日志、复制、检查点和恢复高可用性等。用户可以从基于磁盘的表和MOT的统一部署、配置和访问中受益。根据特定需求,灵活且低成本地选择使用哪种存储引擎。例如,把会导致瓶颈的高度性能敏感数据放入内存中。 + +## MOT应用场景 + +MOT可以根据负载的特点,显著加快应用程序的整体性能。MOT通过提高数据访问和事务执行的效率,并通过消除并发执行事务之间的锁和锁存争用,最大程度地减少重定向,从而提高了事务处理的性能。 + +MOT的极速不仅因为它在内存中,还因为它围绕并发内存使用管理进行了优化。数据存储、访问和处理算法从头开始设计,以利用内存和高并发计算的最新先进技术。 + +openGauss允许应用程序随意组合MOT和基于标准磁盘的表。对于启用已证明是瓶颈的最活跃、高争用和对性能敏感的应用程序表,以及需要可预测的低延迟访问和高吞吐量的表来说,MOT特别有用。 + +MOT可用于各种应用,例如: + +- 高吞吐事务处理:这是使用MOT的主要场景,因为它支持海量事务,同时要求单个事务的延迟较低。这类应用的例子有实时决策系统、支付系统、金融工具交易、体育博彩、移动游戏、广告投放等。 +- 性能瓶颈加速:存在高争用现象的表可以通过使用MOT受益,即使该表是磁盘表。由于延迟更低、竞争和锁更少以及服务器吞吐量能力增加,此类表(除了相关表和在查询和事务中一起引用的表之外)的转换使得性能显著提升。 +- 消除中间层缓存:云计算和移动应用往往会有周期性或峰值的高工作负载。此外,许多应用都有80%以上负载是读负载,并伴有频繁的重复查询。为了满足峰值负载单独要求,以及降低响应延迟提供最佳的用户体验,应用程序通常会部署中间缓存层。这样的附加层增加了开发的复杂性和时间,也增加了运营成本。 MOT提供了一个很好的替代方案,通过一致的高性能数据存储来简化应用架构,缩短开发周期,降低CAPEX和OPEX成本。 +- 大规模流数据提取:MOT可以满足云端(针对移动、M2M和物联网)、事务处理(Transactional Processing,TP)、分析处理(Analytical Processing,AP)和机器学习(Machine Learning,ML)的大规模流数据的提取要求。MOT尤其擅长持续快速地同时提取来自许多不同来源的大量数据。这些数据可以在以后进行处理、转换,并在速度较慢的基于磁盘的表中进行移动。另外,MOT还可以查询到一致的、最新的数据,从而得出实时结果。在有许多实时数据流的物联网和云计算应用中,通常会有专门的数据摄取和处理。例如,一个Apache Kafka集群可以用来提取10万个事件/秒的数据,延迟为10ms。一个周期性的批处理任务会将收集到的数据收集起来,并将转换格式,放入关系型数据库中进行进一步分析。MOT可以通过将数据流直接存储在MOT关系表中,为分析和决策做好准备,从而支持这样的场景(同时消除单独的数据处理层)。这样可以更快地收集和处理数据,MOT避免了代价高昂的分层和缓慢的批处理,提高了一致性,增加了分析数据的实时性,同时降低了总拥有成本(Total Cost of Ownership,TCO)。 +- 降低TCO:提高资源利用率和消除中间层可以节省30%到90%的TCO。 + +- 该特性在金融版本下不支持 + +## 不支持的数据类型 + +- UUID +- User-Defined Type \(UDF\) +- Array data type +- NVARCHAR2\(n\) +- Clob +- Name +- Blob +- Raw +- Path +- Circle +- Reltime +- Bit varying\(10\) +- Tsvector +- Tsquery +- JSON +- Box +- Text +- Line +- Point +- LSEG +- POLYGON +- INET +- CIDR +- MACADDR +- Smalldatetime +- BYTEA +- Bit +- Varbit +- OID +- Money +- 无限制的varchar/character varying +- HSTORE + +## 使用MOT + +1. 授予用户权限 + + 以授予数据库用户对MOT存储引擎的访问权限为例。每个数据库用户仅执行一次,通常在初始配置阶段完成。 + + >![](public_sys-resources/icon-note.png) **说明:** + >MOT通过外部数据封装器(Foreign Data Wrapper,FDW)机制与openGauss数据库集成,所以需要授权用户权限。 + + 要使特定用户能够创建和访问MOT(DDL、DML、SELECT),以下语句只执行一次: + + ``` + GRANT USAGE ON FOREIGN SERVER mot_server TO ; + ``` + + 所有关键字不区分大小写。 + +2. 创建/删除MOT + + 只有MOT中的创建和删除表语句与openGauss中基于磁盘的表的语句不同。SELECT、DML和DDL的所有其他命令的语法对于MOT表和openGauss基于磁盘的表是一样的。 + + - 创建MOT: + + ``` + create FOREIGN table test(x int) [server mot_server]; + ``` + + - 以上语句中: + - 始终使用FOREIGN关键字引用MOT。 + - 在创建MOT表时,\[server mot\_server\]部分是可选的,因为MOT是一个集成的引擎,而不是一个独立的服务器。 + - 上文以创建一个名为test的内存表(表中有一个名为x的整数列)为例。在下一节(创建索引)中将提供一个更现实的例子。 + - 如果postgresql.conf中开启了增量检查点,则无法创建MOT。因此请在创建MOT前将enable\_incremental\_checkpoint设置为off。 + + - 删除名为test的MOT: + + ``` + drop FOREIGN table test; + ``` + +3. 为MOT创建索引 + + 支持标准的openGauss创建和删除索引语句。 + + 例如: + + ``` + create index text_index1 on test(x) ; + ``` + + 创建一个用于TPC-C的ORDER表,并创建索引: + + ``` + create FOREIGN table bmsql_oorder ( + o_w_id integer not null, + o_d_id integer not null, + o_id integer not null, + o_c_id integer not null, + o_carrier_id integer, + o_ol_cnt integer, + o_all_local integer, + o_entry_d timestamp, + primary key (o_w_id, o_d_id, o_id) + ); + create index bmsql_oorder_index1 on bmsql_oorder(o_w_id, o_d_id, o_c_id, o_id) ; + ``` + + >![](public_sys-resources/icon-note.png) **说明:** + >在MOT名字之前不需要指定FOREIGN关键字,因为它仅用于创建和删除表的命令。 + + +## 将磁盘表转换为MOT + +磁盘表直接转换为MOT尚不能实现,这意味着尚不存在将基于磁盘的表转换为MOT的ALTER TABLE语句。 + +下面介绍如何手动将基于磁盘的表转换为MOT,如何使用gs\_dump工具导出数据,以及如何使用gs\_restore工具导入数据。 + +- 前置条件检查 + + 检查待转换为MOT的磁盘表是否包含所有需要的列。 + + 检查表中是否包含任何不支持的列数据类型,具体参见“不支持的数据类型”。 + + 如果不支持特定列数据类型,则建议首先创建一个更新了列数据类型的磁盘表。此表内容与原始表相同,只是所有不支持的数据类型都已转换为支持的数据类型。 + + 使用以下脚本导出该备磁盘表,然后导入到MOT中。 + +- 转换 + + 要将基于磁盘的表转换为MOT,请执行以下步骤: + + 1. 暂停应用程序活动。 + 2. 使用gs\_dump工具将表数据转储到磁盘的物理文件中。请确保使用data only。 + 3. 重命名原始基于磁盘的表。 + 4. 创建同名同模式的MOT。请确保使用创建FOREIGN关键字指定该表为MOT。 + 5. 使用gs\_restore将磁盘文件的数据加载/恢复到数据库表中。 + 6. 浏览或手动验证所有原始数据是否正确导入到新的MOT中。下面将举例说明。 + 7. 恢复应用程序活动。 + + >![](public_sys-resources/icon-notice.png) **须知:** + >由于表名称保持不变,应用程序查询和相关数据库存储过程将能够无缝访问新的MOT,而无需更改代码。请注意,MOT目前不支持跨引擎多表查询(如使用Join、Union和子查询)和跨引擎多表事务。因此,如果在多表查询、存储过程或事务中访问原始表,则必须将所有相关的磁盘表转换为MOT,或者更改应用程序或数据库中的相关代码。 + +- 转换示例 + + 假设要将数据库benchmarksql中一个基于磁盘的表customer迁移到MOT中。 + + 将customer表迁移到MOT,操作步骤如下: + + 1. 检查源表列类型。验证MOT支持所有类型,详情请参阅“不支持的数据类型”章节。 + + ``` + benchmarksql-# \d+ customer + Table "public.customer" + Column | Type | Modifiers | Storage | Stats target | Description + --------+---------+-----------+---------+--------------+------------- + x | integer | | plain | | + y | integer | | plain | | + Has OIDs: no + Options: orientation=row, compression=no + ``` + + 2. 请检查源表数据。 + + ``` + benchmarksql=# select * from customer; + x | y + ---+--- + 1 | 2 + 3 | 4 + (2 rows) + ``` + + 3. 只能使用gs\_dump转储表数据。 + + ``` + $ gs_dump -Fc benchmarksql -a --table customer -f customer.dump -p 16000 + gs_dump[port='15500'][benchmarksql][2020-06-04 16:45:38]: dump database benchmarksql successfully + gs_dump[port='15500'][benchmarksql][2020-06-04 16:45:38]: total time: 332 ms + ``` + + 4. 重命名源表。 + + ``` + benchmarksql=# alter table customer rename to customer_bk; + ALTER TABLE + ``` + + 5. 创建与源表完全相同的MOT。 + + ``` + benchmarksql=# create foreign table customer (x int, y int); + CREATE FOREIGN TABLE + benchmarksql=# select * from customer; + x | y + ---+--- + (0 rows) + ``` + + 6. 将源转储数据导入到新MOT中。 + + ``` + $ gs_restore -C -d benchmarksql customer.dump -p 16000 + restore operation successful + total time: 24 ms + Check that the data was imported successfully. + benchmarksql=# select * from customer; + x | y + ---+--- + 1 | 2 + 3 | 4 + (2 rows) + + benchmarksql=# \d + List of relations + Schema | Name | Type | Owner | Storage + --------+-------------+---------------+--------+---------------------------------- + public | customer | foreign table | aharon | + public | customer_bk | table | aharon | {orientation=row,compression=no} + (2 rows) + ``` + + + diff --git "a/content/zh/docs/BriefTutorial/\345\210\227\345\255\230\345\202\250.md" "b/content/zh/docs/BriefTutorial/\345\210\227\345\255\230\345\202\250.md" index 543d8325fae9189e86ec9429fa985fce5778d982..0a34c6cc38acf89a254a71955ff517021a790e06 100644 --- "a/content/zh/docs/BriefTutorial/\345\210\227\345\255\230\345\202\250.md" +++ "b/content/zh/docs/BriefTutorial/\345\210\227\345\255\230\345\202\250.md" @@ -1,132 +1,132 @@ -# 列存储 - -openGauss支持行列混合存储。行存储是指将表按行存储到硬盘分区上,列存储是指将表按列存储到硬盘分区上。 - -行、列存储模型各有优劣,建议根据实际情况选择。通常openGauss用于OLTP(联机事务处理)场景的数据库,默认使用行存储,仅对执行复杂查询且数据量大的OLAP(联机分析处理)场景时,才使用列存储。默认情况下,创建的表为行存储。行存储和列存储的差异请参见[图1](#zh-cn_topic_0283136734_zh-cn_topic_0237120296_fig1417354233018)。 - -**图 1** 行存储和列存储的差异 - - -![](figures/zh-cn_image_0000001189073180.png) - -上图中,左上为行存表,右上为行存表在硬盘上的存储方式。左下为列存表,右下为列存表在硬盘上的存储方式。 - -行、列存储有如下优缺点: - - - - - - - - - - - - - - - - -

存储模型

-

优点

-

缺点

-

行存

-

数据被保存在一起。INSERT/UPDATE容易。

-

选择(SELECT)时即使只涉及某几列,所有数据也都会被读取。

-

列存

-
  • 查询时只有涉及到的列会被读取。
  • 投影(Projection)很高效。
  • 任何列都能作为索引。
-
  • 选择完成时,被选择的列要重新组装。
  • INSERT/UPDATE比较麻烦。
-
- -一般情况下,如果表的字段比较多(大宽表),查询中涉及到的列不多的情况下,适合列存储。如果表的字段个数比较少,查询大部分字段,那么选择行存储比较好。 - - - - - - - - - - - - - -

存储类型

-

适用场景

-

行存

-
  • 点查询(返回记录少,基于索引的简单查询)。
  • 增、删、改操作较多的场景。
  • 频繁的更新、少量的插入。
-

列存

-
  • 统计分析类查询 (关联、分组操作较多的场景)。
  • 即席查询(查询条件不确定,行存表扫描难以使用索引)。
  • 一次性大批量插入。
  • 表列数较多,建议使用列存表。
  • 如果每次查询时,只涉及了表的少数(<50%总列数)几个列,建议使用列存表。
-
- -## 语法格式 - -``` -CREATE TABLE table_name - (column_name data_type [, ... ]) - [ WITH ( ORIENTATION = value) ]; -``` - -## 参数说明 - -- **table\_name** - - 要创建的表名。 - -- **column\_name** - - 新表中要创建的字段名。 - -- **data\_type** - - 字段的数据类型。 - -- **ORIENTATION** - - 指定表数据的存储方式,即行存方式、列存方式,该参数设置成功后就不再支持修改。 - - 取值范围: - - - ROW,表示表的数据将以行式存储。 - - 行存储适合于OLTP业务,适用于点查询或者增删操作较多的场景。 - - - COLUMN,表示表的数据将以列式存储。 - - 列存储适合于数据仓库业务,此类型的表上会做大量的汇聚计算,且涉及的列操作较少。 - - - -## 示例 - -不指定ORIENTATION参数时,表默认为行存表。例如: - -``` -openGauss=# CREATE TABLE customer_test1 -( - state_ID CHAR(2), - state_NAME VARCHAR2(40), - area_ID NUMBER -); - ---删除表 -openGauss=# DROP TABLE customer_test1; -``` - -创建列存表时,需要指定ORIENTATION参数。例如: - -``` -openGauss=# CREATE TABLE customer_test2 -( - state_ID CHAR(2), - state_NAME VARCHAR2(40), - area_ID NUMBER -) -WITH (ORIENTATION = COLUMN); - ---删除表 -openGauss=# DROP TABLE customer_test2; -``` - +# 列存储 + +openGauss支持行列混合存储。行存储是指将表按行存储到硬盘分区上,列存储是指将表按列存储到硬盘分区上。 + +行、列存储模型各有优劣,建议根据实际情况选择。通常openGauss用于OLTP(联机事务处理)场景的数据库,默认使用行存储,仅对执行复杂查询且数据量大的OLAP(联机分析处理)场景时,才使用列存储。默认情况下,创建的表为行存储。行存储和列存储的差异请参见[图1](#zh-cn_topic_0283136734_zh-cn_topic_0237120296_fig1417354233018)。 + +**图 1** 行存储和列存储的差异 + + +![](figures/zh-cn_image_0000001189073180.png) + +上图中,左上为行存表,右上为行存表在硬盘上的存储方式。左下为列存表,右下为列存表在硬盘上的存储方式。 + +行、列存储有如下优缺点: + + + + + + + + + + + + + + + + +

存储模型

+

优点

+

缺点

+

行存

+

数据被保存在一起。INSERT/UPDATE容易。

+

选择(SELECT)时即使只涉及某几列,所有数据也都会被读取。

+

列存

+
  • 查询时只有涉及到的列会被读取。
  • 投影(Projection)很高效。
  • 任何列都能作为索引。
+
  • 选择完成时,被选择的列要重新组装。
  • INSERT/UPDATE比较麻烦。
+
+ +一般情况下,如果表的字段比较多(大宽表),查询中涉及到的列不多的情况下,适合列存储。如果表的字段个数比较少,查询大部分字段,那么选择行存储比较好。 + + + + + + + + + + + + + +

存储类型

+

适用场景

+

行存

+
  • 点查询(返回记录少,基于索引的简单查询)。
  • 增、删、改操作较多的场景。
  • 频繁的更新、少量的插入。
+

列存

+
  • 统计分析类查询 (关联、分组操作较多的场景)。
  • 即席查询(查询条件不确定,行存表扫描难以使用索引)。
  • 一次性大批量插入。
  • 表列数较多,建议使用列存表。
  • 如果每次查询时,只涉及了表的少数(<50%总列数)几个列,建议使用列存表。
+
+ +## 语法格式 + +``` +CREATE TABLE table_name + (column_name data_type [, ... ]) + [ WITH ( ORIENTATION = value) ]; +``` + +## 参数说明 + +- **table\_name** + + 要创建的表名。 + +- **column\_name** + + 新表中要创建的字段名。 + +- **data\_type** + + 字段的数据类型。 + +- **ORIENTATION** + + 指定表数据的存储方式,即行存方式、列存方式,该参数设置成功后就不再支持修改。 + + 取值范围: + + - ROW,表示表的数据将以行式存储。 + + 行存储适合于OLTP业务,适用于点查询或者增删操作较多的场景。 + + - COLUMN,表示表的数据将以列式存储。 + + 列存储适合于数据仓库业务,此类型的表上会做大量的汇聚计算,且涉及的列操作较少。该特性在金融版本下不支持。 + + + +## 示例 + +不指定ORIENTATION参数时,表默认为行存表。例如: + +``` +openGauss=# CREATE TABLE customer_test1 +( + state_ID CHAR(2), + state_NAME VARCHAR2(40), + area_ID NUMBER +); + +--删除表 +openGauss=# DROP TABLE customer_test1; +``` + +创建列存表时,需要指定ORIENTATION参数。例如: + +``` +openGauss=# CREATE TABLE customer_test2 +( + state_ID CHAR(2), + state_NAME VARCHAR2(40), + area_ID NUMBER +) +WITH (ORIENTATION = COLUMN); + +--删除表 +openGauss=# DROP TABLE customer_test2; +``` + diff --git "a/content/zh/docs/DatabaseReference/DCF\345\217\202\346\225\260\350\256\276\347\275\256.md" "b/content/zh/docs/DatabaseReference/DCF\345\217\202\346\225\260\350\256\276\347\275\256.md" index bfbf8ea6af73a9cb1ba7b2e98bc0fd688f81f5cb..39edcc5465b46f9dd50631c646dd04ea60ab94b7 100644 --- "a/content/zh/docs/DatabaseReference/DCF\345\217\202\346\225\260\350\256\276\347\275\256.md" +++ "b/content/zh/docs/DatabaseReference/DCF\345\217\202\346\225\260\350\256\276\347\275\256.md" @@ -2,7 +2,7 @@ ## enable\_dcf -**参数说明**: 是否开启DCF模式,该参数不允许修改。 +**参数说明**: 是否开启DCF模式,该参数不允许修改,该特性在金融版本下不支持。 该参数属于POSTMASTER类型参数,请参考[表1](重设参数.md#zh-cn_topic_0283137176_zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 diff --git "a/content/zh/docs/DatabaseReference/\344\274\230\345\214\226\345\231\250\346\226\271\346\263\225\351\205\215\347\275\256.md" "b/content/zh/docs/DatabaseReference/\344\274\230\345\214\226\345\231\250\346\226\271\346\263\225\351\205\215\347\275\256.md" index c1c36c2f0c9feea08aef9a2c2eef1d8b7a226752..30a50b41fe3fcfd7ca84a18953bb3c0217422d3b 100644 --- "a/content/zh/docs/DatabaseReference/\344\274\230\345\214\226\345\231\250\346\226\271\346\263\225\351\205\215\347\275\256.md" +++ "b/content/zh/docs/DatabaseReference/\344\274\230\345\214\226\345\231\250\346\226\271\346\263\225\351\205\215\347\275\256.md" @@ -1,401 +1,401 @@ -# 优化器方法配置 - -这些配置参数提供了影响查询优化器选择查询规划的原始方法。如果优化器为特定的查询选择的缺省规划并不是最优的,可以通过使用这些配置参数强制优化器选择一个不同的规划来临时解决这个问题。更好的方法包括调节优化器开销常量、手动运行ANALYZE、增加配置参数default\_statistics\_target的值、增加使用ALTER TABLE SET STATISTICS为指定列增加收集的统计信息。 - -## enable\_inner\_unique\_opt - -**参数说明**:控制优化器对Inner Unique优化的使用。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0283137176_zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示使用。 -- off表示不使用。 - -**默认值**:off - -## enable\_broadcast - -**参数说明**:控制优化器对stream代价估算时对broadcast分布方式的使用。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0283137176_zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示使用。 -- off表示不使用。 - -**默认值**:on - -## enable\_bitmapscan - -**参数说明**:控制优化器对位图扫描规划类型的使用。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示使用。 -- off表示不使用。 - -**默认值**:on - -## force\_bitmapand - -**参数说明**:控制优化器强制使用bitmapand规划类型的使用。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示使用。 -- off表示不使用。 - -**默认值**:off - -## enable\_hashagg - -**参数说明**:控制优化器对Hash聚集规划类型的使用。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示使用。 -- off表示不使用。 - -**默认值**:on - -## enable\_hashjoin - -**参数说明**:控制优化器对Hash连接规划类型的使用。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示使用。 -- off表示不使用。 - -**默认值**:on - -## enable\_indexscan - -**参数说明**:控制优化器对索引扫描规划类型的使用。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示使用。 -- off表示不使用。 - -**默认值**:on - -## enable\_indexonlyscan - -**参数说明**:控制优化器对仅索引扫描规划类型的使用。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示使用。 -- off表示不使用。 - -**默认值**:on - -## enable\_material - -**参数说明**:控制优化器对实体化的使用。消除整个实体化是不可能的,但是可以关闭这个变量以防止优化器插入实体节点。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示使用。 -- off表示不使用。 - -**默认值**:on - -## enable\_mergejoin - -**参数说明**:控制优化器对融合连接规划类型的使用。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示使用。 -- off表示不使用。 - -**默认值**:off - -## enable\_nestloop - -**参数说明**:控制优化器对内表全表扫描嵌套循环连接规划类型的使用。完全消除嵌套循环连接是不可能的,但是关闭这个变量就会让优化器在存在其他方法的时候优先选择其他方法。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示使用。 -- off表示不使用。 - -**默认值**:off - -## enable\_index\_nestloop - -**参数说明**:控制优化器对内表参数化索引扫描嵌套循环连接规划类型的使用。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示使用。 -- off表示不使用。 - -**默认值**:on - -## enable\_seqscan - -**参数说明**:控制优化器对顺序扫描规划类型的使用。完全消除顺序扫描是不可能的,但是关闭这个变量会让优化器在存在其他方法的时候优先选择其他方法。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示使用。 -- off表示不使用。 - -**默认值**:on - -## enable\_sort - -**参数说明**:控制优化器使用的排序步骤。完全消除明确的排序是不可能的,但是关闭这个变量可以让优化器在存在其他方法的时候优先选择其他方法。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示使用。 -- off表示不使用。 - -**默认值**:on - -## enable\_tidscan - -**参数说明**:控制优化器对TID扫描规划类型的使用。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示使用。 -- off表示不使用。 - -**默认值**:on - -## enable\_kill\_query - -**参数说明**:CASCADE模式删除用户时,会删除此用户拥有的所有对象。此参数标识是否允许在删除用户的时候,取消锁定此用户所属对象的query。 - -该参数属于SUSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示允许取消锁定。 -- off表示不允许取消锁定。 - -**默认值**:off - -## enforce\_a\_behavior - -**参数说明**:控制正则表达式的规则匹配模式。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示正则表达式采用A格式的匹配规则。 -- off表示正则表达式采用POSIX格式的匹配规则。 - -**默认值**:on - -## max\_recursive\_times - -**参数说明**:控制with recursive的最大迭代次数。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:整型,0~INT\_MAX。 - -**默认值**:200 - -## enable\_vector\_engine - -**参数说明**:控制优化器对向量化执行引擎的使用。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示使用。 -- off表示不使用。 - -**默认值**:on - -## enable\_vector\_targetlist - -**参数说明**:控制优化器对hashjoin与hashagg的下层算子中的投影列是否按需剪裁,会跟随try_vector_engine_strategy变化而变化。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示进行剪裁。 -- off表示不进行剪裁。 - -**默认值**:on - -## enable\_change\_hjcost - -**参数说明**:控制优化器在Hash Join代价估算路径选择时,是否使用将内表运行时代价排除在Hash Join节点运行时代价外的估算方式。如果使用,则有利于选择条数少,但运行代价大的表做内表。 - -该参数属于SUSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示使用。 -- off表示不使用。 - -**默认值**:off - -## enable\_absolute\_tablespace - -**参数说明**:控制表空间是否可以使用绝对路径。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示可以使用绝对路径。 -- off表示不可以使用绝对路径。 - -**默认值**:on - -## enable\_valuepartition\_pruning - -**参数说明**:控制是否对DFS分区表进行静态/动态优化。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示对DFS分区表进行静态/动态优化。 -- off表示不对DFS分区表进行静态/动态优化。 - -**默认值**:on - -## qrw\_inlist2join\_optmode - -**参数说明**:控制是否使用inlist-to-join查询重写。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:字符串 - -- disable:关闭inlist2join查询重写。 -- cost\_base:基于代价的inlist2join查询重写。 -- rule\_base:基于规则的inlist2join查询重写,即强制使用inlist2join查询重写。 -- 任意正整数:inlist2join查询重写阈值,即list内元素个数大于该阈值,进行inlist2join查询重写。 - -**默认值**:cost\_base - -## skew\_option - -**参数说明**:控制是否使用优化策略。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:字符串 - -- off:关闭策略。 -- normal:采用激进策略。对于不确定是否出现倾斜的场景,认为存在倾斜,并进行相应优化。 -- lazy:采用保守策略。对于不确定是否出现倾斜场景,认为不存在倾斜,不进行优化。 - -**默认值**:normal - -## default\_limit\_rows - -**参数说明**:设置生成genericplan的缺省limit估算行数。此参数设置为正数时表示直接将设置的值作为优化阶段估算limit的行数(但如果判断出语句实际返回的行数是小于该参数值的,以实际返回的行数为准作为估算值),设置为负数时表示使用百分比的形式设置默认的估算值,负数转换为默认百分比,即-5代表5%。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:浮点型,-100~DBL\_MAX。 - -**默认值**:-10 - -## check\_implicit\_conversions - -**参数说明**:控制是否对查询中有隐式类型转换的索引列是否会生成候选索引路径进行检查。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- on表示对查询中有隐式类型转换的索引列是否会生成候选索引路径进行检查。 -- off表示不进行相关检查。 - -**默认值**:off - -## cost\_weight\_index - -**参数说明**:设置index\_scan的代价权重。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0283137176_zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:浮点型,1e-10\~1e+10。 - -**默认值**:1 - -## try\_vector\_engine\_strategy - -**参数说明**:设置行存表走向量化执行引擎的策略。通过设置该参数,可以使包含行存表的查询可以转换为向量化的执行计划执行计算,从而提升类AP场景的复杂查询的执行性能。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0283137176_zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:枚举型 - -- off,为默认取值,表示关闭本功能,即行存表不会转换为向量的执行计划执行。 -- force,表示只要查询中不包含向量化引擎不支持的类型或者表达式,则不论查询的基表为行存表、列存表,还是行列混合存储的,强制将查询转换为向量化的执行计划执行计算。在这种情况下,针对不同的查询场景可能出现性能下降。 -- optimal,表示在force的基础上,由优化器根据查询的复杂度进行选择是否将查询语句转换为向量化的执行计划,尽可能避免转换为向量化的执行计划后出现性能下降。 - -**默认值**:off - -## enable\_expr\_fusion - -**参数说明**:控制SRF、表达式展平、取消集中式Seq Scan投影、共享聚合函数的转移状态和Step步数优化特性的开关。 - -该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0283137176_zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- off:为默认取值,表示关闭本功能。 -- on:表示同时启用SRF、表达式展平、取消集中式Seq Scan投影、共享聚合函数的转移状态和Step步数优化特性。 - -**默认值**:off - -## enable\_default\_index\_deduplication - -**参数说明**:设置btree索引默认情况下是否对键值重复的元组进行去重压缩。去重压缩功能对主键索引和唯一索引不生效。在重复键值的索引较多时,去重压缩功能可以有效降低索引占用空间。非唯一索引且索引键值重复度很低或者唯一的场景,去重压缩功能会使索引插入性能小幅度劣化。若创建索引时带有with(deduplication=on/off)语法时,优先根据deduplication参数决定该索引是否使用去重压缩功能。 - -该参数属于POSTMASTER类型参数,请参考[表1](重设参数.md#zh-cn_topic_0283137176_zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 - -**取值范围**:布尔型 - -- off:为默认取值,表示btree索引默认关闭索引去重压缩功能。 -- on:表示btree索引默认开启索引去重压缩功能。 - -**默认值**:off +# 优化器方法配置 + +这些配置参数提供了影响查询优化器选择查询规划的原始方法。如果优化器为特定的查询选择的缺省规划并不是最优的,可以通过使用这些配置参数强制优化器选择一个不同的规划来临时解决这个问题。更好的方法包括调节优化器开销常量、手动运行ANALYZE、增加配置参数default\_statistics\_target的值、增加使用ALTER TABLE SET STATISTICS为指定列增加收集的统计信息。 + +## enable\_inner\_unique\_opt + +**参数说明**:控制优化器对Inner Unique优化的使用。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0283137176_zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示使用。 +- off表示不使用。 + +**默认值**:off + +## enable\_broadcast + +**参数说明**:控制优化器对stream代价估算时对broadcast分布方式的使用。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0283137176_zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示使用。 +- off表示不使用。 + +**默认值**:on + +## enable\_bitmapscan + +**参数说明**:控制优化器对位图扫描规划类型的使用。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示使用。 +- off表示不使用。 + +**默认值**:on + +## force\_bitmapand + +**参数说明**:控制优化器强制使用bitmapand规划类型的使用。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示使用。 +- off表示不使用。 + +**默认值**:off + +## enable\_hashagg + +**参数说明**:控制优化器对Hash聚集规划类型的使用。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示使用。 +- off表示不使用。 + +**默认值**:on + +## enable\_hashjoin + +**参数说明**:控制优化器对Hash连接规划类型的使用。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示使用。 +- off表示不使用。 + +**默认值**:on + +## enable\_indexscan + +**参数说明**:控制优化器对索引扫描规划类型的使用。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示使用。 +- off表示不使用。 + +**默认值**:on + +## enable\_indexonlyscan + +**参数说明**:控制优化器对仅索引扫描规划类型的使用。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示使用。 +- off表示不使用。 + +**默认值**:on + +## enable\_material + +**参数说明**:控制优化器对实体化的使用。消除整个实体化是不可能的,但是可以关闭这个变量以防止优化器插入实体节点。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示使用。 +- off表示不使用。 + +**默认值**:on + +## enable\_mergejoin + +**参数说明**:控制优化器对融合连接规划类型的使用。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示使用。 +- off表示不使用。 + +**默认值**:off + +## enable\_nestloop + +**参数说明**:控制优化器对内表全表扫描嵌套循环连接规划类型的使用。完全消除嵌套循环连接是不可能的,但是关闭这个变量就会让优化器在存在其他方法的时候优先选择其他方法。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示使用。 +- off表示不使用。 + +**默认值**:off + +## enable\_index\_nestloop + +**参数说明**:控制优化器对内表参数化索引扫描嵌套循环连接规划类型的使用。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示使用。 +- off表示不使用。 + +**默认值**:on + +## enable\_seqscan + +**参数说明**:控制优化器对顺序扫描规划类型的使用。完全消除顺序扫描是不可能的,但是关闭这个变量会让优化器在存在其他方法的时候优先选择其他方法。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示使用。 +- off表示不使用。 + +**默认值**:on + +## enable\_sort + +**参数说明**:控制优化器使用的排序步骤。完全消除明确的排序是不可能的,但是关闭这个变量可以让优化器在存在其他方法的时候优先选择其他方法。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示使用。 +- off表示不使用。 + +**默认值**:on + +## enable\_tidscan + +**参数说明**:控制优化器对TID扫描规划类型的使用。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示使用。 +- off表示不使用。 + +**默认值**:on + +## enable\_kill\_query + +**参数说明**:CASCADE模式删除用户时,会删除此用户拥有的所有对象。此参数标识是否允许在删除用户的时候,取消锁定此用户所属对象的query。 + +该参数属于SUSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示允许取消锁定。 +- off表示不允许取消锁定。 + +**默认值**:off + +## enforce\_a\_behavior + +**参数说明**:控制正则表达式的规则匹配模式。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示正则表达式采用A格式的匹配规则。 +- off表示正则表达式采用POSIX格式的匹配规则。 + +**默认值**:on + +## max\_recursive\_times + +**参数说明**:控制with recursive的最大迭代次数。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:整型,0~INT\_MAX。 + +**默认值**:200 + +## enable\_vector\_engine + +**参数说明**:控制优化器对向量化执行引擎的使用。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示使用。 +- off表示不使用。 + +**默认值**:on + +## enable\_vector\_targetlist + +**参数说明**:控制优化器对hashjoin与hashagg的下层算子中的投影列是否按需剪裁,会跟随try_vector_engine_strategy变化而变化。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示进行剪裁。 +- off表示不进行剪裁。 + +**默认值**:on + +## enable\_change\_hjcost + +**参数说明**:控制优化器在Hash Join代价估算路径选择时,是否使用将内表运行时代价排除在Hash Join节点运行时代价外的估算方式。如果使用,则有利于选择条数少,但运行代价大的表做内表。 + +该参数属于SUSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示使用。 +- off表示不使用。 + +**默认值**:off + +## enable\_absolute\_tablespace + +**参数说明**:控制表空间是否可以使用绝对路径。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示可以使用绝对路径。 +- off表示不可以使用绝对路径。 + +**默认值**:on + +## enable\_valuepartition\_pruning + +**参数说明**:控制是否对DFS分区表进行静态/动态优化。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示对DFS分区表进行静态/动态优化。 +- off表示不对DFS分区表进行静态/动态优化。 + +**默认值**:on + +## qrw\_inlist2join\_optmode + +**参数说明**:控制是否使用inlist-to-join查询重写。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:字符串 + +- disable:关闭inlist2join查询重写。 +- cost\_base:基于代价的inlist2join查询重写。 +- rule\_base:基于规则的inlist2join查询重写,即强制使用inlist2join查询重写。 +- 任意正整数:inlist2join查询重写阈值,即list内元素个数大于该阈值,进行inlist2join查询重写。 + +**默认值**:cost\_base + +## skew\_option + +**参数说明**:控制是否使用优化策略。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:字符串 + +- off:关闭策略。 +- normal:采用激进策略。对于不确定是否出现倾斜的场景,认为存在倾斜,并进行相应优化。 +- lazy:采用保守策略。对于不确定是否出现倾斜场景,认为不存在倾斜,不进行优化。 + +**默认值**:normal + +## default\_limit\_rows + +**参数说明**:设置生成genericplan的缺省limit估算行数。此参数设置为正数时表示直接将设置的值作为优化阶段估算limit的行数(但如果判断出语句实际返回的行数是小于该参数值的,以实际返回的行数为准作为估算值),设置为负数时表示使用百分比的形式设置默认的估算值,负数转换为默认百分比,即-5代表5%。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:浮点型,-100~DBL\_MAX。 + +**默认值**:-10 + +## check\_implicit\_conversions + +**参数说明**:控制是否对查询中有隐式类型转换的索引列是否会生成候选索引路径进行检查。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- on表示对查询中有隐式类型转换的索引列是否会生成候选索引路径进行检查。 +- off表示不进行相关检查。 + +**默认值**:off + +## cost\_weight\_index + +**参数说明**:设置index\_scan的代价权重。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0283137176_zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:浮点型,1e-10\~1e+10。 + +**默认值**:1 + +## try\_vector\_engine\_strategy + +**参数说明**:设置行存表走向量化执行引擎的策略。通过设置该参数,可以使包含行存表的查询可以转换为向量化的执行计划执行计算,从而提升类AP场景的复杂查询的执行性能,该特性在金融版本下不支持。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0283137176_zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:枚举型 + +- off,为默认取值,表示关闭本功能,即行存表不会转换为向量的执行计划执行。 +- force,表示只要查询中不包含向量化引擎不支持的类型或者表达式,则不论查询的基表为行存表、列存表,还是行列混合存储的,强制将查询转换为向量化的执行计划执行计算。在这种情况下,针对不同的查询场景可能出现性能下降。 +- optimal,表示在force的基础上,由优化器根据查询的复杂度进行选择是否将查询语句转换为向量化的执行计划,尽可能避免转换为向量化的执行计划后出现性能下降。 + +**默认值**:off + +## enable\_expr\_fusion + +**参数说明**:控制SRF、表达式展平、取消集中式Seq Scan投影、共享聚合函数的转移状态和Step步数优化特性的开关。 + +该参数属于USERSET类型参数,请参考[表1](重设参数.md#zh-cn_topic_0283137176_zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- off:为默认取值,表示关闭本功能。 +- on:表示同时启用SRF、表达式展平、取消集中式Seq Scan投影、共享聚合函数的转移状态和Step步数优化特性。 + +**默认值**:off + +## enable\_default\_index\_deduplication + +**参数说明**:设置btree索引默认情况下是否对键值重复的元组进行去重压缩。去重压缩功能对主键索引和唯一索引不生效。在重复键值的索引较多时,去重压缩功能可以有效降低索引占用空间。非唯一索引且索引键值重复度很低或者唯一的场景,去重压缩功能会使索引插入性能小幅度劣化。若创建索引时带有with(deduplication=on/off)语法时,优先根据deduplication参数决定该索引是否使用去重压缩功能。 + +该参数属于POSTMASTER类型参数,请参考[表1](重设参数.md#zh-cn_topic_0283137176_zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 + +**取值范围**:布尔型 + +- off:为默认取值,表示btree索引默认关闭索引去重压缩功能。 +- on:表示btree索引默认开启索引去重压缩功能。 + +**默认值**:off diff --git "a/content/zh/docs/DatabaseReference/\345\205\266\345\256\203\351\200\211\351\241\271.md" "b/content/zh/docs/DatabaseReference/\345\205\266\345\256\203\351\200\211\351\241\271.md" index d58743b57be866f922849940d45a2a03def388b8..5cd18e2379a8c178f99af8b58da61ceba3c94ea3 100644 --- "a/content/zh/docs/DatabaseReference/\345\205\266\345\256\203\351\200\211\351\241\271.md" +++ "b/content/zh/docs/DatabaseReference/\345\205\266\345\256\203\351\200\211\351\241\271.md" @@ -12,7 +12,7 @@ ## enable\_ustore -**参数说明**: 指定是否开启Ustore存储引擎,该参数为on时,支持创建Ustore表。特别需要注意,使用Ustore表,必须要开启track_counts和track_activities参数,否则会引起空间膨胀。 +**参数说明**: 指定是否开启Ustore存储引擎,该参数为on时,支持创建Ustore表。特别需要注意,使用Ustore表,必须要开启track_counts和track_activities参数,否则会引起空间膨胀,该特性在金融版本下不支持。 该参数属于POSTMASTER类型,请参考[表1](重设参数.md#zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)对应设置方法进行设置。 diff --git "a/content/zh/docs/DatabaseReference/\345\256\211\345\205\250\351\205\215\347\275\256.md" "b/content/zh/docs/DatabaseReference/\345\256\211\345\205\250\351\205\215\347\275\256.md" index 42ede70cfbd8a675673e282f1c3c42dbc6b55ede..d098c2fb642be79d1f3d08f4bd0198e823b7c306 100644 --- "a/content/zh/docs/DatabaseReference/\345\256\211\345\205\250\351\205\215\347\275\256.md" +++ "b/content/zh/docs/DatabaseReference/\345\256\211\345\205\250\351\205\215\347\275\256.md" @@ -54,7 +54,7 @@ off:不是初始用户。 ## enable\_tde -**参数说明**: 透明数据加密功能开关。创建加密表前需要将此参数置为on。当前参数值为off时,禁止创建新的加密表,对于已经创建的加密表只在读取数据时解密,写入数据时不再加密。 +**参数说明**: 透明数据加密功能开关。创建加密表前需要将此参数置为on。当前参数值为off时,禁止创建新的加密表,对于已经创建的加密表只在读取数据时解密,写入数据时不再加密。该特性在金融版本下不支持。 该参数属于POSTMASTER类型参数,请参考[表1](重设参数.md#zh-cn_topic_0283137176_zh-cn_topic_0237121562_zh-cn_topic_0059777490_t91a6f212010f4503b24d7943aed6d846)中对应设置方法进行设置。 diff --git "a/content/zh/docs/DatabaseReference/\345\275\222\346\241\243.md" "b/content/zh/docs/DatabaseReference/\345\275\222\346\241\243.md" index 4e19f63c8ce8c0e5e1c1e29cf16623ad0a3606d3..028279fa3c2635ac92e279e0b51278d2d9972d9d 100644 --- "a/content/zh/docs/DatabaseReference/\345\275\222\346\241\243.md" +++ "b/content/zh/docs/DatabaseReference/\345\275\222\346\241\243.md" @@ -8,6 +8,7 @@ >![](public_sys-resources/icon-notice.png) **须知:** >当[wal\_level](设置.md#zh-cn_topic_0283137354_zh-cn_topic_0237124707_zh-cn_topic_0059778393_s2c76f5957066407a959191148f2c780f)设置成minimal时,archive\_mode参数无法使用。 +>该特性在金融版本下不支持 **取值范围**:布尔型 diff --git a/content/zh/docs/SQLReference/CREATE-TABLE-PARTITION.md b/content/zh/docs/SQLReference/CREATE-TABLE-PARTITION.md index c7c13e1912fc634eddaa16447aeb83a0a4ae3c01..c34377cf8db7fd6cad58fdb95e3f8eea8f5931a3 100644 --- a/content/zh/docs/SQLReference/CREATE-TABLE-PARTITION.md +++ b/content/zh/docs/SQLReference/CREATE-TABLE-PARTITION.md @@ -1,1111 +1,1112 @@ -# CREATE TABLE PARTITION - -## 功能描述 - -创建分区表。分区表是把逻辑上的一张表根据某种方案分成几张物理块进行存储,这张逻辑上的表称之为分区表,物理块称之为分区。分区表是一张逻辑表,不存储数据,数据实际是存储在分区上的。 - -常见的分区方案有范围分区(Range Partitioning)、间隔分区(Interval Partitioning)、哈希分区(Hash Partitioning)、列表分区(List Partitioning)、数值分区(Value Partition)等。目前行存表支持范围分区、间隔分区、哈希分区、列表分区,列存表仅支持范围分区。 - -范围分区是根据表的一列或者多列,将要插入表的记录分为若干个范围,这些范围在不同的分区里没有重叠。为每个范围创建一个分区,用来存储相应的数据。 - -范围分区的分区策略是指记录插入分区的方式。目前范围分区仅支持范围分区策略。 - -范围分区策略:根据分区键值将记录映射到已创建的某个分区上,如果可以映射到已创建的某一分区上,则把记录插入到对应的分区上,否则给出报错和提示信息。这是最常用的分区策略。 - -间隔分区是一种特殊的范围分区,相比范围分区,新增间隔值定义,当插入记录找不到匹配的分区时,可以根据间隔值自动创建分区。 - -间隔分区只支持基于表的一列分区,并且该列只支持TIMESTAMP\[\(p\)\] \[WITHOUT TIME ZONE\]、TIMESTAMP\[\(p\)\] \[WITH TIME ZONE\]、DATE数据类型。 - -间隔分区策略:根据分区键值将记录映射到已创建的某个分区上,如果可以映射到已创建的某一分区上,则把记录插入到对应的分区上,否则根据分区键值和表定义信息自动创建一个分区,然后将记录插入新分区中,新创建的分区数据范围等于间隔值。 - -哈希分区是根据表的一列,为每个分区指定模数和余数,将要插入表的记录划分到对应的分区中,每个分区所持有的行都需要满足条件:分区键的值除以为其指定的模数将产生为其指定的余数。 - -哈希分区策略:根据分区键值将记录映射到已创建的某个分区上,如果可以映射到已创建的某一分区上,则把记录插入到对应的分区上,否则返回报错和提示信息。 - -列表分区是根据表的一列,将要插入表的记录通过每一个分区中出现的键值划分到对应的分区中,这些键值在不同的分区里没有重叠。为每组键值创建一个分区,用来存储相应的数据。 - -列表分区策略:根据分区键值将记录映射到已创建的某个分区上,如果可以映射到已创建的某一分区上,则把记录插入到对应的分区上,否则给出报错和提示信息。 - -分区可以提供若干好处: - -- 某些类型的查询性能可以得到极大提升。特别是表中访问率较高的行位于一个单独分区或少数几个分区上的情况下。分区可以减少数据的搜索空间,提高数据访问效率。 -- 当查询或更新一个分区的大部分记录时,连续扫描那个分区而不是访问整个表可以获得巨大的性能提升。 -- 如果需要大量加载或者删除的记录位于单独的分区上,则可以通过直接读取或删除那个分区以获得巨大的性能提升,同时还可以避免由于大量DELETE导致的VACUUM超载(哈希分区不支持删除分区)。 - -## 注意事项 - -- 唯一约束和主键约束的约束键包含所有分区键将为约束创建LOCAL索引,否则创建GLOBAL索引。 -- 目前哈希分区和列表分区仅支持单列构建分区键,暂不支持多列构建分区键。 -- 只需要有间隔分区表的INSERT权限,往该表INSERT数据时就可以自动创建分区。 -- 对于分区表PARTITION FOR \(values\)语法,values只能是常量。 -- 对于分区表PARTITION FOR \(values\)语法,values在需要数据类型转换时,建议使用强制类型转换,以防隐式类型转换结果与预期不符。 -- 分区数最大值为1048575个,一般情况下业务不可能创建这么多分区,这样会导致内存不足。应参照参数local\_syscache\_threshold的值合理创建分区,分区表使用内存大致为(分区数 \* 3 / 1024)MB。理论上分区占用内存不允许大于local\_syscache\_threshold的值,同时还需要预留部分空间以供其他功能使用。 -- 当分区数太多导致内存不足时,会间接导致性能急剧下降。 -- 指定分区语句目前不能走全局索引扫描。 -- 目前Hash分区是按倒序排列的,即通过哈希和取余计算后得到的分区下标与创建顺序相反,同样EXPLAIN计划显示的Selected Partitions的序号排序也与创建顺序相反。List分区是按分区数组的第一个元素排序的。 -- 支持使用表达式当作分区键,允许分区键使用算术运算符 "+"、"-"、"*"。 -- 只支持部分函数允许在分区键中使用,支持的函数为: ABS()、CEILING()。 -- 表达式用作分区键时,只支持设置一个partition key,且分区为range、hash和list分区,另外暂不支持列存表。 - -## 语法格式 - -``` -CREATE TABLE [ IF NOT EXISTS ] partition_table_name -( [ - { column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ] - | table_constraint - | LIKE source_table [ like_option [...] ] }[, ... ] -] ) - [ AUTO_INCREMENT [ = ] value ] - [ WITH ( {storage_parameter = value} [, ... ] ) ] - [ COMPRESS | NOCOMPRESS ] - [ TABLESPACE tablespace_name ] - [ COMMENT {=| } 'text' ] - PARTITION BY { - {RANGE [COLUMNS] (partition_key) [ INTERVAL ('interval_expr') [ STORE IN (tablespace_name [, ... ] ) ] ] [ PARTITIONS integer ] ( partition_less_than_item [, ... ] )} | - {RANGE [COLUMNS] (partition_key) [ INTERVAL ('interval_expr') [ STORE IN (tablespace_name [, ... ] ) ] ] [ PARTITIONS integer ] ( partition_start_end_item [, ... ] )} | - {LIST [COLUMNS] (partition_key) [ PARTITIONS integer ] ( PARTITION partition_name VALUES [IN] (list_values) [TABLESPACE [=] tablespace_name][, ... ])} | - {{ HASH | KEY } (partition_key) [ PARTITIONS integer ] ( PARTITION partition_name [TABLESPACE [=] tablespace_name][, ... ])} - {RANGE (partition_key) [ INTERVAL ('interval_expr') [ STORE IN (tablespace_name [, ... ] ) ] ] ( partition_less_than_item [COMMENT {=| } 'text'][...][, ... ] )} | - {RANGE (partition_key) [ INTERVAL ('interval_expr') [ STORE IN (tablespace_name [, ... ] ) ] ] ( partition_start_end_item [COMMENT {=| } 'text'][...][, ... ] )} | - {LIST | HASH (partition_key) (PARTITION partition_name [VALUES (list_values_clause)] opt_table_space [COMMENT {=| } 'text'][...])} - } [ { ENABLE | DISABLE } ROW MOVEMENT ]; -``` - -- 列约束column\_constraint: - - ``` - [ CONSTRAINT constraint_name ] - { NOT NULL | - NULL | - CHECK ( expression ) | - DEFAULT default_e xpr | - GENERATED ALWAYS AS ( generation_expr ) [STORED] | - AUTO_INCREMENT | - UNIQUE [KEY] 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 ] - [ COMMENT {=| } 'text' ] - ``` - -- 表约束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 | - FOREIGN KEY [ index_name ] ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] - [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] } - [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] - [ COMMENT {=| } 'text' ] - ``` - - -- like选项like\_option: - - ``` - { INCLUDING | EXCLUDING } { DEFAULTS | GENERATED | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | RELOPTIONS| ALL } - ``` - - -- 索引存储参数index\_parameters: - - ``` - [ WITH ( {storage_parameter = value} [, ... ] ) ] - [ USING INDEX TABLESPACE tablespace_name ] - ``` - - -- 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) EVERY (interval_value)} | - {START(partition_value) END ({partition_value | MAXVALUE})} | - {START(partition_value)} | - {END({partition_value | MAXVALUE})} - } [TABLESPACE [=] tablespace_name] - ``` - -- COMMENT {=| } 'text': - - 分区表的分区中,该字段无实际意义,仅作语法兼容。在数据库中使用该语法时会有告警提示。 - -## 参数说明 - -- **IF NOT EXISTS** - - 如果已经存在相同名称的表,不会抛出一个错误,而会发出一个通知,告知表关系已存在。 - -- **partition\_table\_name** - - 分区表的名称。 - - 取值范围:字符串,要符合标识符的命名规范。 - -- **column\_name** - - 新表中要创建的字段名。 - - 取值范围:字符串,要符合标识符的命名规范。 - -- **data\_type** - - 字段的数据类型。 - -- **COLLATE collation** - - COLLATE子句指定列的排序规则(该列必须是可排列的数据类型)。如果没有指定,则使用默认的排序规则。排序规则可以使用“select \* from pg\_collation;”命令从pg\_collation系统表中查询,默认的排序规则为查询结果中以default开始的行。 - -- **CONSTRAINT constraint\_name** - - 列约束或表约束的名称。可选的约束子句用于声明约束,新行或者更新的行必须满足这些约束才能成功插入或更新。 - - 定义约束有两种方法: - - - 列约束:作为一个列定义的一部分,仅影响该列。 - - 表约束:不和某个列绑在一起,可以作用于多个列。在B模式数据库下(即sql\_compatibility = 'B')constraint\_name为可选项,在其他模式数据库下,必须加上constraint\_name。 - -- **index\_name** - - 索引名。 - - >![](public_sys-resources/icon-notice.png) **须知:** - > - >- index\_name仅在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库下不支持。 - >- 对于外键约束,constraint\_name和index\_name同时指定时,索引名为constraint\_name。 - >- 对于唯一键约束,constraint\_name和index\_name同时指定时,索引名以index\_name。 - -- **USING method** - - 指定创建索引的方法。 - - 取值范围参考[参数说明](CREATE-INDEX.md)中的USING method。 - - >![](public_sys-resources/icon-notice.png) **须知:** - > - >- USING method仅在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库下不支持。 - >- 在B模式下,未指定USING method时,对于ASTORE的存储方式,默认索引方法为btree;对于USTORE的存储方式,默认索引方法为ubtree。 - -- **ASC | DESC** - - ASC表示指定按升序排序(默认)。DESC指定按降序排序。 - - >![](public_sys-resources/icon-notice.png) **须知:** - > - >ASC|DESC只在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库不支持。 - - -- **LIKE source\_table \[ like\_option ... \]** - - LIKE子句声明一个表,新表自动从这个表里面继承所有字段名及其数据类型和非空约束。 - - 和INHERITS不同,新表与原来的表之间在创建动作完毕之后是完全无关的。在源表做的任何修改都不会传播到新表中,并且也不可能在扫描源表的时候包含新表的数据。 - - - 字段缺省表达式只有在声明了INCLUDING DEFAULTS之后才会包含进来。缺省是不包含缺省表达式的,即新表中所有字段的缺省值都是NULL。 - - 如果指定了INCLUDING GENERATED,则源表列的生成表达式会复制到新表中。默认不复制生成表达式。 - - 非空约束将总是复制到新表中,CHECK约束则仅在指定了INCLUDING CONSTRAINTS的时候才复制,而其他类型的约束则永远也不会被复制。此规则同时适用于表约束和列约束。 - - 和INHERITS不同,被复制的列和约束并不使用相同的名称进行融合。如果明确的指定了相同的名称或者在另外一个LIKE子句中,将会报错。 - - 如果指定了INCLUDING INDEXES,则源表上的索引也将在新表上创建,默认不建立索引。 - - 如果指定了INCLUDING STORAGE,则源表列的STORAGE设置也将被拷贝,默认情况下不包含STORAGE设置。 - - 如果指定了INCLUDING COMMENTS,则源表列、约束和索引的注释也会被拷贝过来。默认情况下,不拷贝源表的注释。 - - 如果指定了INCLUDING RELOPTIONS,则源表的存储参数(即源表的WITH子句)也将拷贝至新表。默认情况下,不拷贝源表的存储参数。 - - INCLUDING ALL包含了INCLUDING DEFAULTS、INCLUDING CONSTRAINTS、INCLUDING INDEXES、INCLUDING STORAGE、INCLUDING COMMENTS、INCLUDING PARTITION和INCLUDING RELOPTIONS的内容。 - -- **AUTO\_INCREMENT \[ = \] value** - - 这个子句为自动增长列指定一个初始值,value必须为正整数,不得超过2127-1。 - - >![](public_sys-resources/icon-notice.png) **须知:** - > - >该子句仅在参数sql\_compatibility=B时有效。 - -- **WITH \( storage\_parameter \[= value\] \[, ... \] \)** - - 这个子句为表或索引指定一个可选的存储参数。参数的详细描述如下所示: - - - FILLFACTOR - - 一个表的填充因子(fillfactor)是一个介于10和100之间的百分数。100(完全填充)是默认值。如果指定了较小的填充因子,INSERT操作仅按照填充因子指定的百分率填充表页。每个页上的剩余空间将用于在该页上更新行,这就使得UPDATE有机会在同一页上放置同一条记录的新版本,这比把新版本放置在其他页上更有效。对于一个从不更新的表将填充因子设为100是最佳选择,但是对于频繁更新的表,选择较小的填充因子则更加合适。该参数对于列存表没有意义。 - - 取值范围:10\~100 - - - ORIENTATION - - 决定了表的数据的存储方式。 - - 取值范围: - - - COLUMN:表的数据将以列式存储。 - - ROW(缺省值):表的数据将以行式存储。 - - >![](public_sys-resources/icon-notice.png) **须知:** - > - >orientation不支持修改。 - - - COMPRESSTYPE - - 行存表参数,设置行存表压缩算法。1代表pglz算法(不推荐使用),2代表zstd算法,默认不压缩。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。(仅支持ASTORE和USTORE下的普通表和分区表) - - 取值范围:0\~2,默认值为0。 - - - COMPRESS\_LEVEL - - 行存表参数,设置行存表压缩算法等级,仅当COMPRESSTYPE为2时生效。压缩等级越高,表的压缩效果越好,表的访问速度越慢。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - - 取值范围:-31\~31,默认值为0。 - - - COMPRESS\_CHUNK_SIZE - - 行存表参数,设置行存表压缩chunk块大小,仅当COMPRESSTYPE不为0时生效。chunk数据块越小,预期能达到的压缩效果越好,同时数据越离散,影响表的访问速度。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - 取值范围:与页面大小有关。在页面大小为8k场景,取值范围为:512、1024、2048、4096。 - - 默认值:4096 - - - COMPRESS_PREALLOC_CHUNKS - - 行存表参数,设置行存表压缩chunk块预分配数量。预分配数量越大,表的压缩率相对越差,离散度越小,访问性能越好。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - - 取值范围:0\~7,默认值为0。 - - - 当COMPRESS\_CHUNK_SIZE为512和1024时,支持预分配设置最大为7。 - - 当COMPRESS\_CHUNK_SIZE为2048时,支持预分配设置最大为3。 - - 当COMPRESS\_CHUNK_SIZE为4096时,支持预分配设置最大为1。 - - - COMPRESS_BYTE_CONVERT - - 行存表参数,设置行存表压缩字节转换预处理,仅当COMPRESSTYPE不为0时生效。在一些场景下可以提升压缩效果,同时会导致一定性能劣化。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - - 取值范围:布尔值,默认关闭。 - - - COMPRESS_DIFF_CONVERT - - 行存表参数,设置行存表压缩字节差分预处理。只能与compress_byte_convert一起使用。在一些场景下可以提升压缩效果,同时会导致一定性能劣化。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - - 取值范围:布尔值,默认关闭。 - - - STORAGE\_TYPE - - 指定存储引擎类型,该参数设置成功后就不再支持修改。 - - 取值范围: - - - USTORE,表示表支持Inplace-Update存储引擎。特别需要注意,使用USTORE表,必须要开启track\_counts和track\_activities参数,否则会引起空间膨胀。 - - - ASTORE,表示表支持Append-Only存储引擎。 - - 默认值: 不指定表时,默认是Append-Only存储。 - - - COMPRESSION - - 列存表的有效值为LOW/MIDDLE/HIGH/YES/NO,压缩级别依次升高,默认值为LOW。 - - 行存表不支持压缩。 - - - MAX\_BATCHROW - - 指定了在数据加载过程中一个存储单元可以容纳记录的最大数目。该参数只对列存表有效。 - - 取值范围:10000\~60000,默认60000。 - - - PARTIAL\_CLUSTER\_ROWS - - 指定了在数据加载过程中进行将局部聚簇存储的记录数目。该参数只对列存表有效。 - - 取值范围:大于等于MAX\_BATCHROW,建议取值为MAX\_BATCHROW的整数倍数。 - - - DELTAROW\_THRESHOLD - - 预留参数。该参数只对列存表有效。 - - 取值范围:0~9999 - - - segment - - 使用段页式的方式存储。本参数仅支持行存表。不支持列存表、临时表、unlog表。不支持ustore存储引擎。 - - 取值范围:on/off - - 默认值:off - -- **COMPRESS / NOCOMPRESS** - - 创建一个新表时,需要在创建表语句中指定关键字COMPRESS,这样,当对该表进行批量插入时就会触发压缩特性。该特性会在页范围内扫描所有元组数据,生成字典、压缩元组数据并进行存储。指定关键字NOCOMPRESS则不对表进行压缩。行存表不支持压缩。该参数已废弃,列存表请使用COMPRESSION修改压缩等级。 - - 缺省值为NOCOMPRESS,即不对元组数据进行压缩。 - -- **TABLESPACE tablespace\_name** - - 指定新表将要在tablespace\_name表空间内创建。如果没有声明,将使用默认表空间。 - -- **PARTITION BY RANGE \[COLUMNS\]\(partition\_key\)** - - 创建范围分区。partition\_key为分区键的名称。 - - COLUMNS关键字只能在sql\_compatibility='B'时使用,“PARTITION BY RANGE COLUMNS” 语义同 “PARTITION BY RANGE”。 - - (1)对于从句是VALUES LESS THAN的语法格式: - - >![](public_sys-resources/icon-notice.png) **须知:** - >对于从句是VALUE LESS THAN的语法格式,范围分区策略的分区键最多支持16列。 - - 该情形下,分区键支持的数据类型为:SMALLINT、INTEGER、BIGINT、DECIMAL、NUMERIC、REAL、DOUBLE PRECISION、CHARACTER VARYING\(n\)、VARCHAR\(n\)、CHARACTER\(n\)、CHAR\(n\)、CHARACTER、CHAR、TEXT、NVARCHAR、NVARCHAR2、NAME、TIMESTAMP\[\(p\)\] \[WITHOUT TIME ZONE\]、TIMESTAMP\[\(p\)\] \[WITH TIME ZONE\]、DATE。 - - (2)对于从句是START END的语法格式: - - >![](public_sys-resources/icon-notice.png) **须知:** - >对于从句是START END的语法格式,范围分区策略的分区键仅支持1列。 - - 该情形下,分区键支持的数据类型为:SMALLINT、INTEGER、BIGINT、DECIMAL、NUMERIC、REAL、DOUBLE PRECISION、TIMESTAMP\[\(p\)\] \[WITHOUT TIME ZONE\]、TIMESTAMP\[\(p\)\] \[WITH TIME ZONE\]、DATE。 - - (3)对于指定了INTERVAL子句的语法格式: - - >![](public_sys-resources/icon-notice.png) **须知:** - >对于指定了INTERVAL子句的语法格式,范围分区策略的分区键仅支持1列。 - - 该情形下,分区键支持的数据类型为:TIMESTAMP\[\(p\)\] \[WITHOUT TIME ZONE\]、TIMESTAMP\[\(p\)\] \[WITH TIME ZONE\]、DATE。 - -- **PARTITION partition\_name VALUES LESS THAN \{\( \{ partition\_value | MAXVALUE \} \[,...\] \) | MAXVALUE \}** - - 指定各分区的信息。partition\_name为范围分区的名称。partition\_value为范围分区的上边界,取值依赖于partition\_key的类型。MAXVALUE表示分区的上边界,它通常用于设置最后一个范围分区的上边界。 - - >![](public_sys-resources/icon-notice.png) **须知:** - > - >- 每个分区都需要指定一个上边界。 - - >- 分区上边界的类型应当和分区键的类型一致。 - - >- 分区列表是按照分区上边界升序排列的,值较小的分区位于值较大的分区之前。 - >- 不在括号内的MAVALUE只能在sql\_compatibility='B'时使用,并且只能有一个分区键。 - -- **PARTITION partition\_name \{START \(partition\_value\) END \(partition\_value\) EVERY \(interval\_value\)\} | \{START \(partition\_value\) END \(partition\_value|MAXVALUE\)\} | \{START\(partition\_value\)\} | \{END \(partition\_value | MAXVALUE\)\}** - - 指定各分区的信息,各参数意义如下: - - - partition\_name:范围分区的名称或名称前缀,除以下情形外(假定其中的partition\_name是p1),均为分区的名称。 - - 若该定义是START+END+EVERY从句,则语义上定义的分区的名称依次为p1\_1, p1\_2, ...。例如对于定义“PARTITION p1 START\(1\) END\(4\) EVERY\(1\)”,则生成的分区是:\[1, 2\), \[2, 3\) 和 \[3, 4\),名称依次为p1\_1, p1\_2和p1\_3,即此处的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。 - - interval\_value:对\[START,END\) 表示的范围进行切分,interval\_value是指定切分后每个分区的宽度,不可是MAXVALUE;如果(END-START)值不能整除以EVERY值,则仅最后一个分区的宽度小于EVERY值。 - - MAXVALUE:表示最大值,它通常用于设置最后一个范围分区的上边界。 - - >![](public_sys-resources/icon-notice.png) **须知:** - > - >1. 在创建分区表若第一个分区定义含START值,则范围(MINVALUE,START)将自动作为实际的第一个分区。 - >2. START END语法需要遵循以下限制: - > - 每个partition\_start\_end\_item中的START值(如果有的话,下同)必须小于其END值。 - - > - 相邻的两个partition\_start\_end\_item,第一个的END值必须等于第二个的START值; - - > - 每个partition\_start\_end\_item中的EVERY值必须是正向递增的,且必须小于(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语法格式。 - -- **INTERVAL \('interval\_expr'\) \[ STORE IN \(tablespace\_name \[, ... \] \) \]** - - 间隔分区定义信息。 - - - interval\_expr:自动创建分区的间隔,例如:1 day、1 month。 - - - STORE IN \(tablespace\_name \[, ... \] \):指定存放自动创建分区的表空间列表,如果有指定,则自动创建的分区从表空间列表中循环选择使用,否则使用分区表默认的表空间。 - - >![](public_sys-resources/icon-notice.png) **须知:** - > - >列存表不支持间隔分区。 - -- **PARTITION BY LIST \[COLUMNS\] \(partition\_key\)** - - 创建列表分区。partition\_key为分区键的名称。 - - COLUMNS关键字只能在sql\_compatibility='B'时使用,“PARTITION BY LIST COLUMNS” 语义同 “PARTITION BY LIST”。 - - - 对于partition\_key,列表分区策略的分区键最多支持16列。 - - 对于从句是VALUES \[IN\] \(list\_values\)的语法格式,list\_values中包含了对应分区存在的键值,每个分区的键值数量不超过64个。 - - 从句"VALUES IN"只能在sql\_compatibility='B'时使用,语义同"VALUES"。 - - 分区键支持的数据类型为:INT1、INT2、INT4、INT8、NUMERIC、VARCHAR\(n\)、CHAR、BPCHAR、NVARCHAR、NVARCHAR2、TIMESTAMP\[\(p\)\] \[WITHOUT TIME ZONE\]、TIMESTAMP\[\(p\)\] \[WITH TIME ZONE\]、DATE。分区个数不能超过1048575个。 - -- **PARTITION BY HASH\(partition\_key\)** - - 创建哈希分区。partition\_key为分区键的名称。 - - 对于partition\_key,哈希分区策略的分区键仅支持1列。 - - 分区键支持的数据类型为:INT1、INT2、INT4、INT8、NUMERIC、VARCHAR\(n\)、CHAR、BPCHAR、TEXT、NVARCHAR、NVARCHAR2、TIMESTAMP\[\(p\)\] \[WITHOUT TIME ZONE\]、TIMESTAMP\[\(p\)\] \[WITH TIME ZONE\]、DATE。分区个数不能超过1048575 个。 - -- **PARTITION BY KEY\(partition\_key\)** - - 只能在sql\_compatibility='B'时使用,语义同“PARTITION BY HASH\(partition\_key\)”。 - -- **PARTITIONS integer** - - 指定分区个数。 - - integer为分区数,必须为大于0的整数,且不得大于1048575。 - - - 当在RANGE和LIST分区后指定此子句时,必须显式定义每个分区,且定义分区的数量必须与integer值相等。只能在sql\_compatibility='B'时在RANGE和LIST分区后指定此子句。 - - 当在HASH和KEY分区后指定此子句时,若不列出各个分区定义,将自动生成integer个分区,自动生成的分区名为“p+数字”,数字依次为0到integer-1,分区的表空间默认为此表的表空间;也可以显式列出每个分区定义,此时定义分区的数量必须与integer值相等。若既不列出分区定义,也不指定分区数量,将创建唯一一个分区。 - -- **\{ ENABLE | DISABLE \} ROW MOVEMENT** - - 行迁移开关。 - - 如果进行UPDATE操作时,更新了元组在分区键上的值,造成了该元组所在分区发生变化,就会根据该开关给出报错信息,或者进行元组在分区间的转移。 - - 取值范围: - - - ENABLE(缺省值):行迁移开关打开。 - - DISABLE:行迁移开关关闭。 - -- **NOT NULL** - - 字段值不允许为NULL。ENABLE用于语法兼容,可省略。 - -- **NULL** - - 字段值允许NULL ,这是缺省。 - - 这个子句只是为和非标准SQL数据库兼容。不建议使用。 - -- **CHECK \(condition\) \[ NO INHERIT \]** - - CHECK约束声明一个布尔表达式,每次要插入的新行或者要更新的行的新值必须使表达式结果为真或未知才能成功,否则会抛出一个异常并且不会修改数据库。 - - 声明为字段约束的检查约束应该只引用该字段的数值,而在表约束里出现的表达式可以引用多个字段。 - - 用NO INHERIT标记的约束将不会传递到子表中去。 - - ENABLE用于语法兼容,可省略。 - -- **DEFAULT default\_expr** - - DEFAULT子句给字段指定缺省值。该数值可以是任何不含变量的表达式\(不允许使用子查询和对本表中的其他字段的交叉引用\)。缺省表达式的数据类型必须和字段类型匹配。 - - 缺省表达式将被用于任何未声明该字段数值的插入操作。如果没有指定缺省值则缺省值为NULL 。 - -- **GENERATED ALWAYS AS \( generation\_expr \) \[STORED\]** - - 该子句将字段创建为生成列,生成列的值在写入(插入或更新)数据时由generation\_expr计算得到,STORED表示像普通列一样存储生成列的值。 - - >![](public_sys-resources/icon-note.png) **说明:** - > - >- STORED关键字可省略,与不省略STORED语义相同。 - >- 生成表达式不能以任何方式引用当前行以外的其他数据。生成表达式不能引用其他生成列,不能引用系统列。生成表达式不能返回结果集,不能使用子查询,不能使用聚集函数,不能使用窗口函数。生成表达式调用的函数只能是不可变(IMMUTABLE)函数。 - >- 不能为生成列指定默认值。 - >- 生成列不能作为分区键的一部分。 - >- 生成列不能和ON UPDATE约束字句的CASCADE,SET NULL,SET DEFAULT动作同时指定。生成列不能和ON DELETE约束字句的SET NULL、SET DEFAULT动作同时指定。 - >- 修改和删除生成列的方法和普通列相同。删除生成列依赖的普通列,生成列被自动删除。不能改变生成列所依赖的列的类型。 - >- 生成列不能被直接写入。在INSERT或UPDATE命令中, 不能为生成列指定值, 但是可以指定关键字DEFAULT。 - >- 生成列的权限控制和普通列一样。 - >- 列存表、内存表MOT不支持生成列。外表中仅postgres\_fdw支持生成列。 - -- **AUTO\_INCREMENT** - - 指定列为自动增长列。 - - 详见:[AUTO\_INCREMENT](CREATE-TABLE.md)。 - -- **UNIQUE \[KEY\] index\_parameters** - - **UNIQUE \( column\_name \[, ... \] \) index\_parameters** - - UNIQUE约束表示表里的一个字段或多个字段的组合必须在全表范围内唯一。 - - 对于唯一约束,NULL被认为是互不相等的。 - - UNIQUE KEY只能在sql\_compatibility='B'时使用,与UNIQUE语义相同。 - -- **PRIMARY KEY index\_parameters** - - **PRIMARY KEY \( column\_name \[, ... \] \) index\_parameters** - - 主键约束声明表中的一个或者多个字段只能包含唯一的非NULL值。 - - 一个表只能声明一个主键。 - -- **DEFERRABLE | NOT DEFERRABLE** - - 这两个关键字设置该约束是否可推迟。一个不可推迟的约束将在每条命令之后马上检查。可推迟约束可以推迟到事务结尾使用SET CONSTRAINTS命令检查。缺省是NOT DEFERRABLE。目前,UNIQUE约束、主键约束、外键约束可以接受这个子句。所有其他约束类型都是不可推迟的。 - -- **INITIALLY IMMEDIATE | INITIALLY DEFERRED** - - 如果约束是可推迟的,则这个子句声明检查约束的缺省时间。 - - - 如果约束是INITIALLY IMMEDIATE(缺省),则在每条语句执行之后就立即检查它; - - 如果约束是INITIALLY DEFERRED ,则只有在事务结尾才检查它。 - - 约束检查的时间可以用SET CONSTRAINTS命令修改。 - -- **USING INDEX TABLESPACE tablespace\_name** - - 为UNIQUE或PRIMARY KEY约束相关的索引声明一个表空间。如果没有提供这个子句,这个索引将在default\_tablespace中创建,如果default\_tablespace为空,将使用数据库的缺省表空间。 - - -## 示例 - -- 示例1:创建范围分区表tpcds.web\_returns\_p1,含有8个分区,分区键为integer类型。 分区的范围分别为:wr\_returned\_date\_sk< 2450815、2450815<= wr\_returned\_date\_sk< 2451179、2451179<=wr\_returned\_date\_sk< 2451544、2451544 <= wr\_returned\_date\_sk< 2451910、2451910 <= wr\_returned\_date\_sk< 2452275、2452275 <= wr\_returned\_date\_sk< 2452640、2452640 <= wr\_returned\_date\_sk< 2453005、wr\_returned\_date\_sk\>=2453005。 - - ``` - --创建表tpcds.web_returns。 - openGauss=# CREATE TABLE tpcds.web_returns - ( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) - ); - --创建分区表tpcds.web_returns_p1。 - openGauss=# CREATE TABLE tpcds.web_returns_p1 - ( - WR_RETURNED_DATE_SK INTEGER , - WR_RETURNED_TIME_SK INTEGER , - WR_ITEM_SK INTEGER NOT NULL, - WR_REFUNDED_CUSTOMER_SK INTEGER , - WR_REFUNDED_CDEMO_SK INTEGER , - WR_REFUNDED_HDEMO_SK INTEGER , - WR_REFUNDED_ADDR_SK INTEGER , - WR_RETURNING_CUSTOMER_SK INTEGER , - WR_RETURNING_CDEMO_SK INTEGER , - WR_RETURNING_HDEMO_SK INTEGER , - WR_RETURNING_ADDR_SK INTEGER , - WR_WEB_PAGE_SK INTEGER , - WR_REASON_SK INTEGER , - WR_ORDER_NUMBER BIGINT NOT NULL, - WR_RETURN_QUANTITY INTEGER , - WR_RETURN_AMT DECIMAL(7,2) , - WR_RETURN_TAX DECIMAL(7,2) , - WR_RETURN_AMT_INC_TAX DECIMAL(7,2) , - WR_FEE DECIMAL(7,2) , - WR_RETURN_SHIP_COST DECIMAL(7,2) , - WR_REFUNDED_CASH DECIMAL(7,2) , - WR_REVERSED_CHARGE DECIMAL(7,2) , - WR_ACCOUNT_CREDIT DECIMAL(7,2) , - WR_NET_LOSS DECIMAL(7,2) - ) - WITH (ORIENTATION = COLUMN,COMPRESSION=MIDDLE) - PARTITION BY RANGE(WR_RETURNED_DATE_SK) - ( - PARTITION P1 VALUES LESS THAN(2450815), - PARTITION P2 VALUES LESS THAN(2451179), - PARTITION P3 VALUES LESS THAN(2451544), - PARTITION P4 VALUES LESS THAN(2451910), - PARTITION P5 VALUES LESS THAN(2452275), - PARTITION P6 VALUES LESS THAN(2452640), - PARTITION P7 VALUES LESS THAN(2453005), - PARTITION P8 VALUES LESS THAN(MAXVALUE) - ); - - --从示例数据表导入数据。 - openGauss=# INSERT INTO tpcds.web_returns_p1 SELECT * FROM tpcds.web_returns; - - --删除分区P8。 - openGauss=# ALTER TABLE tpcds.web_returns_p1 DROP PARTITION P8; - - --增加分区WR_RETURNED_DATE_SK介于2453005和2453105之间。 - openGauss=# ALTER TABLE tpcds.web_returns_p1 ADD PARTITION P8 VALUES LESS THAN (2453105); - - --增加分区WR_RETURNED_DATE_SK介于2453105和MAXVALUE之间。 - openGauss=# ALTER TABLE tpcds.web_returns_p1 ADD PARTITION P9 VALUES LESS THAN (MAXVALUE); - - --删除分区P8。 - openGauss=# ALTER TABLE tpcds.web_returns_p1 DROP PARTITION FOR (2453005); - - --分区P7重命名为P10。 - openGauss=# ALTER TABLE tpcds.web_returns_p1 RENAME PARTITION P7 TO P10; - - --分区P6重命名为P11。 - openGauss=# ALTER TABLE tpcds.web_returns_p1 RENAME PARTITION FOR (2452639) TO P11; - - --查询分区P10的行数。 - openGauss=# SELECT count(*) FROM tpcds.web_returns_p1 PARTITION (P10); - count - -------- - 0 - (1 row) - - --查询分区P1的行数。 - openGauss=# SELECT COUNT(*) FROM tpcds.web_returns_p1 PARTITION FOR (2450815); - count - -------- - 0 - (1 row) - ``` - -- 示例2:创建范围分区表tpcds.web\_returns\_p2,含有8个分区,分区键类型为integer类型,其中第8个分区上边界为MAXVALUE。 - - 八个分区的范围分别为: wr\_returned\_date\_sk< 2450815、2450815<= wr\_returned\_date\_sk< 2451179、2451179<=wr\_returned\_date\_sk< 2451544、2451544 <= wr\_returned\_date\_sk< 2451910、2451910 <= wr\_returned\_date\_sk< 2452275、2452275 <= wr\_returned\_date\_sk< 2452640、2452640 <= wr\_returned\_date\_sk< 2453005、wr\_returned\_date\_sk\>=2453005。 - - 分区表tpcds.web\_returns\_p2的表空间为example1;分区P1到P7没有声明表空间,使用采用分区表tpcds.web\_returns\_p2的表空间example1;指定分区P8的表空间为example2。 - - 假定数据库节点的数据目录/pg\_location/mount1/path1,数据库节点的数据目录/pg\_location/mount2/path2,数据库节点的数据目录/pg\_location/mount3/path3,数据库节点的数据目录/pg\_location/mount4/path4是dwsadmin用户拥有读写权限的空目录。 - - ``` - openGauss=# CREATE TABLESPACE example1 RELATIVE LOCATION 'tablespace1/tablespace_1'; - openGauss=# CREATE TABLESPACE example2 RELATIVE LOCATION 'tablespace2/tablespace_2'; - openGauss=# CREATE TABLESPACE example3 RELATIVE LOCATION 'tablespace3/tablespace_3'; - openGauss=# CREATE TABLESPACE example4 RELATIVE LOCATION 'tablespace4/tablespace_4'; - - openGauss=# CREATE TABLE tpcds.web_returns_p2 - ( - WR_RETURNED_DATE_SK INTEGER , - WR_RETURNED_TIME_SK INTEGER , - WR_ITEM_SK INTEGER NOT NULL, - WR_REFUNDED_CUSTOMER_SK INTEGER , - WR_REFUNDED_CDEMO_SK INTEGER , - WR_REFUNDED_HDEMO_SK INTEGER , - WR_REFUNDED_ADDR_SK INTEGER , - WR_RETURNING_CUSTOMER_SK INTEGER , - WR_RETURNING_CDEMO_SK INTEGER , - WR_RETURNING_HDEMO_SK INTEGER , - WR_RETURNING_ADDR_SK INTEGER , - WR_WEB_PAGE_SK INTEGER , - WR_REASON_SK INTEGER , - WR_ORDER_NUMBER BIGINT NOT NULL, - WR_RETURN_QUANTITY INTEGER , - WR_RETURN_AMT DECIMAL(7,2) , - WR_RETURN_TAX DECIMAL(7,2) , - WR_RETURN_AMT_INC_TAX DECIMAL(7,2) , - WR_FEE DECIMAL(7,2) , - WR_RETURN_SHIP_COST DECIMAL(7,2) , - WR_REFUNDED_CASH DECIMAL(7,2) , - WR_REVERSED_CHARGE DECIMAL(7,2) , - WR_ACCOUNT_CREDIT DECIMAL(7,2) , - WR_NET_LOSS DECIMAL(7,2) - ) - TABLESPACE example1 - PARTITION BY RANGE(WR_RETURNED_DATE_SK) - ( - PARTITION P1 VALUES LESS THAN(2450815), - PARTITION P2 VALUES LESS THAN(2451179), - PARTITION P3 VALUES LESS THAN(2451544), - PARTITION P4 VALUES LESS THAN(2451910), - PARTITION P5 VALUES LESS THAN(2452275), - PARTITION P6 VALUES LESS THAN(2452640), - PARTITION P7 VALUES LESS THAN(2453005), - PARTITION P8 VALUES LESS THAN(MAXVALUE) TABLESPACE example2 - ) - ENABLE ROW MOVEMENT; - - --以like方式创建一个分区表。 - openGauss=# CREATE TABLE tpcds.web_returns_p3 (LIKE tpcds.web_returns_p2 INCLUDING PARTITION); - - --修改分区P1的表空间为example2。 - openGauss=# ALTER TABLE tpcds.web_returns_p2 MOVE PARTITION P1 TABLESPACE example2; - - --修改分区P2的表空间为example3。 - openGauss=# ALTER TABLE tpcds.web_returns_p2 MOVE PARTITION P2 TABLESPACE example3; - - --以2453010为分割点切分P8。 - openGauss=# ALTER TABLE tpcds.web_returns_p2 SPLIT PARTITION P8 AT (2453010) INTO - ( - PARTITION P9, - PARTITION P10 - ); - - --将P6,P7合并为一个分区。 - openGauss=# ALTER TABLE tpcds.web_returns_p2 MERGE PARTITIONS P6, P7 INTO PARTITION P8; - - --修改分区表迁移属性。 - openGauss=# ALTER TABLE tpcds.web_returns_p2 DISABLE ROW MOVEMENT; - --删除表和表空间。 - openGauss=# DROP TABLE tpcds.web_returns_p1; - openGauss=# DROP TABLE tpcds.web_returns_p2; - openGauss=# DROP TABLE tpcds.web_returns_p3; - openGauss=# DROP TABLESPACE example1; - openGauss=# DROP TABLESPACE example2; - openGauss=# DROP TABLESPACE example3; - openGauss=# DROP TABLESPACE example4; - ``` - - -- 示例3:START END语法创建、修改Range分区表。 - - 假定/home/omm/startend\_tbs1、/home/omm/startend\_tbs2、/home/omm/startend\_tbs3、/home/omm/startend\_tbs4是omm用户拥有读写权限的空目录。 - - ``` - -- 创建表空间 - openGauss=# CREATE TABLESPACE startend_tbs1 LOCATION '/home/omm/startend_tbs1'; - openGauss=# CREATE TABLESPACE startend_tbs2 LOCATION '/home/omm/startend_tbs2'; - openGauss=# CREATE TABLESPACE startend_tbs3 LOCATION '/home/omm/startend_tbs3'; - openGauss=# CREATE TABLESPACE startend_tbs4 LOCATION '/home/omm/startend_tbs4'; - - -- 创建临时schema - openGauss=# CREATE SCHEMA tpcds; - openGauss=# SET CURRENT_SCHEMA TO tpcds; - - -- 创建分区表,分区键是integer类型 - openGauss=# CREATE TABLE tpcds.startend_pt (c1 INT, c2 INT) - TABLESPACE startend_tbs1 - PARTITION BY RANGE (c2) ( - PARTITION p1 START(1) END(1000) EVERY(200) TABLESPACE startend_tbs2, - PARTITION p2 END(2000), - PARTITION p3 START(2000) END(2500) TABLESPACE startend_tbs3, - PARTITION p4 START(2500), - PARTITION p5 START(3000) END(5000) EVERY(1000) TABLESPACE startend_tbs4 - ) - ENABLE ROW MOVEMENT; - - -- 查看分区表信息 - openGauss=# SELECT relname, boundaries, spcname FROM pg_partition p JOIN pg_tablespace t ON p.reltablespace=t.oid and p.parentid='tpcds.startend_pt'::regclass ORDER BY 1; - relname | boundaries | spcname - -------------+------------+--------------- - p1_0 | {1} | startend_tbs2 - p1_1 | {201} | startend_tbs2 - p1_2 | {401} | startend_tbs2 - p1_3 | {601} | startend_tbs2 - p1_4 | {801} | startend_tbs2 - p1_5 | {1000} | startend_tbs2 - p2 | {2000} | startend_tbs1 - p3 | {2500} | startend_tbs3 - p4 | {3000} | startend_tbs1 - p5_1 | {4000} | startend_tbs4 - p5_2 | {5000} | startend_tbs4 - startend_pt | | startend_tbs1 - (12 rows) - - -- 导入数据,查看分区数据量 - openGauss=# INSERT INTO tpcds.startend_pt VALUES (GENERATE_SERIES(0, 4999), GENERATE_SERIES(0, 4999)); - openGauss=# SELECT COUNT(*) FROM tpcds.startend_pt PARTITION FOR (0); - count - ------- - 1 - (1 row) - - openGauss=# SELECT COUNT(*) FROM tpcds.startend_pt PARTITION (p3); - count - ------- - 500 - (1 row) - - -- 增加分区: [5000, 5300), [5300, 5600), [5600, 5900), [5900, 6000) - openGauss=# ALTER TABLE tpcds.startend_pt ADD PARTITION p6 START(5000) END(6000) EVERY(300) TABLESPACE startend_tbs4; - - -- 增加MAXVALUE分区: p7 - openGauss=# ALTER TABLE tpcds.startend_pt ADD PARTITION p7 END(MAXVALUE); - - -- 重命名分区p7为p8 - openGauss=# ALTER TABLE tpcds.startend_pt RENAME PARTITION p7 TO p8; - - -- 删除分区p8 - openGauss=# ALTER TABLE tpcds.startend_pt DROP PARTITION p8; - - -- 重命名5950所在的分区为:p71 - openGauss=# ALTER TABLE tpcds.startend_pt RENAME PARTITION FOR(5950) TO p71; - - -- 分裂4500所在的分区[4000, 5000) - openGauss=# ALTER TABLE tpcds.startend_pt SPLIT PARTITION FOR(4500) INTO(PARTITION q1 START(4000) END(5000) EVERY(250) TABLESPACE startend_tbs3); - - -- 修改分区p2的表空间为startend_tbs4 - openGauss=# ALTER TABLE tpcds.startend_pt MOVE PARTITION p2 TABLESPACE startend_tbs4; - - -- 查看分区情形 - openGauss=# SELECT relname, boundaries, spcname FROM pg_partition p JOIN pg_tablespace t ON p.reltablespace=t.oid and p.parentid='tpcds.startend_pt'::regclass ORDER BY 1; - relname | boundaries | spcname - -------------+------------+--------------- - p1_0 | {1} | startend_tbs2 - p1_1 | {201} | startend_tbs2 - p1_2 | {401} | startend_tbs2 - p1_3 | {601} | startend_tbs2 - p1_4 | {801} | startend_tbs2 - p1_5 | {1000} | startend_tbs2 - p2 | {2000} | startend_tbs4 - p3 | {2500} | startend_tbs3 - p4 | {3000} | startend_tbs1 - p5_1 | {4000} | startend_tbs4 - p6_1 | {5300} | startend_tbs4 - p6_2 | {5600} | startend_tbs4 - p6_3 | {5900} | startend_tbs4 - p71 | {6000} | startend_tbs4 - q1_1 | {4250} | startend_tbs3 - q1_2 | {4500} | startend_tbs3 - q1_3 | {4750} | startend_tbs3 - q1_4 | {5000} | startend_tbs3 - startend_pt | | startend_tbs1 - (19 rows) - - -- 删除表和表空间 - openGauss=# DROP SCHEMA tpcds CASCADE; - openGauss=# DROP TABLESPACE startend_tbs1; - openGauss=# DROP TABLESPACE startend_tbs2; - openGauss=# DROP TABLESPACE startend_tbs3; - openGauss=# DROP TABLESPACE startend_tbs4; - ``` - - -- 示例4:创建间隔分区表sales,初始包含2个分区,分区键为DATE类型。 分区的范围分别为:time\_id < '2019-02-01 00:00:00'、 - - '2019-02-01 00:00:00' <= time\_id < '2019-02-02 00:00:00' 。 - - ``` - --创建表sales - openGauss=# CREATE TABLE sales - (prod_id NUMBER(6), - cust_id NUMBER, - time_id DATE, - channel_id CHAR(1), - promo_id NUMBER(6), - quantity_sold NUMBER(3), - amount_sold NUMBER(10,2) - ) - PARTITION BY RANGE (time_id) - INTERVAL('1 day') - ( PARTITION p1 VALUES LESS THAN ('2019-02-01 00:00:00'), - PARTITION p2 VALUES LESS THAN ('2019-02-02 00:00:00') - ); - - -- 数据插入分区p1 - openGauss=# INSERT INTO sales VALUES(1, 12, '2019-01-10 00:00:00', 'a', 1, 1, 1); - - -- 数据插入分区p2 - openGauss=# INSERT INTO sales VALUES(1, 12, '2019-02-01 00:00:00', 'a', 1, 1, 1); - - -- 查看分区信息 - openGauss=# SELECT t1.relname, partstrategy, boundaries FROM pg_partition t1, pg_class t2 WHERE t1.parentid = t2.oid AND t2.relname = 'sales' AND t1.parttype = 'p'; - relname | partstrategy | boundaries - ---------+--------------+------------------------- - p1 | r | {"2019-02-01 00:00:00"} - p2 | r | {"2019-02-02 00:00:00"} - (2 rows) - - -- 插入数据没有匹配的分区,新创建一个分区,并将数据插入该分区 - -- 新分区的范围为 '2019-02-05 00:00:00' <= time_id < '2019-02-06 00:00:00' - openGauss=# INSERT INTO sales VALUES(1, 12, '2019-02-05 00:00:00', 'a', 1, 1, 1); - - -- 插入数据没有匹配的分区,新创建一个分区,并将数据插入该分区 - -- 新分区的范围为 '2019-02-03 00:00:00' <= time_id < '2019-02-04 00:00:00' - openGauss=# INSERT INTO sales VALUES(1, 12, '2019-02-03 00:00:00', 'a', 1, 1, 1); - - -- 查看分区信息 - openGauss=# SELECT t1.relname, partstrategy, boundaries FROM pg_partition t1, pg_class t2 WHERE t1.parentid = t2.oid AND t2.relname = 'sales' AND t1.parttype = 'p'; - relname | partstrategy | boundaries - ---------+--------------+------------------------- - sys_p1 | i | {"2019-02-06 00:00:00"} - sys_p2 | i | {"2019-02-04 00:00:00"} - p1 | r | {"2019-02-01 00:00:00"} - p2 | r | {"2019-02-02 00:00:00"} - (4 rows) - - ``` - - -- 示例5:创建LIST分区表test\_list,初始包含4个分区,分区键为INT类型。4个分区的范围分别为:2000、3000、4000、5000。 - - ``` - --创建表test_list - openGauss=# create table test_list (col1 int, col2 int) - partition by list(col1) - ( - partition p1 values (2000), - partition p2 values (3000), - partition p3 values (4000), - partition p4 values (5000) - ); - - -- 数据插入 - openGauss=# INSERT INTO test_list VALUES(2000, 2000); - INSERT 0 1 - openGauss=# INSERT INTO test_list VALUES(3000, 3000); - INSERT 0 1 - - -- 查看分区信息 - openGauss=# SELECT t1.relname, partstrategy, boundaries FROM pg_partition t1, pg_class t2 WHERE t1.parentid = t2.oid AND t2.relname = 'test_list' AND t1.parttype = 'p'; - relname | partstrategy | boundaries - ---------+--------------+------------ - p1 | l | {2000} - p2 | l | {3000} - p3 | l | {4000} - p4 | l | {5000} - (4 rows) - - -- 插入数据没有匹配到分区,报错处理 - openGauss=# INSERT INTO test_list VALUES(6000, 6000); - ERROR: inserted partition key does not map to any table partition - - -- 添加分区 - openGauss=# alter table test_list add partition p5 values (6000); - ALTER TABLE - openGauss=# SELECT t1.relname, partstrategy, boundaries FROM pg_partition t1, pg_class t2 WHERE t1.parentid = t2.oid AND t2.relname = 'test_list' AND t1.parttype = 'p'; - relname | partstrategy | boundaries - ---------+--------------+------------ - p5 | l | {6000} - p4 | l | {5000} - p1 | l | {2000} - p2 | l | {3000} - p3 | l | {4000} - (5 rows) - openGauss=# INSERT INTO test_list VALUES(6000, 6000); - INSERT 0 1 - - -- 分区表和普通表交换数据 - openGauss=# create table t1 (col1 int, col2 int); - CREATE TABLE - openGauss=# select * from test_list partition (p1); - col1 | col2 - ------+------ - 2000 | 2000 - (1 row) - openGauss=# alter table test_list exchange partition (p1) with table t1; - ALTER TABLE - openGauss=# select * from test_list partition (p1); - col1 | col2 - ------+------ - (0 rows) - openGauss=# select * from t1; - col1 | col2 - ------+------ - 2000 | 2000 - (1 row) - - -- truncate分区 - openGauss=# select * from test_list partition (p2); - col1 | col2 - ------+------ - 3000 | 3000 - (1 row) - openGauss=# alter table test_list truncate partition p2; - ALTER TABLE - openGauss=# select * from test_list partition (p2); - col1 | col2 - ------+------ - (0 rows) - - -- 删除分区 - openGauss=# alter table test_list drop partition p5; - ALTER TABLE - openGauss=# SELECT t1.relname, partstrategy, boundaries FROM pg_partition t1, pg_class t2 WHERE t1.parentid = t2.oid AND t2.relname = 'test_list' AND t1.parttype = 'p'; - relname | partstrategy | boundaries - ---------+--------------+------------ - p4 | l | {5000} - p1 | l | {2000} - p2 | l | {3000} - p3 | l | {4000} - (4 rows) - - openGauss=# INSERT INTO test_list VALUES(6000, 6000); - ERROR: inserted partition key does not map to any table partition - - -- 删除分区表 - openGauss=# drop table test_list; - ``` - - -- 示例6:创建HASH分区表test\_hash,初始包含2个分区,分区键为INT类型。 - - ``` - --创建表test_hash - openGauss=# create table test_hash (col1 int, col2 int) - partition by hash(col1) - ( - partition p1, - partition p2 - ); - - -- 数据插入 - openGauss=# INSERT INTO test_hash VALUES(1, 1); - INSERT 0 1 - openGauss=# INSERT INTO test_hash VALUES(2, 2); - INSERT 0 1 - openGauss=# INSERT INTO test_hash VALUES(3, 3); - INSERT 0 1 - openGauss=# INSERT INTO test_hash VALUES(4, 4); - INSERT 0 1 - - -- 查看分区信息 - openGauss=# SELECT t1.relname, partstrategy, boundaries FROM pg_partition t1, pg_class t2 WHERE t1.parentid = t2.oid AND t2.relname = 'test_hash' AND t1.parttype = 'p'; - relname | partstrategy | boundaries - ---------+--------------+------------ - p1 | h | {0} - p2 | h | {1} - (2 rows) - - -- 查看数据 - openGauss=# select * from test_hash partition (p1); - col1 | col2 - ------+------ - 3 | 3 - 4 | 4 - (2 rows) - - openGauss=# select * from test_hash partition (p2); - col1 | col2 - ------+------ - 1 | 1 - 2 | 2 - (2 rows) - - -- 分区表和普通表交换数据 - openGauss=# create table t1 (col1 int, col2 int); - CREATE TABLE - openGauss=# alter table test_hash exchange partition (p1) with table t1; - ALTER TABLE - openGauss=# select * from test_hash partition (p1); - col1 | col2 - ------+------ - (0 rows) - openGauss=# select * from t1; - col1 | col2 - ------+------ - 3 | 3 - 4 | 4 - (2 rows) - - -- truncate分区 - openGauss=# alter table test_hash truncate partition p2; - ALTER TABLE - openGauss=# select * from test_hash partition (p2); - col1 | col2 - ------+------ - (0 rows) - - -- 删除分区表 - openGauss=# drop table test_hash; - ``` - -+ 示例7:创建LIST分区表t\_multi\_keys\_list,初始包含5个分区,两个分区键分别为INT类型和VARCHAR类型。 - - ``` - --创建表t_multi_keys_list - openGauss=# CREATE TABLE t_multi_keys_list (a int, b varchar(4), c int) - PARTITION BY LIST (a,b) - ( - PARTITION p1 VALUES ( (0,NULL) ), - PARTITION p2 VALUES ( (0,'1'), (0,'2'), (0,'3'), (1,'1'), (1,'2') ), - PARTITION p3 VALUES ( (NULL,'0'), (2,'1') ), - PARTITION p4 VALUES ( (3,'2'), (NULL,NULL) ), - PARTITION pd VALUES ( DEFAULT ) - ); - ``` - - - -## 相关链接 - -[ALTER TABLE PARTITION](ALTER-TABLE-PARTITION.md),[DROP TABLE](DROP-TABLE.md) - +# CREATE TABLE PARTITION + +## 功能描述 + +创建分区表。分区表是把逻辑上的一张表根据某种方案分成几张物理块进行存储,这张逻辑上的表称之为分区表,物理块称之为分区。分区表是一张逻辑表,不存储数据,数据实际是存储在分区上的。 + +常见的分区方案有范围分区(Range Partitioning)、间隔分区(Interval Partitioning)、哈希分区(Hash Partitioning)、列表分区(List Partitioning)、数值分区(Value Partition)等。目前行存表支持范围分区、间隔分区、哈希分区、列表分区,列存表仅支持范围分区。 + +范围分区是根据表的一列或者多列,将要插入表的记录分为若干个范围,这些范围在不同的分区里没有重叠。为每个范围创建一个分区,用来存储相应的数据。 + +范围分区的分区策略是指记录插入分区的方式。目前范围分区仅支持范围分区策略。 + +范围分区策略:根据分区键值将记录映射到已创建的某个分区上,如果可以映射到已创建的某一分区上,则把记录插入到对应的分区上,否则给出报错和提示信息。这是最常用的分区策略。 + +间隔分区是一种特殊的范围分区,相比范围分区,新增间隔值定义,当插入记录找不到匹配的分区时,可以根据间隔值自动创建分区。 + +间隔分区只支持基于表的一列分区,并且该列只支持TIMESTAMP\[\(p\)\] \[WITHOUT TIME ZONE\]、TIMESTAMP\[\(p\)\] \[WITH TIME ZONE\]、DATE数据类型。 + +间隔分区策略:根据分区键值将记录映射到已创建的某个分区上,如果可以映射到已创建的某一分区上,则把记录插入到对应的分区上,否则根据分区键值和表定义信息自动创建一个分区,然后将记录插入新分区中,新创建的分区数据范围等于间隔值。 + +哈希分区是根据表的一列,为每个分区指定模数和余数,将要插入表的记录划分到对应的分区中,每个分区所持有的行都需要满足条件:分区键的值除以为其指定的模数将产生为其指定的余数。 + +哈希分区策略:根据分区键值将记录映射到已创建的某个分区上,如果可以映射到已创建的某一分区上,则把记录插入到对应的分区上,否则返回报错和提示信息。 + +列表分区是根据表的一列,将要插入表的记录通过每一个分区中出现的键值划分到对应的分区中,这些键值在不同的分区里没有重叠。为每组键值创建一个分区,用来存储相应的数据。 + +列表分区策略:根据分区键值将记录映射到已创建的某个分区上,如果可以映射到已创建的某一分区上,则把记录插入到对应的分区上,否则给出报错和提示信息。 + +分区可以提供若干好处: + +- 某些类型的查询性能可以得到极大提升。特别是表中访问率较高的行位于一个单独分区或少数几个分区上的情况下。分区可以减少数据的搜索空间,提高数据访问效率。 +- 当查询或更新一个分区的大部分记录时,连续扫描那个分区而不是访问整个表可以获得巨大的性能提升。 +- 如果需要大量加载或者删除的记录位于单独的分区上,则可以通过直接读取或删除那个分区以获得巨大的性能提升,同时还可以避免由于大量DELETE导致的VACUUM超载(哈希分区不支持删除分区)。 + +## 注意事项 + +- 唯一约束和主键约束的约束键包含所有分区键将为约束创建LOCAL索引,否则创建GLOBAL索引。 +- 目前哈希分区和列表分区仅支持单列构建分区键,暂不支持多列构建分区键。 +- 只需要有间隔分区表的INSERT权限,往该表INSERT数据时就可以自动创建分区。 +- 对于分区表PARTITION FOR \(values\)语法,values只能是常量。 +- 对于分区表PARTITION FOR \(values\)语法,values在需要数据类型转换时,建议使用强制类型转换,以防隐式类型转换结果与预期不符。 +- 分区数最大值为1048575个,一般情况下业务不可能创建这么多分区,这样会导致内存不足。应参照参数local\_syscache\_threshold的值合理创建分区,分区表使用内存大致为(分区数 \* 3 / 1024)MB。理论上分区占用内存不允许大于local\_syscache\_threshold的值,同时还需要预留部分空间以供其他功能使用。 +- 当分区数太多导致内存不足时,会间接导致性能急剧下降。 +- 指定分区语句目前不能走全局索引扫描。 +- 目前Hash分区是按倒序排列的,即通过哈希和取余计算后得到的分区下标与创建顺序相反,同样EXPLAIN计划显示的Selected Partitions的序号排序也与创建顺序相反。List分区是按分区数组的第一个元素排序的。 +- 支持使用表达式当作分区键,允许分区键使用算术运算符 "+"、"-"、"*"。 +- 只支持部分函数允许在分区键中使用,支持的函数为: ABS()、CEILING()。 +- 表达式用作分区键时,只支持设置一个partition key,且分区为range、hash和list分区,另外暂不支持列存表。 + +## 语法格式 + +``` +CREATE TABLE [ IF NOT EXISTS ] partition_table_name +( [ + { column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ] + | table_constraint + | LIKE source_table [ like_option [...] ] }[, ... ] +] ) + [ AUTO_INCREMENT [ = ] value ] + [ WITH ( {storage_parameter = value} [, ... ] ) ] + [ COMPRESS | NOCOMPRESS ] + [ TABLESPACE tablespace_name ] + [ COMMENT {=| } 'text' ] + PARTITION BY { + {RANGE [COLUMNS] (partition_key) [ INTERVAL ('interval_expr') [ STORE IN (tablespace_name [, ... ] ) ] ] [ PARTITIONS integer ] ( partition_less_than_item [, ... ] )} | + {RANGE [COLUMNS] (partition_key) [ INTERVAL ('interval_expr') [ STORE IN (tablespace_name [, ... ] ) ] ] [ PARTITIONS integer ] ( partition_start_end_item [, ... ] )} | + {LIST [COLUMNS] (partition_key) [ PARTITIONS integer ] ( PARTITION partition_name VALUES [IN] (list_values) [TABLESPACE [=] tablespace_name][, ... ])} | + {{ HASH | KEY } (partition_key) [ PARTITIONS integer ] ( PARTITION partition_name [TABLESPACE [=] tablespace_name][, ... ])} + {RANGE (partition_key) [ INTERVAL ('interval_expr') [ STORE IN (tablespace_name [, ... ] ) ] ] ( partition_less_than_item [COMMENT {=| } 'text'][...][, ... ] )} | + {RANGE (partition_key) [ INTERVAL ('interval_expr') [ STORE IN (tablespace_name [, ... ] ) ] ] ( partition_start_end_item [COMMENT {=| } 'text'][...][, ... ] )} | + {LIST | HASH (partition_key) (PARTITION partition_name [VALUES (list_values_clause)] opt_table_space [COMMENT {=| } 'text'][...])} + } [ { ENABLE | DISABLE } ROW MOVEMENT ]; +``` + +- 列约束column\_constraint: + + ``` + [ CONSTRAINT constraint_name ] + { NOT NULL | + NULL | + CHECK ( expression ) | + DEFAULT default_e xpr | + GENERATED ALWAYS AS ( generation_expr ) [STORED] | + AUTO_INCREMENT | + UNIQUE [KEY] 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 ] + [ COMMENT {=| } 'text' ] + ``` + +- 表约束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 | + FOREIGN KEY [ index_name ] ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] + [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] } + [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] + [ COMMENT {=| } 'text' ] + ``` + + +- like选项like\_option: + + ``` + { INCLUDING | EXCLUDING } { DEFAULTS | GENERATED | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | RELOPTIONS| ALL } + ``` + + +- 索引存储参数index\_parameters: + + ``` + [ WITH ( {storage_parameter = value} [, ... ] ) ] + [ USING INDEX TABLESPACE tablespace_name ] + ``` + + +- 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) EVERY (interval_value)} | + {START(partition_value) END ({partition_value | MAXVALUE})} | + {START(partition_value)} | + {END({partition_value | MAXVALUE})} + } [TABLESPACE [=] tablespace_name] + ``` + +- COMMENT {=| } 'text': + + 分区表的分区中,该字段无实际意义,仅作语法兼容。在数据库中使用该语法时会有告警提示。 + +## 参数说明 + +- **IF NOT EXISTS** + + 如果已经存在相同名称的表,不会抛出一个错误,而会发出一个通知,告知表关系已存在。 + +- **partition\_table\_name** + + 分区表的名称。 + + 取值范围:字符串,要符合标识符的命名规范。 + +- **column\_name** + + 新表中要创建的字段名。 + + 取值范围:字符串,要符合标识符的命名规范。 + +- **data\_type** + + 字段的数据类型。 + +- **COLLATE collation** + + COLLATE子句指定列的排序规则(该列必须是可排列的数据类型)。如果没有指定,则使用默认的排序规则。排序规则可以使用“select \* from pg\_collation;”命令从pg\_collation系统表中查询,默认的排序规则为查询结果中以default开始的行。 + +- **CONSTRAINT constraint\_name** + + 列约束或表约束的名称。可选的约束子句用于声明约束,新行或者更新的行必须满足这些约束才能成功插入或更新。 + + 定义约束有两种方法: + + - 列约束:作为一个列定义的一部分,仅影响该列。 + - 表约束:不和某个列绑在一起,可以作用于多个列。在B模式数据库下(即sql\_compatibility = 'B')constraint\_name为可选项,在其他模式数据库下,必须加上constraint\_name。 + +- **index\_name** + + 索引名。 + + >![](public_sys-resources/icon-notice.png) **须知:** + > + >- index\_name仅在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库下不支持。 + >- 对于外键约束,constraint\_name和index\_name同时指定时,索引名为constraint\_name。 + >- 对于唯一键约束,constraint\_name和index\_name同时指定时,索引名以index\_name。 + +- **USING method** + + 指定创建索引的方法。 + + 取值范围参考[参数说明](CREATE-INDEX.md)中的USING method。 + + >![](public_sys-resources/icon-notice.png) **须知:** + > + >- USING method仅在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库下不支持。 + >- 在B模式下,未指定USING method时,对于ASTORE的存储方式,默认索引方法为btree;对于USTORE的存储方式,默认索引方法为ubtree。 + +- **ASC | DESC** + + ASC表示指定按升序排序(默认)。DESC指定按降序排序。 + + >![](public_sys-resources/icon-notice.png) **须知:** + > + >ASC|DESC只在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库不支持。 + + +- **LIKE source\_table \[ like\_option ... \]** + + LIKE子句声明一个表,新表自动从这个表里面继承所有字段名及其数据类型和非空约束。 + + 和INHERITS不同,新表与原来的表之间在创建动作完毕之后是完全无关的。在源表做的任何修改都不会传播到新表中,并且也不可能在扫描源表的时候包含新表的数据。 + + - 字段缺省表达式只有在声明了INCLUDING DEFAULTS之后才会包含进来。缺省是不包含缺省表达式的,即新表中所有字段的缺省值都是NULL。 + - 如果指定了INCLUDING GENERATED,则源表列的生成表达式会复制到新表中。默认不复制生成表达式。 + - 非空约束将总是复制到新表中,CHECK约束则仅在指定了INCLUDING CONSTRAINTS的时候才复制,而其他类型的约束则永远也不会被复制。此规则同时适用于表约束和列约束。 + - 和INHERITS不同,被复制的列和约束并不使用相同的名称进行融合。如果明确的指定了相同的名称或者在另外一个LIKE子句中,将会报错。 + - 如果指定了INCLUDING INDEXES,则源表上的索引也将在新表上创建,默认不建立索引。 + - 如果指定了INCLUDING STORAGE,则源表列的STORAGE设置也将被拷贝,默认情况下不包含STORAGE设置。 + - 如果指定了INCLUDING COMMENTS,则源表列、约束和索引的注释也会被拷贝过来。默认情况下,不拷贝源表的注释。 + - 如果指定了INCLUDING RELOPTIONS,则源表的存储参数(即源表的WITH子句)也将拷贝至新表。默认情况下,不拷贝源表的存储参数。 + - INCLUDING ALL包含了INCLUDING DEFAULTS、INCLUDING CONSTRAINTS、INCLUDING INDEXES、INCLUDING STORAGE、INCLUDING COMMENTS、INCLUDING PARTITION和INCLUDING RELOPTIONS的内容。 + +- **AUTO\_INCREMENT \[ = \] value** + + 这个子句为自动增长列指定一个初始值,value必须为正整数,不得超过2127-1。 + + >![](public_sys-resources/icon-notice.png) **须知:** + > + >该子句仅在参数sql\_compatibility=B时有效。 + +- **WITH \( storage\_parameter \[= value\] \[, ... \] \)** + + 这个子句为表或索引指定一个可选的存储参数。参数的详细描述如下所示: + + - FILLFACTOR + + 一个表的填充因子(fillfactor)是一个介于10和100之间的百分数。100(完全填充)是默认值。如果指定了较小的填充因子,INSERT操作仅按照填充因子指定的百分率填充表页。每个页上的剩余空间将用于在该页上更新行,这就使得UPDATE有机会在同一页上放置同一条记录的新版本,这比把新版本放置在其他页上更有效。对于一个从不更新的表将填充因子设为100是最佳选择,但是对于频繁更新的表,选择较小的填充因子则更加合适。该参数对于列存表没有意义。 + + 取值范围:10\~100 + + - ORIENTATION + + 决定了表的数据的存储方式。 + + 取值范围: + + - COLUMN:表的数据将以列式存储。 + - ROW(缺省值):表的数据将以行式存储。 + + >![](public_sys-resources/icon-notice.png) **须知:** + > + >orientation不支持修改。 + + - COMPRESSTYPE + + 行存表参数,设置行存表压缩算法。1代表pglz算法(不推荐使用),2代表zstd算法,默认不压缩。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。(仅支持ASTORE和USTORE下的普通表和分区表) + 该特性在金融版本下不支持 + + 取值范围:0\~2,默认值为0。 + + - COMPRESS\_LEVEL + + 行存表参数,设置行存表压缩算法等级,仅当COMPRESSTYPE为2时生效。压缩等级越高,表的压缩效果越好,表的访问速度越慢。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + + 取值范围:-31\~31,默认值为0。 + + - COMPRESS\_CHUNK_SIZE + + 行存表参数,设置行存表压缩chunk块大小,仅当COMPRESSTYPE不为0时生效。chunk数据块越小,预期能达到的压缩效果越好,同时数据越离散,影响表的访问速度。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + 取值范围:与页面大小有关。在页面大小为8k场景,取值范围为:512、1024、2048、4096。 + + 默认值:4096 + + - COMPRESS_PREALLOC_CHUNKS + + 行存表参数,设置行存表压缩chunk块预分配数量。预分配数量越大,表的压缩率相对越差,离散度越小,访问性能越好。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + + 取值范围:0\~7,默认值为0。 + + - 当COMPRESS\_CHUNK_SIZE为512和1024时,支持预分配设置最大为7。 + - 当COMPRESS\_CHUNK_SIZE为2048时,支持预分配设置最大为3。 + - 当COMPRESS\_CHUNK_SIZE为4096时,支持预分配设置最大为1。 + + - COMPRESS_BYTE_CONVERT + + 行存表参数,设置行存表压缩字节转换预处理,仅当COMPRESSTYPE不为0时生效。在一些场景下可以提升压缩效果,同时会导致一定性能劣化。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + + 取值范围:布尔值,默认关闭。 + + - COMPRESS_DIFF_CONVERT + + 行存表参数,设置行存表压缩字节差分预处理。只能与compress_byte_convert一起使用。在一些场景下可以提升压缩效果,同时会导致一定性能劣化。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + + 取值范围:布尔值,默认关闭。 + + - STORAGE\_TYPE + + 指定存储引擎类型,该参数设置成功后就不再支持修改。 + + 取值范围: + + - USTORE,表示表支持Inplace-Update存储引擎。特别需要注意,使用USTORE表,必须要开启track\_counts和track\_activities参数,否则会引起空间膨胀。 + + - ASTORE,表示表支持Append-Only存储引擎。 + + 默认值: 不指定表时,默认是Append-Only存储。 + + - COMPRESSION + - 列存表的有效值为LOW/MIDDLE/HIGH/YES/NO,压缩级别依次升高,默认值为LOW。 + - 行存表不支持压缩。 + + - MAX\_BATCHROW + + 指定了在数据加载过程中一个存储单元可以容纳记录的最大数目。该参数只对列存表有效。 + + 取值范围:10000\~60000,默认60000。 + + - PARTIAL\_CLUSTER\_ROWS + + 指定了在数据加载过程中进行将局部聚簇存储的记录数目。该参数只对列存表有效。 + + 取值范围:大于等于MAX\_BATCHROW,建议取值为MAX\_BATCHROW的整数倍数。 + + - DELTAROW\_THRESHOLD + + 预留参数。该参数只对列存表有效。 + + 取值范围:0~9999 + + - segment + + 使用段页式的方式存储。本参数仅支持行存表。不支持列存表、临时表、unlog表。不支持ustore存储引擎。 + + 取值范围:on/off + + 默认值:off + +- **COMPRESS / NOCOMPRESS** + + 创建一个新表时,需要在创建表语句中指定关键字COMPRESS,这样,当对该表进行批量插入时就会触发压缩特性。该特性会在页范围内扫描所有元组数据,生成字典、压缩元组数据并进行存储。指定关键字NOCOMPRESS则不对表进行压缩。行存表不支持压缩。该参数已废弃,列存表请使用COMPRESSION修改压缩等级。 + + 缺省值为NOCOMPRESS,即不对元组数据进行压缩。 + +- **TABLESPACE tablespace\_name** + + 指定新表将要在tablespace\_name表空间内创建。如果没有声明,将使用默认表空间。 + +- **PARTITION BY RANGE \[COLUMNS\]\(partition\_key\)** + + 创建范围分区。partition\_key为分区键的名称。 + + COLUMNS关键字只能在sql\_compatibility='B'时使用,“PARTITION BY RANGE COLUMNS” 语义同 “PARTITION BY RANGE”。 + + (1)对于从句是VALUES LESS THAN的语法格式: + + >![](public_sys-resources/icon-notice.png) **须知:** + >对于从句是VALUE LESS THAN的语法格式,范围分区策略的分区键最多支持16列。 + + 该情形下,分区键支持的数据类型为:SMALLINT、INTEGER、BIGINT、DECIMAL、NUMERIC、REAL、DOUBLE PRECISION、CHARACTER VARYING\(n\)、VARCHAR\(n\)、CHARACTER\(n\)、CHAR\(n\)、CHARACTER、CHAR、TEXT、NVARCHAR、NVARCHAR2、NAME、TIMESTAMP\[\(p\)\] \[WITHOUT TIME ZONE\]、TIMESTAMP\[\(p\)\] \[WITH TIME ZONE\]、DATE。 + + (2)对于从句是START END的语法格式: + + >![](public_sys-resources/icon-notice.png) **须知:** + >对于从句是START END的语法格式,范围分区策略的分区键仅支持1列。 + + 该情形下,分区键支持的数据类型为:SMALLINT、INTEGER、BIGINT、DECIMAL、NUMERIC、REAL、DOUBLE PRECISION、TIMESTAMP\[\(p\)\] \[WITHOUT TIME ZONE\]、TIMESTAMP\[\(p\)\] \[WITH TIME ZONE\]、DATE。 + + (3)对于指定了INTERVAL子句的语法格式: + + >![](public_sys-resources/icon-notice.png) **须知:** + >对于指定了INTERVAL子句的语法格式,范围分区策略的分区键仅支持1列。 + + 该情形下,分区键支持的数据类型为:TIMESTAMP\[\(p\)\] \[WITHOUT TIME ZONE\]、TIMESTAMP\[\(p\)\] \[WITH TIME ZONE\]、DATE。 + +- **PARTITION partition\_name VALUES LESS THAN \{\( \{ partition\_value | MAXVALUE \} \[,...\] \) | MAXVALUE \}** + + 指定各分区的信息。partition\_name为范围分区的名称。partition\_value为范围分区的上边界,取值依赖于partition\_key的类型。MAXVALUE表示分区的上边界,它通常用于设置最后一个范围分区的上边界。 + + >![](public_sys-resources/icon-notice.png) **须知:** + > + >- 每个分区都需要指定一个上边界。 + + >- 分区上边界的类型应当和分区键的类型一致。 + + >- 分区列表是按照分区上边界升序排列的,值较小的分区位于值较大的分区之前。 + >- 不在括号内的MAVALUE只能在sql\_compatibility='B'时使用,并且只能有一个分区键。 + +- **PARTITION partition\_name \{START \(partition\_value\) END \(partition\_value\) EVERY \(interval\_value\)\} | \{START \(partition\_value\) END \(partition\_value|MAXVALUE\)\} | \{START\(partition\_value\)\} | \{END \(partition\_value | MAXVALUE\)\}** + + 指定各分区的信息,各参数意义如下: + + - partition\_name:范围分区的名称或名称前缀,除以下情形外(假定其中的partition\_name是p1),均为分区的名称。 + - 若该定义是START+END+EVERY从句,则语义上定义的分区的名称依次为p1\_1, p1\_2, ...。例如对于定义“PARTITION p1 START\(1\) END\(4\) EVERY\(1\)”,则生成的分区是:\[1, 2\), \[2, 3\) 和 \[3, 4\),名称依次为p1\_1, p1\_2和p1\_3,即此处的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。 + - interval\_value:对\[START,END\) 表示的范围进行切分,interval\_value是指定切分后每个分区的宽度,不可是MAXVALUE;如果(END-START)值不能整除以EVERY值,则仅最后一个分区的宽度小于EVERY值。 + - MAXVALUE:表示最大值,它通常用于设置最后一个范围分区的上边界。 + + >![](public_sys-resources/icon-notice.png) **须知:** + > + >1. 在创建分区表若第一个分区定义含START值,则范围(MINVALUE,START)将自动作为实际的第一个分区。 + >2. START END语法需要遵循以下限制: + > - 每个partition\_start\_end\_item中的START值(如果有的话,下同)必须小于其END值。 + + > - 相邻的两个partition\_start\_end\_item,第一个的END值必须等于第二个的START值; + + > - 每个partition\_start\_end\_item中的EVERY值必须是正向递增的,且必须小于(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语法格式。 + +- **INTERVAL \('interval\_expr'\) \[ STORE IN \(tablespace\_name \[, ... \] \) \]** + + 间隔分区定义信息。 + + - interval\_expr:自动创建分区的间隔,例如:1 day、1 month。 + + - STORE IN \(tablespace\_name \[, ... \] \):指定存放自动创建分区的表空间列表,如果有指定,则自动创建的分区从表空间列表中循环选择使用,否则使用分区表默认的表空间。 + + >![](public_sys-resources/icon-notice.png) **须知:** + > + >列存表不支持间隔分区。 + +- **PARTITION BY LIST \[COLUMNS\] \(partition\_key\)** + + 创建列表分区。partition\_key为分区键的名称。 + + COLUMNS关键字只能在sql\_compatibility='B'时使用,“PARTITION BY LIST COLUMNS” 语义同 “PARTITION BY LIST”。 + + - 对于partition\_key,列表分区策略的分区键最多支持16列。 + - 对于从句是VALUES \[IN\] \(list\_values\)的语法格式,list\_values中包含了对应分区存在的键值,每个分区的键值数量不超过64个。 + - 从句"VALUES IN"只能在sql\_compatibility='B'时使用,语义同"VALUES"。 + + 分区键支持的数据类型为:INT1、INT2、INT4、INT8、NUMERIC、VARCHAR\(n\)、CHAR、BPCHAR、NVARCHAR、NVARCHAR2、TIMESTAMP\[\(p\)\] \[WITHOUT TIME ZONE\]、TIMESTAMP\[\(p\)\] \[WITH TIME ZONE\]、DATE。分区个数不能超过1048575个。 + +- **PARTITION BY HASH\(partition\_key\)** + + 创建哈希分区。partition\_key为分区键的名称。 + + 对于partition\_key,哈希分区策略的分区键仅支持1列。 + + 分区键支持的数据类型为:INT1、INT2、INT4、INT8、NUMERIC、VARCHAR\(n\)、CHAR、BPCHAR、TEXT、NVARCHAR、NVARCHAR2、TIMESTAMP\[\(p\)\] \[WITHOUT TIME ZONE\]、TIMESTAMP\[\(p\)\] \[WITH TIME ZONE\]、DATE。分区个数不能超过1048575 个。 + +- **PARTITION BY KEY\(partition\_key\)** + + 只能在sql\_compatibility='B'时使用,语义同“PARTITION BY HASH\(partition\_key\)”。 + +- **PARTITIONS integer** + + 指定分区个数。 + + integer为分区数,必须为大于0的整数,且不得大于1048575。 + + - 当在RANGE和LIST分区后指定此子句时,必须显式定义每个分区,且定义分区的数量必须与integer值相等。只能在sql\_compatibility='B'时在RANGE和LIST分区后指定此子句。 + - 当在HASH和KEY分区后指定此子句时,若不列出各个分区定义,将自动生成integer个分区,自动生成的分区名为“p+数字”,数字依次为0到integer-1,分区的表空间默认为此表的表空间;也可以显式列出每个分区定义,此时定义分区的数量必须与integer值相等。若既不列出分区定义,也不指定分区数量,将创建唯一一个分区。 + +- **\{ ENABLE | DISABLE \} ROW MOVEMENT** + + 行迁移开关。 + + 如果进行UPDATE操作时,更新了元组在分区键上的值,造成了该元组所在分区发生变化,就会根据该开关给出报错信息,或者进行元组在分区间的转移。 + + 取值范围: + + - ENABLE(缺省值):行迁移开关打开。 + - DISABLE:行迁移开关关闭。 + +- **NOT NULL** + + 字段值不允许为NULL。ENABLE用于语法兼容,可省略。 + +- **NULL** + + 字段值允许NULL ,这是缺省。 + + 这个子句只是为和非标准SQL数据库兼容。不建议使用。 + +- **CHECK \(condition\) \[ NO INHERIT \]** + + CHECK约束声明一个布尔表达式,每次要插入的新行或者要更新的行的新值必须使表达式结果为真或未知才能成功,否则会抛出一个异常并且不会修改数据库。 + + 声明为字段约束的检查约束应该只引用该字段的数值,而在表约束里出现的表达式可以引用多个字段。 + + 用NO INHERIT标记的约束将不会传递到子表中去。 + + ENABLE用于语法兼容,可省略。 + +- **DEFAULT default\_expr** + + DEFAULT子句给字段指定缺省值。该数值可以是任何不含变量的表达式\(不允许使用子查询和对本表中的其他字段的交叉引用\)。缺省表达式的数据类型必须和字段类型匹配。 + + 缺省表达式将被用于任何未声明该字段数值的插入操作。如果没有指定缺省值则缺省值为NULL 。 + +- **GENERATED ALWAYS AS \( generation\_expr \) \[STORED\]** + + 该子句将字段创建为生成列,生成列的值在写入(插入或更新)数据时由generation\_expr计算得到,STORED表示像普通列一样存储生成列的值。 + + >![](public_sys-resources/icon-note.png) **说明:** + > + >- STORED关键字可省略,与不省略STORED语义相同。 + >- 生成表达式不能以任何方式引用当前行以外的其他数据。生成表达式不能引用其他生成列,不能引用系统列。生成表达式不能返回结果集,不能使用子查询,不能使用聚集函数,不能使用窗口函数。生成表达式调用的函数只能是不可变(IMMUTABLE)函数。 + >- 不能为生成列指定默认值。 + >- 生成列不能作为分区键的一部分。 + >- 生成列不能和ON UPDATE约束字句的CASCADE,SET NULL,SET DEFAULT动作同时指定。生成列不能和ON DELETE约束字句的SET NULL、SET DEFAULT动作同时指定。 + >- 修改和删除生成列的方法和普通列相同。删除生成列依赖的普通列,生成列被自动删除。不能改变生成列所依赖的列的类型。 + >- 生成列不能被直接写入。在INSERT或UPDATE命令中, 不能为生成列指定值, 但是可以指定关键字DEFAULT。 + >- 生成列的权限控制和普通列一样。 + >- 列存表、内存表MOT不支持生成列。外表中仅postgres\_fdw支持生成列。 + +- **AUTO\_INCREMENT** + + 指定列为自动增长列。 + + 详见:[AUTO\_INCREMENT](CREATE-TABLE.md)。 + +- **UNIQUE \[KEY\] index\_parameters** + + **UNIQUE \( column\_name \[, ... \] \) index\_parameters** + + UNIQUE约束表示表里的一个字段或多个字段的组合必须在全表范围内唯一。 + + 对于唯一约束,NULL被认为是互不相等的。 + + UNIQUE KEY只能在sql\_compatibility='B'时使用,与UNIQUE语义相同。 + +- **PRIMARY KEY index\_parameters** + + **PRIMARY KEY \( column\_name \[, ... \] \) index\_parameters** + + 主键约束声明表中的一个或者多个字段只能包含唯一的非NULL值。 + + 一个表只能声明一个主键。 + +- **DEFERRABLE | NOT DEFERRABLE** + + 这两个关键字设置该约束是否可推迟。一个不可推迟的约束将在每条命令之后马上检查。可推迟约束可以推迟到事务结尾使用SET CONSTRAINTS命令检查。缺省是NOT DEFERRABLE。目前,UNIQUE约束、主键约束、外键约束可以接受这个子句。所有其他约束类型都是不可推迟的。 + +- **INITIALLY IMMEDIATE | INITIALLY DEFERRED** + + 如果约束是可推迟的,则这个子句声明检查约束的缺省时间。 + + - 如果约束是INITIALLY IMMEDIATE(缺省),则在每条语句执行之后就立即检查它; + - 如果约束是INITIALLY DEFERRED ,则只有在事务结尾才检查它。 + + 约束检查的时间可以用SET CONSTRAINTS命令修改。 + +- **USING INDEX TABLESPACE tablespace\_name** + + 为UNIQUE或PRIMARY KEY约束相关的索引声明一个表空间。如果没有提供这个子句,这个索引将在default\_tablespace中创建,如果default\_tablespace为空,将使用数据库的缺省表空间。 + + +## 示例 + +- 示例1:创建范围分区表tpcds.web\_returns\_p1,含有8个分区,分区键为integer类型。 分区的范围分别为:wr\_returned\_date\_sk< 2450815、2450815<= wr\_returned\_date\_sk< 2451179、2451179<=wr\_returned\_date\_sk< 2451544、2451544 <= wr\_returned\_date\_sk< 2451910、2451910 <= wr\_returned\_date\_sk< 2452275、2452275 <= wr\_returned\_date\_sk< 2452640、2452640 <= wr\_returned\_date\_sk< 2453005、wr\_returned\_date\_sk\>=2453005。 + + ``` + --创建表tpcds.web_returns。 + openGauss=# CREATE TABLE tpcds.web_returns + ( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) + ); + --创建分区表tpcds.web_returns_p1。 + openGauss=# CREATE TABLE tpcds.web_returns_p1 + ( + WR_RETURNED_DATE_SK INTEGER , + WR_RETURNED_TIME_SK INTEGER , + WR_ITEM_SK INTEGER NOT NULL, + WR_REFUNDED_CUSTOMER_SK INTEGER , + WR_REFUNDED_CDEMO_SK INTEGER , + WR_REFUNDED_HDEMO_SK INTEGER , + WR_REFUNDED_ADDR_SK INTEGER , + WR_RETURNING_CUSTOMER_SK INTEGER , + WR_RETURNING_CDEMO_SK INTEGER , + WR_RETURNING_HDEMO_SK INTEGER , + WR_RETURNING_ADDR_SK INTEGER , + WR_WEB_PAGE_SK INTEGER , + WR_REASON_SK INTEGER , + WR_ORDER_NUMBER BIGINT NOT NULL, + WR_RETURN_QUANTITY INTEGER , + WR_RETURN_AMT DECIMAL(7,2) , + WR_RETURN_TAX DECIMAL(7,2) , + WR_RETURN_AMT_INC_TAX DECIMAL(7,2) , + WR_FEE DECIMAL(7,2) , + WR_RETURN_SHIP_COST DECIMAL(7,2) , + WR_REFUNDED_CASH DECIMAL(7,2) , + WR_REVERSED_CHARGE DECIMAL(7,2) , + WR_ACCOUNT_CREDIT DECIMAL(7,2) , + WR_NET_LOSS DECIMAL(7,2) + ) + WITH (ORIENTATION = COLUMN,COMPRESSION=MIDDLE) + PARTITION BY RANGE(WR_RETURNED_DATE_SK) + ( + PARTITION P1 VALUES LESS THAN(2450815), + PARTITION P2 VALUES LESS THAN(2451179), + PARTITION P3 VALUES LESS THAN(2451544), + PARTITION P4 VALUES LESS THAN(2451910), + PARTITION P5 VALUES LESS THAN(2452275), + PARTITION P6 VALUES LESS THAN(2452640), + PARTITION P7 VALUES LESS THAN(2453005), + PARTITION P8 VALUES LESS THAN(MAXVALUE) + ); + + --从示例数据表导入数据。 + openGauss=# INSERT INTO tpcds.web_returns_p1 SELECT * FROM tpcds.web_returns; + + --删除分区P8。 + openGauss=# ALTER TABLE tpcds.web_returns_p1 DROP PARTITION P8; + + --增加分区WR_RETURNED_DATE_SK介于2453005和2453105之间。 + openGauss=# ALTER TABLE tpcds.web_returns_p1 ADD PARTITION P8 VALUES LESS THAN (2453105); + + --增加分区WR_RETURNED_DATE_SK介于2453105和MAXVALUE之间。 + openGauss=# ALTER TABLE tpcds.web_returns_p1 ADD PARTITION P9 VALUES LESS THAN (MAXVALUE); + + --删除分区P8。 + openGauss=# ALTER TABLE tpcds.web_returns_p1 DROP PARTITION FOR (2453005); + + --分区P7重命名为P10。 + openGauss=# ALTER TABLE tpcds.web_returns_p1 RENAME PARTITION P7 TO P10; + + --分区P6重命名为P11。 + openGauss=# ALTER TABLE tpcds.web_returns_p1 RENAME PARTITION FOR (2452639) TO P11; + + --查询分区P10的行数。 + openGauss=# SELECT count(*) FROM tpcds.web_returns_p1 PARTITION (P10); + count + -------- + 0 + (1 row) + + --查询分区P1的行数。 + openGauss=# SELECT COUNT(*) FROM tpcds.web_returns_p1 PARTITION FOR (2450815); + count + -------- + 0 + (1 row) + ``` + +- 示例2:创建范围分区表tpcds.web\_returns\_p2,含有8个分区,分区键类型为integer类型,其中第8个分区上边界为MAXVALUE。 + + 八个分区的范围分别为: wr\_returned\_date\_sk< 2450815、2450815<= wr\_returned\_date\_sk< 2451179、2451179<=wr\_returned\_date\_sk< 2451544、2451544 <= wr\_returned\_date\_sk< 2451910、2451910 <= wr\_returned\_date\_sk< 2452275、2452275 <= wr\_returned\_date\_sk< 2452640、2452640 <= wr\_returned\_date\_sk< 2453005、wr\_returned\_date\_sk\>=2453005。 + + 分区表tpcds.web\_returns\_p2的表空间为example1;分区P1到P7没有声明表空间,使用采用分区表tpcds.web\_returns\_p2的表空间example1;指定分区P8的表空间为example2。 + + 假定数据库节点的数据目录/pg\_location/mount1/path1,数据库节点的数据目录/pg\_location/mount2/path2,数据库节点的数据目录/pg\_location/mount3/path3,数据库节点的数据目录/pg\_location/mount4/path4是dwsadmin用户拥有读写权限的空目录。 + + ``` + openGauss=# CREATE TABLESPACE example1 RELATIVE LOCATION 'tablespace1/tablespace_1'; + openGauss=# CREATE TABLESPACE example2 RELATIVE LOCATION 'tablespace2/tablespace_2'; + openGauss=# CREATE TABLESPACE example3 RELATIVE LOCATION 'tablespace3/tablespace_3'; + openGauss=# CREATE TABLESPACE example4 RELATIVE LOCATION 'tablespace4/tablespace_4'; + + openGauss=# CREATE TABLE tpcds.web_returns_p2 + ( + WR_RETURNED_DATE_SK INTEGER , + WR_RETURNED_TIME_SK INTEGER , + WR_ITEM_SK INTEGER NOT NULL, + WR_REFUNDED_CUSTOMER_SK INTEGER , + WR_REFUNDED_CDEMO_SK INTEGER , + WR_REFUNDED_HDEMO_SK INTEGER , + WR_REFUNDED_ADDR_SK INTEGER , + WR_RETURNING_CUSTOMER_SK INTEGER , + WR_RETURNING_CDEMO_SK INTEGER , + WR_RETURNING_HDEMO_SK INTEGER , + WR_RETURNING_ADDR_SK INTEGER , + WR_WEB_PAGE_SK INTEGER , + WR_REASON_SK INTEGER , + WR_ORDER_NUMBER BIGINT NOT NULL, + WR_RETURN_QUANTITY INTEGER , + WR_RETURN_AMT DECIMAL(7,2) , + WR_RETURN_TAX DECIMAL(7,2) , + WR_RETURN_AMT_INC_TAX DECIMAL(7,2) , + WR_FEE DECIMAL(7,2) , + WR_RETURN_SHIP_COST DECIMAL(7,2) , + WR_REFUNDED_CASH DECIMAL(7,2) , + WR_REVERSED_CHARGE DECIMAL(7,2) , + WR_ACCOUNT_CREDIT DECIMAL(7,2) , + WR_NET_LOSS DECIMAL(7,2) + ) + TABLESPACE example1 + PARTITION BY RANGE(WR_RETURNED_DATE_SK) + ( + PARTITION P1 VALUES LESS THAN(2450815), + PARTITION P2 VALUES LESS THAN(2451179), + PARTITION P3 VALUES LESS THAN(2451544), + PARTITION P4 VALUES LESS THAN(2451910), + PARTITION P5 VALUES LESS THAN(2452275), + PARTITION P6 VALUES LESS THAN(2452640), + PARTITION P7 VALUES LESS THAN(2453005), + PARTITION P8 VALUES LESS THAN(MAXVALUE) TABLESPACE example2 + ) + ENABLE ROW MOVEMENT; + + --以like方式创建一个分区表。 + openGauss=# CREATE TABLE tpcds.web_returns_p3 (LIKE tpcds.web_returns_p2 INCLUDING PARTITION); + + --修改分区P1的表空间为example2。 + openGauss=# ALTER TABLE tpcds.web_returns_p2 MOVE PARTITION P1 TABLESPACE example2; + + --修改分区P2的表空间为example3。 + openGauss=# ALTER TABLE tpcds.web_returns_p2 MOVE PARTITION P2 TABLESPACE example3; + + --以2453010为分割点切分P8。 + openGauss=# ALTER TABLE tpcds.web_returns_p2 SPLIT PARTITION P8 AT (2453010) INTO + ( + PARTITION P9, + PARTITION P10 + ); + + --将P6,P7合并为一个分区。 + openGauss=# ALTER TABLE tpcds.web_returns_p2 MERGE PARTITIONS P6, P7 INTO PARTITION P8; + + --修改分区表迁移属性。 + openGauss=# ALTER TABLE tpcds.web_returns_p2 DISABLE ROW MOVEMENT; + --删除表和表空间。 + openGauss=# DROP TABLE tpcds.web_returns_p1; + openGauss=# DROP TABLE tpcds.web_returns_p2; + openGauss=# DROP TABLE tpcds.web_returns_p3; + openGauss=# DROP TABLESPACE example1; + openGauss=# DROP TABLESPACE example2; + openGauss=# DROP TABLESPACE example3; + openGauss=# DROP TABLESPACE example4; + ``` + + +- 示例3:START END语法创建、修改Range分区表。 + + 假定/home/omm/startend\_tbs1、/home/omm/startend\_tbs2、/home/omm/startend\_tbs3、/home/omm/startend\_tbs4是omm用户拥有读写权限的空目录。 + + ``` + -- 创建表空间 + openGauss=# CREATE TABLESPACE startend_tbs1 LOCATION '/home/omm/startend_tbs1'; + openGauss=# CREATE TABLESPACE startend_tbs2 LOCATION '/home/omm/startend_tbs2'; + openGauss=# CREATE TABLESPACE startend_tbs3 LOCATION '/home/omm/startend_tbs3'; + openGauss=# CREATE TABLESPACE startend_tbs4 LOCATION '/home/omm/startend_tbs4'; + + -- 创建临时schema + openGauss=# CREATE SCHEMA tpcds; + openGauss=# SET CURRENT_SCHEMA TO tpcds; + + -- 创建分区表,分区键是integer类型 + openGauss=# CREATE TABLE tpcds.startend_pt (c1 INT, c2 INT) + TABLESPACE startend_tbs1 + PARTITION BY RANGE (c2) ( + PARTITION p1 START(1) END(1000) EVERY(200) TABLESPACE startend_tbs2, + PARTITION p2 END(2000), + PARTITION p3 START(2000) END(2500) TABLESPACE startend_tbs3, + PARTITION p4 START(2500), + PARTITION p5 START(3000) END(5000) EVERY(1000) TABLESPACE startend_tbs4 + ) + ENABLE ROW MOVEMENT; + + -- 查看分区表信息 + openGauss=# SELECT relname, boundaries, spcname FROM pg_partition p JOIN pg_tablespace t ON p.reltablespace=t.oid and p.parentid='tpcds.startend_pt'::regclass ORDER BY 1; + relname | boundaries | spcname + -------------+------------+--------------- + p1_0 | {1} | startend_tbs2 + p1_1 | {201} | startend_tbs2 + p1_2 | {401} | startend_tbs2 + p1_3 | {601} | startend_tbs2 + p1_4 | {801} | startend_tbs2 + p1_5 | {1000} | startend_tbs2 + p2 | {2000} | startend_tbs1 + p3 | {2500} | startend_tbs3 + p4 | {3000} | startend_tbs1 + p5_1 | {4000} | startend_tbs4 + p5_2 | {5000} | startend_tbs4 + startend_pt | | startend_tbs1 + (12 rows) + + -- 导入数据,查看分区数据量 + openGauss=# INSERT INTO tpcds.startend_pt VALUES (GENERATE_SERIES(0, 4999), GENERATE_SERIES(0, 4999)); + openGauss=# SELECT COUNT(*) FROM tpcds.startend_pt PARTITION FOR (0); + count + ------- + 1 + (1 row) + + openGauss=# SELECT COUNT(*) FROM tpcds.startend_pt PARTITION (p3); + count + ------- + 500 + (1 row) + + -- 增加分区: [5000, 5300), [5300, 5600), [5600, 5900), [5900, 6000) + openGauss=# ALTER TABLE tpcds.startend_pt ADD PARTITION p6 START(5000) END(6000) EVERY(300) TABLESPACE startend_tbs4; + + -- 增加MAXVALUE分区: p7 + openGauss=# ALTER TABLE tpcds.startend_pt ADD PARTITION p7 END(MAXVALUE); + + -- 重命名分区p7为p8 + openGauss=# ALTER TABLE tpcds.startend_pt RENAME PARTITION p7 TO p8; + + -- 删除分区p8 + openGauss=# ALTER TABLE tpcds.startend_pt DROP PARTITION p8; + + -- 重命名5950所在的分区为:p71 + openGauss=# ALTER TABLE tpcds.startend_pt RENAME PARTITION FOR(5950) TO p71; + + -- 分裂4500所在的分区[4000, 5000) + openGauss=# ALTER TABLE tpcds.startend_pt SPLIT PARTITION FOR(4500) INTO(PARTITION q1 START(4000) END(5000) EVERY(250) TABLESPACE startend_tbs3); + + -- 修改分区p2的表空间为startend_tbs4 + openGauss=# ALTER TABLE tpcds.startend_pt MOVE PARTITION p2 TABLESPACE startend_tbs4; + + -- 查看分区情形 + openGauss=# SELECT relname, boundaries, spcname FROM pg_partition p JOIN pg_tablespace t ON p.reltablespace=t.oid and p.parentid='tpcds.startend_pt'::regclass ORDER BY 1; + relname | boundaries | spcname + -------------+------------+--------------- + p1_0 | {1} | startend_tbs2 + p1_1 | {201} | startend_tbs2 + p1_2 | {401} | startend_tbs2 + p1_3 | {601} | startend_tbs2 + p1_4 | {801} | startend_tbs2 + p1_5 | {1000} | startend_tbs2 + p2 | {2000} | startend_tbs4 + p3 | {2500} | startend_tbs3 + p4 | {3000} | startend_tbs1 + p5_1 | {4000} | startend_tbs4 + p6_1 | {5300} | startend_tbs4 + p6_2 | {5600} | startend_tbs4 + p6_3 | {5900} | startend_tbs4 + p71 | {6000} | startend_tbs4 + q1_1 | {4250} | startend_tbs3 + q1_2 | {4500} | startend_tbs3 + q1_3 | {4750} | startend_tbs3 + q1_4 | {5000} | startend_tbs3 + startend_pt | | startend_tbs1 + (19 rows) + + -- 删除表和表空间 + openGauss=# DROP SCHEMA tpcds CASCADE; + openGauss=# DROP TABLESPACE startend_tbs1; + openGauss=# DROP TABLESPACE startend_tbs2; + openGauss=# DROP TABLESPACE startend_tbs3; + openGauss=# DROP TABLESPACE startend_tbs4; + ``` + + +- 示例4:创建间隔分区表sales,初始包含2个分区,分区键为DATE类型。 分区的范围分别为:time\_id < '2019-02-01 00:00:00'、 + + '2019-02-01 00:00:00' <= time\_id < '2019-02-02 00:00:00' 。 + + ``` + --创建表sales + openGauss=# CREATE TABLE sales + (prod_id NUMBER(6), + cust_id NUMBER, + time_id DATE, + channel_id CHAR(1), + promo_id NUMBER(6), + quantity_sold NUMBER(3), + amount_sold NUMBER(10,2) + ) + PARTITION BY RANGE (time_id) + INTERVAL('1 day') + ( PARTITION p1 VALUES LESS THAN ('2019-02-01 00:00:00'), + PARTITION p2 VALUES LESS THAN ('2019-02-02 00:00:00') + ); + + -- 数据插入分区p1 + openGauss=# INSERT INTO sales VALUES(1, 12, '2019-01-10 00:00:00', 'a', 1, 1, 1); + + -- 数据插入分区p2 + openGauss=# INSERT INTO sales VALUES(1, 12, '2019-02-01 00:00:00', 'a', 1, 1, 1); + + -- 查看分区信息 + openGauss=# SELECT t1.relname, partstrategy, boundaries FROM pg_partition t1, pg_class t2 WHERE t1.parentid = t2.oid AND t2.relname = 'sales' AND t1.parttype = 'p'; + relname | partstrategy | boundaries + ---------+--------------+------------------------- + p1 | r | {"2019-02-01 00:00:00"} + p2 | r | {"2019-02-02 00:00:00"} + (2 rows) + + -- 插入数据没有匹配的分区,新创建一个分区,并将数据插入该分区 + -- 新分区的范围为 '2019-02-05 00:00:00' <= time_id < '2019-02-06 00:00:00' + openGauss=# INSERT INTO sales VALUES(1, 12, '2019-02-05 00:00:00', 'a', 1, 1, 1); + + -- 插入数据没有匹配的分区,新创建一个分区,并将数据插入该分区 + -- 新分区的范围为 '2019-02-03 00:00:00' <= time_id < '2019-02-04 00:00:00' + openGauss=# INSERT INTO sales VALUES(1, 12, '2019-02-03 00:00:00', 'a', 1, 1, 1); + + -- 查看分区信息 + openGauss=# SELECT t1.relname, partstrategy, boundaries FROM pg_partition t1, pg_class t2 WHERE t1.parentid = t2.oid AND t2.relname = 'sales' AND t1.parttype = 'p'; + relname | partstrategy | boundaries + ---------+--------------+------------------------- + sys_p1 | i | {"2019-02-06 00:00:00"} + sys_p2 | i | {"2019-02-04 00:00:00"} + p1 | r | {"2019-02-01 00:00:00"} + p2 | r | {"2019-02-02 00:00:00"} + (4 rows) + + ``` + + +- 示例5:创建LIST分区表test\_list,初始包含4个分区,分区键为INT类型。4个分区的范围分别为:2000、3000、4000、5000。 + + ``` + --创建表test_list + openGauss=# create table test_list (col1 int, col2 int) + partition by list(col1) + ( + partition p1 values (2000), + partition p2 values (3000), + partition p3 values (4000), + partition p4 values (5000) + ); + + -- 数据插入 + openGauss=# INSERT INTO test_list VALUES(2000, 2000); + INSERT 0 1 + openGauss=# INSERT INTO test_list VALUES(3000, 3000); + INSERT 0 1 + + -- 查看分区信息 + openGauss=# SELECT t1.relname, partstrategy, boundaries FROM pg_partition t1, pg_class t2 WHERE t1.parentid = t2.oid AND t2.relname = 'test_list' AND t1.parttype = 'p'; + relname | partstrategy | boundaries + ---------+--------------+------------ + p1 | l | {2000} + p2 | l | {3000} + p3 | l | {4000} + p4 | l | {5000} + (4 rows) + + -- 插入数据没有匹配到分区,报错处理 + openGauss=# INSERT INTO test_list VALUES(6000, 6000); + ERROR: inserted partition key does not map to any table partition + + -- 添加分区 + openGauss=# alter table test_list add partition p5 values (6000); + ALTER TABLE + openGauss=# SELECT t1.relname, partstrategy, boundaries FROM pg_partition t1, pg_class t2 WHERE t1.parentid = t2.oid AND t2.relname = 'test_list' AND t1.parttype = 'p'; + relname | partstrategy | boundaries + ---------+--------------+------------ + p5 | l | {6000} + p4 | l | {5000} + p1 | l | {2000} + p2 | l | {3000} + p3 | l | {4000} + (5 rows) + openGauss=# INSERT INTO test_list VALUES(6000, 6000); + INSERT 0 1 + + -- 分区表和普通表交换数据 + openGauss=# create table t1 (col1 int, col2 int); + CREATE TABLE + openGauss=# select * from test_list partition (p1); + col1 | col2 + ------+------ + 2000 | 2000 + (1 row) + openGauss=# alter table test_list exchange partition (p1) with table t1; + ALTER TABLE + openGauss=# select * from test_list partition (p1); + col1 | col2 + ------+------ + (0 rows) + openGauss=# select * from t1; + col1 | col2 + ------+------ + 2000 | 2000 + (1 row) + + -- truncate分区 + openGauss=# select * from test_list partition (p2); + col1 | col2 + ------+------ + 3000 | 3000 + (1 row) + openGauss=# alter table test_list truncate partition p2; + ALTER TABLE + openGauss=# select * from test_list partition (p2); + col1 | col2 + ------+------ + (0 rows) + + -- 删除分区 + openGauss=# alter table test_list drop partition p5; + ALTER TABLE + openGauss=# SELECT t1.relname, partstrategy, boundaries FROM pg_partition t1, pg_class t2 WHERE t1.parentid = t2.oid AND t2.relname = 'test_list' AND t1.parttype = 'p'; + relname | partstrategy | boundaries + ---------+--------------+------------ + p4 | l | {5000} + p1 | l | {2000} + p2 | l | {3000} + p3 | l | {4000} + (4 rows) + + openGauss=# INSERT INTO test_list VALUES(6000, 6000); + ERROR: inserted partition key does not map to any table partition + + -- 删除分区表 + openGauss=# drop table test_list; + ``` + + +- 示例6:创建HASH分区表test\_hash,初始包含2个分区,分区键为INT类型。 + + ``` + --创建表test_hash + openGauss=# create table test_hash (col1 int, col2 int) + partition by hash(col1) + ( + partition p1, + partition p2 + ); + + -- 数据插入 + openGauss=# INSERT INTO test_hash VALUES(1, 1); + INSERT 0 1 + openGauss=# INSERT INTO test_hash VALUES(2, 2); + INSERT 0 1 + openGauss=# INSERT INTO test_hash VALUES(3, 3); + INSERT 0 1 + openGauss=# INSERT INTO test_hash VALUES(4, 4); + INSERT 0 1 + + -- 查看分区信息 + openGauss=# SELECT t1.relname, partstrategy, boundaries FROM pg_partition t1, pg_class t2 WHERE t1.parentid = t2.oid AND t2.relname = 'test_hash' AND t1.parttype = 'p'; + relname | partstrategy | boundaries + ---------+--------------+------------ + p1 | h | {0} + p2 | h | {1} + (2 rows) + + -- 查看数据 + openGauss=# select * from test_hash partition (p1); + col1 | col2 + ------+------ + 3 | 3 + 4 | 4 + (2 rows) + + openGauss=# select * from test_hash partition (p2); + col1 | col2 + ------+------ + 1 | 1 + 2 | 2 + (2 rows) + + -- 分区表和普通表交换数据 + openGauss=# create table t1 (col1 int, col2 int); + CREATE TABLE + openGauss=# alter table test_hash exchange partition (p1) with table t1; + ALTER TABLE + openGauss=# select * from test_hash partition (p1); + col1 | col2 + ------+------ + (0 rows) + openGauss=# select * from t1; + col1 | col2 + ------+------ + 3 | 3 + 4 | 4 + (2 rows) + + -- truncate分区 + openGauss=# alter table test_hash truncate partition p2; + ALTER TABLE + openGauss=# select * from test_hash partition (p2); + col1 | col2 + ------+------ + (0 rows) + + -- 删除分区表 + openGauss=# drop table test_hash; + ``` + ++ 示例7:创建LIST分区表t\_multi\_keys\_list,初始包含5个分区,两个分区键分别为INT类型和VARCHAR类型。 + + ``` + --创建表t_multi_keys_list + openGauss=# CREATE TABLE t_multi_keys_list (a int, b varchar(4), c int) + PARTITION BY LIST (a,b) + ( + PARTITION p1 VALUES ( (0,NULL) ), + PARTITION p2 VALUES ( (0,'1'), (0,'2'), (0,'3'), (1,'1'), (1,'2') ), + PARTITION p3 VALUES ( (NULL,'0'), (2,'1') ), + PARTITION p4 VALUES ( (3,'2'), (NULL,NULL) ), + PARTITION pd VALUES ( DEFAULT ) + ); + ``` + + + +## 相关链接 + +[ALTER TABLE PARTITION](ALTER-TABLE-PARTITION.md),[DROP TABLE](DROP-TABLE.md) + diff --git a/content/zh/docs/SQLReference/CREATE-TABLE-SUBPARTITION.md b/content/zh/docs/SQLReference/CREATE-TABLE-SUBPARTITION.md index cf1428a745424625329abf25327e909fa78e071a..ed030b15bf1a81580220c5ec22e19f82bcc69f6f 100644 --- a/content/zh/docs/SQLReference/CREATE-TABLE-SUBPARTITION.md +++ b/content/zh/docs/SQLReference/CREATE-TABLE-SUBPARTITION.md @@ -1,1269 +1,1270 @@ -# CREATE TABLE SUBPARTITION - -## 功能描述 - -创建二级分区表。分区表是把逻辑上的一张表根据某种方案分成几张物理块进行存储,这张逻辑上的表称之为分区表,物理块称之为分区。分区表是一张逻辑表,不存储数据,数据实际是存储在分区上的。对于二级分区表,顶层节点表和一级分区都是逻辑表,不存储数据,只有二级分区(叶子节点)存储数据。 - -二级分区表的分区方案是由两个一级分区的分区方案组合而来的,一级分区的分区方案详见章节CREATE TABLE PARTITION。 - -常见的二级分区表组合方案有Range-Range分区、Range-List分区、Range-Hash分区、List-Range分区、List-List分区、List-Hash分区、Hash-Range分区、Hash-List分区、Hash-Hash分区等。目前二级分区仅支持行存表。 - -## 注意事项 - -- 二级分区表有两个分区键,每个分区键只能支持1列。 -- 唯一约束和主键约束的约束键包含所有分区键将为约束创建LOCAL索引,否则创建GLOBAL索引。 -- 二级分区表的二级分区(叶子节点)个数不能超过1048575个,一级分区无限制,但一级分区下面至少有一个二级分区。 -- 二级分区表只支持行存,不支持列存、段页式、hashbucket。 -- 不支持Upsert、Merge into。 -- 指定分区查询时,如select \* from tablename partition/subpartition \(partitionname\),关键字partition和subpartition注意不要写错。如果写错,查询不会报错,这时查询会变为对表起别名进行查询。 -- 不支持对二级分区 subpartition for \(values\)查询。如select \* from tablename subpartition for \(values\)。 -- 不支持密态数据库、账本数据库和行级访问控制。 -- 对于二级分区表PARTITION FOR \(values\)语法,values只能是常量。 -- 对于分区表PARTITION/SUBPARTITION FOR \(values\)语法,values在需要数据类型转换时,建议使用强制类型转换,以防隐式类型转换结果与预期不符。 -- 指定分区语句目前不能走全局索引扫描。 -- 当分区数太多导致内存不足时,会间接导致性能急剧下降。 -- 目前Hash分区是按倒序排列的,即通过哈希和取余计算后得到的分区下标与创建顺序相反,同样EXPLAIN计划显示的Selected Partitions的序号排序也与创建顺序相反。List分区是按分区数组的第一个元素排序的。 - -## 语法格式 - -``` -CREATE TABLE [ IF NOT EXISTS ] subpartition_table_name -( -{ column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ] -| table_constraint -| LIKE source_table [ like_option [...] ] }[, ... ] -) -[ AUTO_INCREMENT [ = ] value ] -[ WITH ( {storage_parameter = value} [, ... ] ) ] -[ COMPRESS | NOCOMPRESS ] -[ TABLESPACE tablespace_name ] -PARTITION BY {RANGE [ COLUMNS ] | LIST [ COLUMNS ] | HASH | KEY} (partition_key) [ PARTITIONS integer ] SUBPARTITION BY {RANGE | LIST | HASH | KEY} (subpartition_key) [ SUBPARTITIONS integer ] -( - PARTITION partition_name1 [ VALUES LESS THAN {(val1) | MAXVALUE} | VALUES [IN] (val1[, …]) ] [ TABLESPACE [=] tablespace ] - ( - { SUBPARTITION subpartition_name1 [ VALUES LESS THAN (val1_1) | VALUES (val1_1[, …])] [ TABLESPACE [=] tablespace ] [COMMENT {=| } 'text' ] } [, ...] - )[, ...] -)[ { ENABLE | DISABLE } ROW MOVEMENT ]; -``` - -- 列约束column\_constraint: - - ``` - [ CONSTRAINT constraint_name ] - { NOT NULL | - NULL | - CHECK ( expression ) | - DEFAULT default_e xpr | - GENERATED ALWAYS AS ( generation_expr ) [STORED] | - AUTO_INCREMENT | - UNIQUE [KEY] 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 ] - [ COMMENT {=| } 'text' ] - ``` - -- 表约束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 | - FOREIGN KEY [ index_name ] ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] - [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] } - [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] - [ COMMENT {=| } 'text' ] - ``` - - -- like选项like\_option: - - ``` - { INCLUDING | EXCLUDING } { DEFAULTS | GENERATED | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | RELOPTIONS| ALL } - ``` - - -- 索引存储参数index\_parameters: - - ``` - [ WITH ( {storage_parameter = value} [, ... ] ) ] - [ USING INDEX TABLESPACE tablespace_name ] - ``` - - -## 参数说明 - -- **IF NOT EXISTS** - - 如果已经存在相同名称的表,不会抛出一个错误,而会发出一个通知,告知表关系已存在。 - -- **subpartition\_table\_name** - - 二级分区表的名称。 - - 取值范围:字符串,要符合标识符的命名规范。 - - -- **column\_name** - - 新表中要创建的字段名。 - - 取值范围:字符串,要符合标识符的命名规范。 - -- **data\_type** - - 字段的数据类型。 - -- **COLLATE collation** - - COLLATE子句指定列的排序规则(该列必须是可排列的数据类型)。如果没有指定,则使用默认的排序规则。排序规则可以使用“select \* from pg\_collation;”命令从pg\_collation系统表中查询,默认的排序规则为查询结果中以default开始的行。 - -- **CONSTRAINT constraint\_name** - - 列约束或表约束的名称。可选的约束子句用于声明约束,新行或者更新的行必须满足这些约束才能成功插入或更新。 - - 定义约束有两种方法: - - - 列约束:作为一个列定义的一部分,仅影响该列。 - - 表约束:不和某个列绑在一起,可以作用于多个列。 - - >![](public_sys-resources/icon-notice.png) **须知:** - >在B模式数据库下(即sql\_compatibility = 'B')constraint\_name为可选项,在其他模式数据库下,必须加上constraint\_name。 - -- **index\_name** - - 索引名。 - - >![](public_sys-resources/icon-notice.png) **须知:** - >- index\_name仅在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库下不支持。 - >- 对于外键约束,constraint\_name和index\_name同时指定时,索引名为constraint\_name。 - >- 对于唯一键约束,constraint\_name和index\_name同时指定时,索引名以index\_name。 - -- **USING method** - - 指定创建索引的方法。 - - 取值范围参考[参数说明](CREATE-INDEX.md)中的USING method。 - - >![](public_sys-resources/icon-notice.png) **须知:** - >- USING method仅在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库下不支持。 - >- 在B模式下,未指定USING method时,对于ASTORE的存储方式,默认索引方法为btree;对于USTORE的存储方式,默认索引方法为ubtree。 - -- **ASC | DESC** - - ASC表示指定按升序排序(默认)。DESC指定按降序排序。 - - >![](public_sys-resources/icon-notice.png) **须知:** - > - >ASC|DESC只在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库不支持。 - -- **LIKE source\_table \[ like\_option ... \]** - - 二级分区表暂不支持该功能。 - -- **AUTO\_INCREMENT \[ = \] value** - - 这个子句为自动增长列指定一个初始值,value必须为正整数,不得超过2127-1。 - - >![](public_sys-resources/icon-notice.png) **须知:** - > - >该子句仅在参数sql\_compatibility=B时有效。 - - -- **WITH \( storage\_parameter \[= value\] \[, ... \] \)** - - 这个子句为表或索引指定一个可选的存储参数。参数的详细描述如下所示: - - - **FILLFACTOR** - - 一个表的填充因子(fillfactor)是一个介于10和100之间的百分数。100(完全填充)是默认值。如果指定了较小的填充因子,INSERT操作仅按照填充因子指定的百分率填充表页。每个页上的剩余空间将用于在该页上更新行,这就使得UPDATE有机会在同一页上放置同一条记录的新版本,这比把新版本放置在其他页上更有效。对于一个从不更新的表将填充因子设为100是最佳选择,但是对于频繁更新的表,选择较小的填充因子则更加合适。该参数对于列存表没有意义。 - - 取值范围:10\~100 - - - **ORIENTATION** - - 决定了表的数据的存储方式。 - - 取值范围: - - - COLUMN:表的数据将以列式存储。 - - ROW(缺省值):表的数据将以行式存储。 - - >![](public_sys-resources/icon-notice.png) **须知:** - > - >orientation不支持修改。 - - **COMPRESSTYPE** - - 行存表参数,设置行存表压缩算法。1代表pglz算法(不推荐使用),2代表zstd算法,默认不压缩。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。(仅支持ASTORE和USTORE下的普通表和分区表) - - 取值范围:0\~2,默认值为0。 - - - **COMPRESS\_LEVEL** - - 行存表参数,设置行存表压缩算法等级,仅当COMPRESSTYPE为2时生效。压缩等级越高,表的压缩效果越好,表的访问速度越慢。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - - 取值范围:-31\~31,默认值为0。 - - - **COMPRESS\_CHUNK_SIZE** - - 行存表参数,设置行存表压缩chunk块大小,仅当COMPRESSTYPE不为0时生效。chunk数据块越小,预期能达到的压缩效果越好,同时数据越离散,影响表的访问速度。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - 取值范围:与页面大小有关。在页面大小为8k场景,取值范围为:512、1024、2048、4096。 - - 默认值:4096 - - - **COMPRESS_PREALLOC_CHUNKS** - - 行存表参数,设置行存表压缩chunk块预分配数量。预分配数量越大,表的压缩率相对越差,离散度越小,访问性能越好。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - - 取值范围:0\~7,默认值为0。 - - - 当COMPRESS\_CHUNK_SIZE为512和1024时,支持预分配设置最大为7。 - - 当COMPRESS\_CHUNK_SIZE为2048时,支持预分配设置最大为3。 - - 当COMPRESS\_CHUNK_SIZE为4096时,支持预分配设置最大为1。 - - - **COMPRESS_BYTE_CONVERT** - - 行存表参数,设置行存表压缩字节转换预处理,仅当COMPRESSTYPE不为0时生效。在一些场景下可以提升压缩效果,同时会导致一定性能劣化。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - - 取值范围:布尔值,默认关闭。 - - - **COMPRESS_DIFF_CONVERT** - - 行存表参数,设置行存表压缩字节差分预处理。只能与compress_byte_convert一起使用。在一些场景下可以提升压缩效果,同时会导致一定性能劣化。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - - 取值范围:布尔值,默认关闭。 - - - STORAGE\_TYPE - - 指定存储引擎类型,该参数设置成功后就不再支持修改。 - - 取值范围: - - - USTORE,表示表支持Inplace-Update存储引擎。特别需要注意,使用USTORE表,必须要开启track\_counts和track\_activities参数,否则会引起空间膨胀。 - - - ASTORE,表示表支持Append-Only存储引擎。 - - 默认值: 不指定表时,默认是Append-Only存储。 -- **COMPRESSION** - - - 列存表的有效值为LOW/MIDDLE/HIGH/YES/NO,压缩级别依次升高,默认值为LOW。 -- 行存表不支持压缩。 - -- **MAX\_BATCHROW** - - 指定了在数据加载过程中一个存储单元可以容纳记录的最大数目。该参数只对列存表有效。 - - 取值范围:10000\~60000,默认60000。 - -- **PARTIAL\_CLUSTER\_ROWS** - - 指定了在数据加载过程中进行将局部聚簇存储的记录数目。该参数只对列存表有效。 - - 取值范围:大于等于MAX\_BATCHROW,建议取值为MAX\_BATCHROW的整数倍数。 - -- **DELTAROW\_THRESHOLD** - - 预留参数。该参数只对列存表有效。 - - 取值范围:0~9999 - - -- **COMPRESS / NOCOMPRESS** - - 创建一个新表时,需要在创建表语句中指定关键字COMPRESS,这样,当对该表进行批量插入时就会触发压缩特性。该特性会在页范围内扫描所有元组数据,生成字典、压缩元组数据并进行存储。指定关键字NOCOMPRESS则不对表进行压缩。行存表不支持压缩。该参数已废弃,列存表请使用COMPRESSION修改压缩等级。 - - 缺省值为NOCOMPRESS,即不对元组数据进行压缩。 - -- **TABLESPACE tablespace\_name** - - 指定新表将要在tablespace\_name表空间内创建。如果没有声明,将使用默认表空间。 - -- **PARTITION BY \{RANGE \[COLUMNS\] | LIST \[COLUMNS\] | HASH | KEY\} \(partition\_key\)** - - - 对于partition\_key,分区策略的分区键仅支持1列。 - - 分区键支持的数据类型和一级分区表约束保持一致。 - - COLUMNS关键字只能在sql\_compatibility='B'时使用,只能加在RANGE或LIST之后,“RANGE COLUMNS” 语义同 “RANGE”,“LIST COLUMNS” 语义同 “LIST”。 - - KEY关键字只能在sql\_compatibility='B'时使用,KEY与HASH同义。 - -- **SUBPARTITION BY \{RANGE | LIST | HASH | KEY\} \(subpartition\_key\)** - - - 对于subpartition\_key,分区策略的分区键仅支持1列。 - - 分区键支持的数据类型和一级分区表约束保持一致。 - - KEY关键字只能在sql\_compatibility='B'时使用,KEY与HASH同义。 - -- **PARTITIONS integer** - - 指定分区个数。 - - integer为分区数,必须为大于0的整数,且不得大于1048575。 - - - 当在RANGE和LIST分区后指定此子句时,必须显式定义每个分区,且定义分区的数量必须与integer值相等。只能在sql\_compatibility='B'时在RANGE和LIST分区后指定此子句。 - - 当在HASH和KEY分区后指定此子句时,若不列出各个分区定义,将自动生成integer个分区,自动生成的分区名为“p+数字”,数字依次为0到integer-1,分区的表空间默认为此表的表空间;也可以显式列出每个分区定义,此时定义分区的数量必须与integer值相等。若既不列出分区定义,也不指定分区数量,将创建唯一一个分区。 - -- **SUBPARTITIONS integer** - - 指定二级分区数量。 - - integer为二级分区个数,必须为大于0的整数,且不得大于1048575。 - - - 只能在HASH和KEY二级分区后指定此子句。 - - 若不列出各个二级分区定义,将在每个一级分区内自动生成integer个二级分区,自动生成的二级分区名为“一级分区名+sp+数字”,数字依次为0到integer-1,分区的表空间默认为此表的表空间。 - - 也可以列出每个二级分区定义,此时二级分区的数量必须与integer值相等。 - - 若既不列出每个二级分区定义,也不指定二级分区数量,将创建唯一一个二级分区。 - - -- **\{ ENABLE | DISABLE \} ROW MOVEMENT** - - 行迁移开关。 - - 如果进行UPDATE操作时,更新了元组在分区键上的值,造成了该元组所在分区发生变化,就会根据该开关给出报错信息,或者进行元组在分区间的转移。 - - 取值范围: - - - ENABLE(缺省值):行迁移开关打开。 - - DISABLE:行迁移开关关闭。 - -- **NOT NULL** - - 字段值不允许为NULL。ENABLE用于语法兼容,可省略。 - -- **NULL** - - 字段值允许NULL ,这是缺省。 - - 这个子句只是为和非标准SQL数据库兼容。不建议使用。 - -- **CHECK \(condition\) \[ NO INHERIT \]** - - CHECK约束声明一个布尔表达式,每次要插入的新行或者要更新的行的新值必须使表达式结果为真或未知才能成功,否则会抛出一个异常并且不会修改数据库。 - - 声明为字段约束的检查约束应该只引用该字段的数值,而在表约束里出现的表达式可以引用多个字段。 - - 用NO INHERIT标记的约束将不会传递到子表中去。 - - ENABLE用于语法兼容,可省略。 - -- **DEFAULT default\_expr** - - DEFAULT子句给字段指定缺省值。该数值可以是任何不含变量的表达式\(不允许使用子查询和对本表中的其他字段的交叉引用\)。缺省表达式的数据类型必须和字段类型匹配。 - - 缺省表达式将被用于任何未声明该字段数值的插入操作。如果没有指定缺省值则缺省值为NULL 。 - -- **GENERATED ALWAYS AS \( generation\_expr \) [STORED]** - - 该子句将字段创建为生成列,生成列的值在写入(插入或更新)数据时由generation\_expr计算得到,STORED表示像普通列一样存储生成列的值。 - - >![](public_sys-resources/icon-note.png) **说明:** - > - >- STORED关键字可省略,与不省略STORED语义相同。 - >- 生成表达式不能以任何方式引用当前行以外的其他数据。生成表达式不能引用其他生成列,不能引用系统列。生成表达式不能返回结果集,不能使用子查询,不能使用聚集函数,不能使用窗口函数。生成表达式调用的函数只能是不可变(IMMUTABLE)函数。 - >- 不能为生成列指定默认值。 - >- 生成列不能作为分区键的一部分。 - >- 生成列不能和ON UPDATE约束字句的CASCADE、SET NULL、SET DEFAULT动作同时指定。生成列不能和ON DELETE约束字句的SET NULL、SET DEFAULT动作同时指定。 - >- 修改和删除生成列的方法和普通列相同。删除生成列依赖的普通列,生成列被自动删除。不能改变生成列所依赖的列的类型。 - >- 生成列不能被直接写入。在INSERT或UPDATE命令中, 不能为生成列指定值, 但是可以指定关键字DEFAULT。 - >- 生成列的权限控制和普通列一样。 - > - > - >- 不能为生成列指定默认值。 - > - >- 生成列不能作为分区键的一部分。 - > - >- 生成列不能和ON UPDATE约束字句的CASCADE、SET NULL、SET DEFAULT动作同时指定。生成列不能和ON DELETE约束字句的SET NULL、SET DEFAULT动作同时指定。 - > - >- 修改和删除生成列的方法和普通列相同。删除生成列依赖的普通列,生成列被自动删除。不能改变生成列所依赖的列的类型。 - > - >- 生成列不能被直接写入。在INSERT或UPDATE命令中, 不能为生成列指定值, 但是可以指定关键字DEFAULT。 - > - >- 生成列的权限控制和普通列一样。 - > - >- 列存表、内存表MOT不支持生成列。外表中仅postgres\_fdw支持生成列。 - -- **AUTO\_INCREMENT** - - 指定列为自动增长列。 - - 详见:[AUTO\_INCREMENT](CREATE-TABLE.md)。 - -- **UNIQUE index\_parameters** - - **UNIQUE \( column\_name \[, ... \] \) index\_parameters** - - UNIQUE约束表示表里的一个字段或多个字段的组合必须在全表范围内唯一。 - - 对于唯一约束,NULL被认为是互不相等的。 - -- **PRIMARY KEY index\_parameters** - - **PRIMARY KEY \( column\_name \[, ... \] \) index\_parameters** - - 主键约束声明表中的一个或者多个字段只能包含唯一的非NULL值。 - - 一个表只能声明一个主键。 - -- **DEFERRABLE | NOT DEFERRABLE** - - 这两个关键字设置该约束是否可推迟。一个不可推迟的约束将在每条命令之后马上检查。可推迟约束可以推迟到事务结尾使用SET CONSTRAINTS命令检查。缺省是NOT DEFERRABLE。目前,UNIQUE约束、主键约束、外键约束可以接受这个子句。所有其他约束类型都是不可推迟的。 - -- **INITIALLY IMMEDIATE | INITIALLY DEFERRED** - - 如果约束是可推迟的,则这个子句声明检查约束的缺省时间。 - - - 如果约束是INITIALLY IMMEDIATE(缺省),则在每条语句执行之后就立即检查它; - - 如果约束是INITIALLY DEFERRED ,则只有在事务结尾才检查它。 - - 约束检查的时间可以用SET CONSTRAINTS命令修改。 - -- **USING INDEX TABLESPACE tablespace\_name** - - 为UNIQUE或PRIMARY KEY约束相关的索引声明一个表空间。如果没有提供这个子句,这个索引将在default\_tablespace中创建,如果default\_tablespace为空,将使用数据库的缺省表空间。 - -- COMMENT {=| } 'text': - - 二级分区表的分区中,该字段无实际意义,仅作语法兼容。在数据库中使用该语法时会有告警提示。 - -## 示例 - -- 示例1:创建各种组合类型的二级分区表 - - ``` - CREATE TABLE list_list - ( - month_code VARCHAR2 ( 30 ) NOT NULL , - dept_code VARCHAR2 ( 30 ) NOT NULL , - user_no VARCHAR2 ( 30 ) NOT NULL , - sales_amt int - ) - PARTITION BY LIST (month_code) SUBPARTITION BY LIST (dept_code) - ( - PARTITION p_201901 VALUES ( '201902' ) - ( - SUBPARTITION p_201901_a VALUES ( '1' ), - SUBPARTITION p_201901_b VALUES ( '2' ) - ), - PARTITION p_201902 VALUES ( '201903' ) - ( - SUBPARTITION p_201902_a VALUES ( '1' ), - SUBPARTITION p_201902_b VALUES ( '2' ) - ) - ); - insert into list_list values('201902', '1', '1', 1); - insert into list_list values('201902', '2', '1', 1); - insert into list_list values('201902', '1', '1', 1); - insert into list_list values('201903', '2', '1', 1); - insert into list_list values('201903', '1', '1', 1); - insert into list_list values('201903', '2', '1', 1); - select * from list_list; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201903 | 2 | 1 | 1 - 201903 | 2 | 1 | 1 - 201903 | 1 | 1 | 1 - 201902 | 2 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - (6 rows) - - drop table list_list; - CREATE TABLE list_hash - ( - month_code VARCHAR2 ( 30 ) NOT NULL , - dept_code VARCHAR2 ( 30 ) NOT NULL , - user_no VARCHAR2 ( 30 ) NOT NULL , - sales_amt int - ) - PARTITION BY LIST (month_code) SUBPARTITION BY HASH (dept_code) - ( - PARTITION p_201901 VALUES ( '201902' ) - ( - SUBPARTITION p_201901_a, - SUBPARTITION p_201901_b - ), - PARTITION p_201902 VALUES ( '201903' ) - ( - SUBPARTITION p_201902_a, - SUBPARTITION p_201902_b - ) - ); - insert into list_hash values('201902', '1', '1', 1); - insert into list_hash values('201902', '2', '1', 1); - insert into list_hash values('201902', '3', '1', 1); - insert into list_hash values('201903', '4', '1', 1); - insert into list_hash values('201903', '5', '1', 1); - insert into list_hash values('201903', '6', '1', 1); - select * from list_hash; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201903 | 4 | 1 | 1 - 201903 | 5 | 1 | 1 - 201903 | 6 | 1 | 1 - 201902 | 2 | 1 | 1 - 201902 | 3 | 1 | 1 - 201902 | 1 | 1 | 1 - (6 rows) - - drop table list_hash; - CREATE TABLE list_range - ( - month_code VARCHAR2 ( 30 ) NOT NULL , - dept_code VARCHAR2 ( 30 ) NOT NULL , - user_no VARCHAR2 ( 30 ) NOT NULL , - sales_amt int - ) - PARTITION BY LIST (month_code) SUBPARTITION BY RANGE (dept_code) - ( - PARTITION p_201901 VALUES ( '201902' ) - ( - SUBPARTITION p_201901_a values less than ('4'), - SUBPARTITION p_201901_b values less than ('6') - ), - PARTITION p_201902 VALUES ( '201903' ) - ( - SUBPARTITION p_201902_a values less than ('3'), - SUBPARTITION p_201902_b values less than ('6') - ) - ); - insert into list_range values('201902', '1', '1', 1); - insert into list_range values('201902', '2', '1', 1); - insert into list_range values('201902', '3', '1', 1); - insert into list_range values('201903', '4', '1', 1); - insert into list_range values('201903', '5', '1', 1); - insert into list_range values('201903', '6', '1', 1); - ERROR: inserted partition key does not map to any table partition - select * from list_range; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201903 | 4 | 1 | 1 - 201903 | 5 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 2 | 1 | 1 - 201902 | 3 | 1 | 1 - (5 rows) - - drop table list_range; - CREATE TABLE range_list - ( - month_code VARCHAR2 ( 30 ) NOT NULL , - dept_code VARCHAR2 ( 30 ) NOT NULL , - user_no VARCHAR2 ( 30 ) NOT NULL , - sales_amt int - ) - PARTITION BY RANGE (month_code) SUBPARTITION BY LIST (dept_code) - ( - PARTITION p_201901 VALUES LESS THAN( '201903' ) - ( - SUBPARTITION p_201901_a values ('1'), - SUBPARTITION p_201901_b values ('2') - ), - PARTITION p_201902 VALUES LESS THAN( '201904' ) - ( - SUBPARTITION p_201902_a values ('1'), - SUBPARTITION p_201902_b values ('2') - ) - ); - insert into range_list values('201902', '1', '1', 1); - insert into range_list values('201902', '2', '1', 1); - insert into range_list values('201902', '1', '1', 1); - insert into range_list values('201903', '2', '1', 1); - insert into range_list values('201903', '1', '1', 1); - insert into range_list values('201903', '2', '1', 1); - select * from range_list; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 2 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201903 | 2 | 1 | 1 - 201903 | 2 | 1 | 1 - 201903 | 1 | 1 | 1 - (6 rows) - - drop table range_list; - CREATE TABLE range_hash - ( - month_code VARCHAR2 ( 30 ) NOT NULL , - dept_code VARCHAR2 ( 30 ) NOT NULL , - user_no VARCHAR2 ( 30 ) NOT NULL , - sales_amt int - ) - PARTITION BY RANGE (month_code) SUBPARTITION BY HASH (dept_code) - ( - PARTITION p_201901 VALUES LESS THAN( '201903' ) - ( - SUBPARTITION p_201901_a, - SUBPARTITION p_201901_b - ), - PARTITION p_201902 VALUES LESS THAN( '201904' ) - ( - SUBPARTITION p_201902_a, - SUBPARTITION p_201902_b - ) - ); - insert into range_hash values('201902', '1', '1', 1); - insert into range_hash values('201902', '2', '1', 1); - insert into range_hash values('201902', '1', '1', 1); - insert into range_hash values('201903', '2', '1', 1); - insert into range_hash values('201903', '1', '1', 1); - insert into range_hash values('201903', '2', '1', 1); - select * from range_hash; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 2 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201903 | 2 | 1 | 1 - 201903 | 2 | 1 | 1 - 201903 | 1 | 1 | 1 - (6 rows) - - drop table range_hash; - CREATE TABLE range_range - ( - month_code VARCHAR2 ( 30 ) NOT NULL , - dept_code VARCHAR2 ( 30 ) NOT NULL , - user_no VARCHAR2 ( 30 ) NOT NULL , - sales_amt int - ) - PARTITION BY RANGE (month_code) SUBPARTITION BY RANGE (dept_code) - ( - PARTITION p_201901 VALUES LESS THAN( '201903' ) - ( - SUBPARTITION p_201901_a VALUES LESS THAN( '2' ), - SUBPARTITION p_201901_b VALUES LESS THAN( '3' ) - ), - PARTITION p_201902 VALUES LESS THAN( '201904' ) - ( - SUBPARTITION p_201902_a VALUES LESS THAN( '2' ), - SUBPARTITION p_201902_b VALUES LESS THAN( '3' ) - ) - ); - insert into range_range values('201902', '1', '1', 1); - insert into range_range values('201902', '2', '1', 1); - insert into range_range values('201902', '1', '1', 1); - insert into range_range values('201903', '2', '1', 1); - insert into range_range values('201903', '1', '1', 1); - insert into range_range values('201903', '2', '1', 1); - select * from range_range; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 2 | 1 | 1 - 201903 | 1 | 1 | 1 - 201903 | 2 | 1 | 1 - 201903 | 2 | 1 | 1 - (6 rows) - - drop table range_range; - CREATE TABLE hash_list - ( - month_code VARCHAR2 ( 30 ) NOT NULL , - dept_code VARCHAR2 ( 30 ) NOT NULL , - user_no VARCHAR2 ( 30 ) NOT NULL , - sales_amt int - ) - PARTITION BY hash (month_code) SUBPARTITION BY LIST (dept_code) - ( - PARTITION p_201901 - ( - SUBPARTITION p_201901_a VALUES ( '1' ), - SUBPARTITION p_201901_b VALUES ( '2' ) - ), - PARTITION p_201902 - ( - SUBPARTITION p_201902_a VALUES ( '1' ), - SUBPARTITION p_201902_b VALUES ( '2' ) - ) - ); - insert into hash_list values('201901', '1', '1', 1); - insert into hash_list values('201901', '2', '1', 1); - insert into hash_list values('201901', '1', '1', 1); - insert into hash_list values('201903', '2', '1', 1); - insert into hash_list values('201903', '1', '1', 1); - insert into hash_list values('201903', '2', '1', 1); - select * from hash_list; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201903 | 2 | 1 | 1 - 201903 | 2 | 1 | 1 - 201903 | 1 | 1 | 1 - 201901 | 2 | 1 | 1 - 201901 | 1 | 1 | 1 - 201901 | 1 | 1 | 1 - (6 rows) - - drop table hash_list; - CREATE TABLE hash_hash - ( - month_code VARCHAR2 ( 30 ) NOT NULL , - dept_code VARCHAR2 ( 30 ) NOT NULL , - user_no VARCHAR2 ( 30 ) NOT NULL , - sales_amt int - ) - PARTITION BY hash (month_code) SUBPARTITION BY hash (dept_code) - ( - PARTITION p_201901 - ( - SUBPARTITION p_201901_a, - SUBPARTITION p_201901_b - ), - PARTITION p_201902 - ( - SUBPARTITION p_201902_a, - SUBPARTITION p_201902_b - ) - ); - insert into hash_hash values('201901', '1', '1', 1); - insert into hash_hash values('201901', '2', '1', 1); - insert into hash_hash values('201901', '1', '1', 1); - insert into hash_hash values('201903', '2', '1', 1); - insert into hash_hash values('201903', '1', '1', 1); - insert into hash_hash values('201903', '2', '1', 1); - select * from hash_hash; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201903 | 2 | 1 | 1 - 201903 | 2 | 1 | 1 - 201903 | 1 | 1 | 1 - 201901 | 2 | 1 | 1 - 201901 | 1 | 1 | 1 - 201901 | 1 | 1 | 1 - (6 rows) - - drop table hash_hash; - CREATE TABLE hash_range - ( - month_code VARCHAR2 ( 30 ) NOT NULL , - dept_code VARCHAR2 ( 30 ) NOT NULL , - user_no VARCHAR2 ( 30 ) NOT NULL , - sales_amt int - ) - PARTITION BY hash (month_code) SUBPARTITION BY range (dept_code) - ( - PARTITION p_201901 - ( - SUBPARTITION p_201901_a VALUES LESS THAN ( '2' ), - SUBPARTITION p_201901_b VALUES LESS THAN ( '3' ) - ), - PARTITION p_201902 - ( - SUBPARTITION p_201902_a VALUES LESS THAN ( '2' ), - SUBPARTITION p_201902_b VALUES LESS THAN ( '3' ) - ) - ); - insert into hash_range values('201901', '1', '1', 1); - insert into hash_range values('201901', '2', '1', 1); - insert into hash_range values('201901', '1', '1', 1); - insert into hash_range values('201903', '2', '1', 1); - insert into hash_range values('201903', '1', '1', 1); - insert into hash_range values('201903', '2', '1', 1); - select * from hash_range; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201903 | 1 | 1 | 1 - 201903 | 2 | 1 | 1 - 201903 | 2 | 1 | 1 - 201901 | 1 | 1 | 1 - 201901 | 1 | 1 | 1 - 201901 | 2 | 1 | 1 - (6 rows) - ``` - -- 示例2:对二级分区表进行DML指定分区操作 - - ``` - CREATE TABLE range_list - ( - month_code VARCHAR2 ( 30 ) NOT NULL , - dept_code VARCHAR2 ( 30 ) NOT NULL , - user_no VARCHAR2 ( 30 ) NOT NULL , - sales_amt int - ) - PARTITION BY RANGE (month_code) SUBPARTITION BY LIST (dept_code) - ( - PARTITION p_201901 VALUES LESS THAN( '201903' ) - ( - SUBPARTITION p_201901_a values ('1'), - SUBPARTITION p_201901_b values ('2') - ), - PARTITION p_201902 VALUES LESS THAN( '201910' ) - ( - SUBPARTITION p_201902_a values ('1'), - SUBPARTITION p_201902_b values ('2') - ) - ); - --指定一级分区插入数据 - insert into range_list partition (p_201901) values('201902', '1', '1', 1); - --实际分区和指定分区不一致,报错 - insert into range_list partition (p_201902) values('201902', '1', '1', 1); - ERROR: inserted partition key does not map to the table partition - DETAIL: N/A. - --指定二级分区插入数据 - insert into range_list subpartition (p_201901_a) values('201902', '1', '1', 1); - --实际分区和指定分区不一致,报错 - insert into range_list subpartition (p_201901_b) values('201902', '1', '1', 1); - ERROR: inserted subpartition key does not map to the table subpartition - DETAIL: N/A. - insert into range_list partition for ('201902') values('201902', '1', '1', 1); - insert into range_list subpartition for ('201902','1') values('201902', '1', '1', 1); - - --指定分区查询数据 - select * from range_list partition (p_201901); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - (4 rows) - - select * from range_list subpartition (p_201901_a); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - (4 rows) - - select * from range_list partition for ('201902'); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - (4 rows) - - select * from range_list subpartition for ('201902','1'); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - (4 rows) - - --指定分区更新数据 - update range_list partition (p_201901) set user_no = '2'; - select * from range_list; - select *from range_list; month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 1 | 2 | 1 - 201902 | 1 | 2 | 1 - 201902 | 1 | 2 | 1 - 201902 | 1 | 2 | 1 - (4 rows) - update range_list subpartition (p_201901_a) set user_no = '3'; - select * from range_list; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 1 | 3 | 1 - 201902 | 1 | 3 | 1 - 201902 | 1 | 3 | 1 - 201902 | 1 | 3 | 1 - (4 rows) - update range_list partition for ('201902') set user_no = '4'; - select * from range_list; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 1 | 4 | 1 - 201902 | 1 | 4 | 1 - 201902 | 1 | 4 | 1 - 201902 | 1 | 4 | 1 - (4 rows) - update range_list subpartition for ('201902','2') set user_no = '5'; - openGauss=# select *from range_list; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 1 | 4 | 1 - 201902 | 1 | 4 | 1 - 201902 | 1 | 4 | 1 - 201902 | 1 | 4 | 1 - (4 rows) - select * from range_list; - - --指定分区删除数据 - delete from range_list partition (p_201901); - DELETE 4 - delete from range_list partition for ('201903'); - DELETE 0 - delete from range_list subpartition (p_201901_a); - DELETE 0 - delete from range_list subpartition for ('201903','2'); - DELETE 0 - --参数sql_compatibility=B时,可指定多分区删除数据 - delete from range_list as t partition (p_201901_a, p_201901); - DELETE 0 - - --指定分区insert数据 - insert into range_list partition (p_201901) values('201902', '1', '1', 1) ON DUPLICATE KEY UPDATE sales_amt = 5; - insert into range_list subpartition (p_201901_a) values('201902', '1', '1', 1) ON DUPLICATE KEY UPDATE sales_amt = 10; - insert into range_list partition for ('201902') values('201902', '1', '1', 1) ON DUPLICATE KEY UPDATE sales_amt = 30; - insert into range_list subpartition for ('201902','1') values('201902', '1', '1', 1) ON DUPLICATE KEY UPDATE sales_amt = 40; - select * from range_list; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - (4 rows) - - --指定分区merge into数据 - CREATE TABLE newrange_list - ( - month_code VARCHAR2 ( 30 ) NOT NULL , - dept_code VARCHAR2 ( 30 ) NOT NULL , - user_no VARCHAR2 ( 30 ) NOT NULL , - sales_amt int - ) - PARTITION BY RANGE (month_code) SUBPARTITION BY LIST (dept_code) - ( - PARTITION p_201901 VALUES LESS THAN( '201903' ) - ( - SUBPARTITION p_201901_a values ('1'), - SUBPARTITION p_201901_b values ('2') - ), - PARTITION p_201902 VALUES LESS THAN( '201910' ) - ( - SUBPARTITION p_201902_a values ('1'), - SUBPARTITION p_201902_b values ('2') - ) - ); - insert into newrange_list values('201902', '1', '1', 1); - insert into newrange_list values('201903', '1', '1', 2); - - MERGE INTO range_list partition (p_201901) p - USING newrange_list partition (p_201901) np - ON p.month_code= np.month_code - WHEN MATCHED THEN - UPDATE SET dept_code = np.dept_code, user_no = np.user_no, sales_amt = np.sales_amt - WHEN NOT MATCHED THEN - INSERT VALUES (np.month_code, np.dept_code, np.user_no, np.sales_amt); - - select * from range_list; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - (4 rows) - - MERGE INTO range_list partition for ('201901') p - USING newrange_list partition for ('201901') np - ON p.month_code= np.month_code - WHEN MATCHED THEN - UPDATE SET dept_code = np.dept_code, user_no = np.user_no, sales_amt = np.sales_amt - WHEN NOT MATCHED THEN - INSERT VALUES (np.month_code, np.dept_code, np.user_no, np.sales_amt); - - select * from range_list; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - (4 rows) - - MERGE INTO range_list subpartition (p_201901_a) p - USING newrange_list subpartition (p_201901_a) np - ON p.month_code= np.month_code - WHEN MATCHED THEN - UPDATE SET dept_code = np.dept_code, user_no = np.user_no, sales_amt = np.sales_amt - WHEN NOT MATCHED THEN - INSERT VALUES (np.month_code, np.dept_code, np.user_no, np.sales_amt); - - select * from range_list; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - (4 rows) - - MERGE INTO range_list subpartition for ('201901', '1') p - USING newrange_list subpartition for ('201901', '1') np - ON p.month_code= np.month_code - WHEN MATCHED THEN - UPDATE SET dept_code = np.dept_code, user_no = np.user_no, sales_amt = np.sales_amt - WHEN NOT MATCHED THEN - INSERT VALUES (np.month_code, np.dept_code, np.user_no, np.sales_amt); - - select * from range_list; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - (4 rows) - ``` - -- 示例3:对二级分区表进行truncate操作 - - ``` - CREATE TABLE list_list - ( - month_code VARCHAR2 ( 30 ) NOT NULL , - dept_code VARCHAR2 ( 30 ) NOT NULL , - user_no VARCHAR2 ( 30 ) NOT NULL , - sales_amt int - ) - PARTITION BY LIST (month_code) SUBPARTITION BY LIST (dept_code) - ( - PARTITION p_201901 VALUES ( '201902' ) - ( - SUBPARTITION p_201901_a VALUES ( '1' ), - SUBPARTITION p_201901_b VALUES ( default ) - ), - PARTITION p_201902 VALUES ( '201903' ) - ( - SUBPARTITION p_201902_a VALUES ( '1' ), - SUBPARTITION p_201902_b VALUES ( '2' ) - ) - ); - insert into list_list values('201902', '1', '1', 1); - insert into list_list values('201902', '2', '1', 1); - insert into list_list values('201902', '1', '1', 1); - insert into list_list values('201903', '2', '1', 1); - insert into list_list values('201903', '1', '1', 1); - insert into list_list values('201903', '2', '1', 1); - select * from list_list; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201903 | 2 | 1 | 1 - 201903 | 2 | 1 | 1 - 201903 | 1 | 1 | 1 - 201902 | 2 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - (6 rows) - - select * from list_list partition (p_201901); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 2 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - (3 rows) - - alter table list_list truncate partition p_201901; - select * from list_list partition (p_201901); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - (0 rows) - - select * from list_list partition (p_201902); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201903 | 2 | 1 | 1 - 201903 | 2 | 1 | 1 - 201903 | 1 | 1 | 1 - (3 rows) - - alter table list_list truncate partition p_201902; - select * from list_list partition (p_201902); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - (0 rows) - - select * from list_list; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - (0 rows) - - insert into list_list values('201902', '1', '1', 1); - insert into list_list values('201902', '2', '1', 1); - insert into list_list values('201902', '1', '1', 1); - insert into list_list values('201903', '2', '1', 1); - insert into list_list values('201903', '1', '1', 1); - insert into list_list values('201903', '2', '1', 1); - select * from list_list subpartition (p_201901_a); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - (2 rows) - - alter table list_list truncate subpartition p_201901_a; - select * from list_list subpartition (p_201901_a); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - (0 rows) - - select * from list_list subpartition (p_201901_b); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 2 | 1 | 1 - (1 row) - - alter table list_list truncate subpartition p_201901_b; - select * from list_list subpartition (p_201901_b); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - (0 rows) - - select * from list_list subpartition (p_201902_a); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201903 | 1 | 1 | 1 - (1 row) - - alter table list_list truncate subpartition p_201902_a; - select * from list_list subpartition (p_201902_a); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - (0 rows) - - select * from list_list subpartition (p_201902_b); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201903 | 2 | 1 | 1 - 201903 | 2 | 1 | 1 - (2 rows) - - alter table list_list truncate subpartition p_201902_b; - select * from list_list subpartition (p_201902_b); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - (0 rows) - - select * from list_list; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - (0 rows) - - drop table list_list; - - ``` - -- 示例4:对二级分区表进行split操作 - - ``` - CREATE TABLE list_list - ( - month_code VARCHAR2 ( 30 ) NOT NULL , - dept_code VARCHAR2 ( 30 ) NOT NULL , - user_no VARCHAR2 ( 30 ) NOT NULL , - sales_amt int - ) - PARTITION BY LIST (month_code) SUBPARTITION BY LIST (dept_code) - ( - PARTITION p_201901 VALUES ( '201902' ) - ( - SUBPARTITION p_201901_a VALUES ( '1' ), - SUBPARTITION p_201901_b VALUES ( default ) - ), - PARTITION p_201902 VALUES ( '201903' ) - ( - SUBPARTITION p_201902_a VALUES ( '1' ), - SUBPARTITION p_201902_b VALUES ( default ) - ) - ); - insert into list_list values('201902', '1', '1', 1); - insert into list_list values('201902', '2', '1', 1); - insert into list_list values('201902', '1', '1', 1); - insert into list_list values('201903', '2', '1', 1); - insert into list_list values('201903', '1', '1', 1); - insert into list_list values('201903', '2', '1', 1); - select * from list_list; - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201903 | 2 | 1 | 1 - 201903 | 2 | 1 | 1 - 201903 | 1 | 1 | 1 - 201902 | 2 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - (6 rows) - - select * from list_list subpartition (p_201901_a); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - (2 rows) - - select * from list_list subpartition (p_201901_b); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 2 | 1 | 1 - (1 row) - - alter table list_list split subpartition p_201901_b values (2) into - ( - subpartition p_201901_b, - subpartition p_201901_c - ); - select * from list_list subpartition (p_201901_a); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - (2 rows) - - select * from list_list subpartition (p_201901_b); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 2 | 1 | 1 - (1 row) - - select * from list_list subpartition (p_201901_c); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - (0 rows) - - select * from list_list partition (p_201901); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201902 | 2 | 1 | 1 - 201902 | 1 | 1 | 1 - 201902 | 1 | 1 | 1 - (3 rows) - - select * from list_list subpartition (p_201902_a); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201903 | 1 | 1 | 1 - (1 row) - - select * from list_list subpartition (p_201902_b); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201903 | 2 | 1 | 1 - 201903 | 2 | 1 | 1 - (2 rows) - - alter table list_list split subpartition p_201902_b values (3) into - ( - subpartition p_201902_b, - subpartition p_201902_c - ); - select * from list_list subpartition (p_201902_a); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201903 | 1 | 1 | 1 - (1 row) - - select * from list_list subpartition (p_201902_b); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - (0 rows) - - select * from list_list subpartition (p_201902_c); - month_code | dept_code | user_no | sales_amt - ------------+-----------+---------+----------- - 201903 | 2 | 1 | 1 - 201903 | 2 | 1 | 1 - (2 rows) - - drop table list_list; - ``` - - +# CREATE TABLE SUBPARTITION + +## 功能描述 + +创建二级分区表。分区表是把逻辑上的一张表根据某种方案分成几张物理块进行存储,这张逻辑上的表称之为分区表,物理块称之为分区。分区表是一张逻辑表,不存储数据,数据实际是存储在分区上的。对于二级分区表,顶层节点表和一级分区都是逻辑表,不存储数据,只有二级分区(叶子节点)存储数据。 + +二级分区表的分区方案是由两个一级分区的分区方案组合而来的,一级分区的分区方案详见章节CREATE TABLE PARTITION。 + +常见的二级分区表组合方案有Range-Range分区、Range-List分区、Range-Hash分区、List-Range分区、List-List分区、List-Hash分区、Hash-Range分区、Hash-List分区、Hash-Hash分区等。目前二级分区仅支持行存表。 + +## 注意事项 + +- 二级分区表有两个分区键,每个分区键只能支持1列。 +- 唯一约束和主键约束的约束键包含所有分区键将为约束创建LOCAL索引,否则创建GLOBAL索引。 +- 二级分区表的二级分区(叶子节点)个数不能超过1048575个,一级分区无限制,但一级分区下面至少有一个二级分区。 +- 二级分区表只支持行存,不支持列存、段页式、hashbucket。 +- 不支持Upsert、Merge into。 +- 指定分区查询时,如select \* from tablename partition/subpartition \(partitionname\),关键字partition和subpartition注意不要写错。如果写错,查询不会报错,这时查询会变为对表起别名进行查询。 +- 不支持对二级分区 subpartition for \(values\)查询。如select \* from tablename subpartition for \(values\)。 +- 不支持密态数据库、账本数据库和行级访问控制。 +- 对于二级分区表PARTITION FOR \(values\)语法,values只能是常量。 +- 对于分区表PARTITION/SUBPARTITION FOR \(values\)语法,values在需要数据类型转换时,建议使用强制类型转换,以防隐式类型转换结果与预期不符。 +- 指定分区语句目前不能走全局索引扫描。 +- 当分区数太多导致内存不足时,会间接导致性能急剧下降。 +- 目前Hash分区是按倒序排列的,即通过哈希和取余计算后得到的分区下标与创建顺序相反,同样EXPLAIN计划显示的Selected Partitions的序号排序也与创建顺序相反。List分区是按分区数组的第一个元素排序的。 + +## 语法格式 + +``` +CREATE TABLE [ IF NOT EXISTS ] subpartition_table_name +( +{ column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ] +| table_constraint +| LIKE source_table [ like_option [...] ] }[, ... ] +) +[ AUTO_INCREMENT [ = ] value ] +[ WITH ( {storage_parameter = value} [, ... ] ) ] +[ COMPRESS | NOCOMPRESS ] +[ TABLESPACE tablespace_name ] +PARTITION BY {RANGE [ COLUMNS ] | LIST [ COLUMNS ] | HASH | KEY} (partition_key) [ PARTITIONS integer ] SUBPARTITION BY {RANGE | LIST | HASH | KEY} (subpartition_key) [ SUBPARTITIONS integer ] +( + PARTITION partition_name1 [ VALUES LESS THAN {(val1) | MAXVALUE} | VALUES [IN] (val1[, …]) ] [ TABLESPACE [=] tablespace ] + ( + { SUBPARTITION subpartition_name1 [ VALUES LESS THAN (val1_1) | VALUES (val1_1[, …])] [ TABLESPACE [=] tablespace ] [COMMENT {=| } 'text' ] } [, ...] + )[, ...] +)[ { ENABLE | DISABLE } ROW MOVEMENT ]; +``` + +- 列约束column\_constraint: + + ``` + [ CONSTRAINT constraint_name ] + { NOT NULL | + NULL | + CHECK ( expression ) | + DEFAULT default_e xpr | + GENERATED ALWAYS AS ( generation_expr ) [STORED] | + AUTO_INCREMENT | + UNIQUE [KEY] 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 ] + [ COMMENT {=| } 'text' ] + ``` + +- 表约束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 | + FOREIGN KEY [ index_name ] ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] + [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] } + [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] + [ COMMENT {=| } 'text' ] + ``` + + +- like选项like\_option: + + ``` + { INCLUDING | EXCLUDING } { DEFAULTS | GENERATED | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | RELOPTIONS| ALL } + ``` + + +- 索引存储参数index\_parameters: + + ``` + [ WITH ( {storage_parameter = value} [, ... ] ) ] + [ USING INDEX TABLESPACE tablespace_name ] + ``` + + +## 参数说明 + +- **IF NOT EXISTS** + + 如果已经存在相同名称的表,不会抛出一个错误,而会发出一个通知,告知表关系已存在。 + +- **subpartition\_table\_name** + + 二级分区表的名称。 + + 取值范围:字符串,要符合标识符的命名规范。 + + +- **column\_name** + + 新表中要创建的字段名。 + + 取值范围:字符串,要符合标识符的命名规范。 + +- **data\_type** + + 字段的数据类型。 + +- **COLLATE collation** + + COLLATE子句指定列的排序规则(该列必须是可排列的数据类型)。如果没有指定,则使用默认的排序规则。排序规则可以使用“select \* from pg\_collation;”命令从pg\_collation系统表中查询,默认的排序规则为查询结果中以default开始的行。 + +- **CONSTRAINT constraint\_name** + + 列约束或表约束的名称。可选的约束子句用于声明约束,新行或者更新的行必须满足这些约束才能成功插入或更新。 + + 定义约束有两种方法: + + - 列约束:作为一个列定义的一部分,仅影响该列。 + - 表约束:不和某个列绑在一起,可以作用于多个列。 + + >![](public_sys-resources/icon-notice.png) **须知:** + >在B模式数据库下(即sql\_compatibility = 'B')constraint\_name为可选项,在其他模式数据库下,必须加上constraint\_name。 + +- **index\_name** + + 索引名。 + + >![](public_sys-resources/icon-notice.png) **须知:** + >- index\_name仅在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库下不支持。 + >- 对于外键约束,constraint\_name和index\_name同时指定时,索引名为constraint\_name。 + >- 对于唯一键约束,constraint\_name和index\_name同时指定时,索引名以index\_name。 + +- **USING method** + + 指定创建索引的方法。 + + 取值范围参考[参数说明](CREATE-INDEX.md)中的USING method。 + + >![](public_sys-resources/icon-notice.png) **须知:** + >- USING method仅在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库下不支持。 + >- 在B模式下,未指定USING method时,对于ASTORE的存储方式,默认索引方法为btree;对于USTORE的存储方式,默认索引方法为ubtree。 + +- **ASC | DESC** + + ASC表示指定按升序排序(默认)。DESC指定按降序排序。 + + >![](public_sys-resources/icon-notice.png) **须知:** + > + >ASC|DESC只在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库不支持。 + +- **LIKE source\_table \[ like\_option ... \]** + + 二级分区表暂不支持该功能。 + +- **AUTO\_INCREMENT \[ = \] value** + + 这个子句为自动增长列指定一个初始值,value必须为正整数,不得超过2127-1。 + + >![](public_sys-resources/icon-notice.png) **须知:** + > + >该子句仅在参数sql\_compatibility=B时有效。 + + +- **WITH \( storage\_parameter \[= value\] \[, ... \] \)** + + 这个子句为表或索引指定一个可选的存储参数。参数的详细描述如下所示: + + - **FILLFACTOR** + + 一个表的填充因子(fillfactor)是一个介于10和100之间的百分数。100(完全填充)是默认值。如果指定了较小的填充因子,INSERT操作仅按照填充因子指定的百分率填充表页。每个页上的剩余空间将用于在该页上更新行,这就使得UPDATE有机会在同一页上放置同一条记录的新版本,这比把新版本放置在其他页上更有效。对于一个从不更新的表将填充因子设为100是最佳选择,但是对于频繁更新的表,选择较小的填充因子则更加合适。该参数对于列存表没有意义。 + + 取值范围:10\~100 + + - **ORIENTATION** + + 决定了表的数据的存储方式。 + + 取值范围: + + - COLUMN:表的数据将以列式存储。 + - ROW(缺省值):表的数据将以行式存储。 + + >![](public_sys-resources/icon-notice.png) **须知:** + > + >orientation不支持修改。 + - **COMPRESSTYPE** + + 行存表参数,设置行存表压缩算法。1代表pglz算法(不推荐使用),2代表zstd算法,默认不压缩。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。(仅支持ASTORE和USTORE下的普通表和分区表) + 该特性在金融版本下不支持 + + 取值范围:0\~2,默认值为0。 + + - **COMPRESS\_LEVEL** + + 行存表参数,设置行存表压缩算法等级,仅当COMPRESSTYPE为2时生效。压缩等级越高,表的压缩效果越好,表的访问速度越慢。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + + 取值范围:-31\~31,默认值为0。 + + - **COMPRESS\_CHUNK_SIZE** + + 行存表参数,设置行存表压缩chunk块大小,仅当COMPRESSTYPE不为0时生效。chunk数据块越小,预期能达到的压缩效果越好,同时数据越离散,影响表的访问速度。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + 取值范围:与页面大小有关。在页面大小为8k场景,取值范围为:512、1024、2048、4096。 + + 默认值:4096 + + - **COMPRESS_PREALLOC_CHUNKS** + + 行存表参数,设置行存表压缩chunk块预分配数量。预分配数量越大,表的压缩率相对越差,离散度越小,访问性能越好。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + + 取值范围:0\~7,默认值为0。 + + - 当COMPRESS\_CHUNK_SIZE为512和1024时,支持预分配设置最大为7。 + - 当COMPRESS\_CHUNK_SIZE为2048时,支持预分配设置最大为3。 + - 当COMPRESS\_CHUNK_SIZE为4096时,支持预分配设置最大为1。 + + - **COMPRESS_BYTE_CONVERT** + + 行存表参数,设置行存表压缩字节转换预处理,仅当COMPRESSTYPE不为0时生效。在一些场景下可以提升压缩效果,同时会导致一定性能劣化。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + + 取值范围:布尔值,默认关闭。 + + - **COMPRESS_DIFF_CONVERT** + + 行存表参数,设置行存表压缩字节差分预处理。只能与compress_byte_convert一起使用。在一些场景下可以提升压缩效果,同时会导致一定性能劣化。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + + 取值范围:布尔值,默认关闭。 + + - STORAGE\_TYPE + + 指定存储引擎类型,该参数设置成功后就不再支持修改。 + + 取值范围: + + - USTORE,表示表支持Inplace-Update存储引擎。特别需要注意,使用USTORE表,必须要开启track\_counts和track\_activities参数,否则会引起空间膨胀。 + + - ASTORE,表示表支持Append-Only存储引擎。 + + 默认值: 不指定表时,默认是Append-Only存储。 +- **COMPRESSION** + + - 列存表的有效值为LOW/MIDDLE/HIGH/YES/NO,压缩级别依次升高,默认值为LOW。 +- 行存表不支持压缩。 + +- **MAX\_BATCHROW** + + 指定了在数据加载过程中一个存储单元可以容纳记录的最大数目。该参数只对列存表有效。 + + 取值范围:10000\~60000,默认60000。 + +- **PARTIAL\_CLUSTER\_ROWS** + + 指定了在数据加载过程中进行将局部聚簇存储的记录数目。该参数只对列存表有效。 + + 取值范围:大于等于MAX\_BATCHROW,建议取值为MAX\_BATCHROW的整数倍数。 + +- **DELTAROW\_THRESHOLD** + + 预留参数。该参数只对列存表有效。 + + 取值范围:0~9999 + + +- **COMPRESS / NOCOMPRESS** + + 创建一个新表时,需要在创建表语句中指定关键字COMPRESS,这样,当对该表进行批量插入时就会触发压缩特性。该特性会在页范围内扫描所有元组数据,生成字典、压缩元组数据并进行存储。指定关键字NOCOMPRESS则不对表进行压缩。行存表不支持压缩。该参数已废弃,列存表请使用COMPRESSION修改压缩等级。 + + 缺省值为NOCOMPRESS,即不对元组数据进行压缩。 + +- **TABLESPACE tablespace\_name** + + 指定新表将要在tablespace\_name表空间内创建。如果没有声明,将使用默认表空间。 + +- **PARTITION BY \{RANGE \[COLUMNS\] | LIST \[COLUMNS\] | HASH | KEY\} \(partition\_key\)** + + - 对于partition\_key,分区策略的分区键仅支持1列。 + - 分区键支持的数据类型和一级分区表约束保持一致。 + - COLUMNS关键字只能在sql\_compatibility='B'时使用,只能加在RANGE或LIST之后,“RANGE COLUMNS” 语义同 “RANGE”,“LIST COLUMNS” 语义同 “LIST”。 + - KEY关键字只能在sql\_compatibility='B'时使用,KEY与HASH同义。 + +- **SUBPARTITION BY \{RANGE | LIST | HASH | KEY\} \(subpartition\_key\)** + + - 对于subpartition\_key,分区策略的分区键仅支持1列。 + - 分区键支持的数据类型和一级分区表约束保持一致。 + - KEY关键字只能在sql\_compatibility='B'时使用,KEY与HASH同义。 + +- **PARTITIONS integer** + + 指定分区个数。 + + integer为分区数,必须为大于0的整数,且不得大于1048575。 + + - 当在RANGE和LIST分区后指定此子句时,必须显式定义每个分区,且定义分区的数量必须与integer值相等。只能在sql\_compatibility='B'时在RANGE和LIST分区后指定此子句。 + - 当在HASH和KEY分区后指定此子句时,若不列出各个分区定义,将自动生成integer个分区,自动生成的分区名为“p+数字”,数字依次为0到integer-1,分区的表空间默认为此表的表空间;也可以显式列出每个分区定义,此时定义分区的数量必须与integer值相等。若既不列出分区定义,也不指定分区数量,将创建唯一一个分区。 + +- **SUBPARTITIONS integer** + + 指定二级分区数量。 + + integer为二级分区个数,必须为大于0的整数,且不得大于1048575。 + + - 只能在HASH和KEY二级分区后指定此子句。 + - 若不列出各个二级分区定义,将在每个一级分区内自动生成integer个二级分区,自动生成的二级分区名为“一级分区名+sp+数字”,数字依次为0到integer-1,分区的表空间默认为此表的表空间。 + - 也可以列出每个二级分区定义,此时二级分区的数量必须与integer值相等。 + - 若既不列出每个二级分区定义,也不指定二级分区数量,将创建唯一一个二级分区。 + + +- **\{ ENABLE | DISABLE \} ROW MOVEMENT** + + 行迁移开关。 + + 如果进行UPDATE操作时,更新了元组在分区键上的值,造成了该元组所在分区发生变化,就会根据该开关给出报错信息,或者进行元组在分区间的转移。 + + 取值范围: + + - ENABLE(缺省值):行迁移开关打开。 + - DISABLE:行迁移开关关闭。 + +- **NOT NULL** + + 字段值不允许为NULL。ENABLE用于语法兼容,可省略。 + +- **NULL** + + 字段值允许NULL ,这是缺省。 + + 这个子句只是为和非标准SQL数据库兼容。不建议使用。 + +- **CHECK \(condition\) \[ NO INHERIT \]** + + CHECK约束声明一个布尔表达式,每次要插入的新行或者要更新的行的新值必须使表达式结果为真或未知才能成功,否则会抛出一个异常并且不会修改数据库。 + + 声明为字段约束的检查约束应该只引用该字段的数值,而在表约束里出现的表达式可以引用多个字段。 + + 用NO INHERIT标记的约束将不会传递到子表中去。 + + ENABLE用于语法兼容,可省略。 + +- **DEFAULT default\_expr** + + DEFAULT子句给字段指定缺省值。该数值可以是任何不含变量的表达式\(不允许使用子查询和对本表中的其他字段的交叉引用\)。缺省表达式的数据类型必须和字段类型匹配。 + + 缺省表达式将被用于任何未声明该字段数值的插入操作。如果没有指定缺省值则缺省值为NULL 。 + +- **GENERATED ALWAYS AS \( generation\_expr \) [STORED]** + + 该子句将字段创建为生成列,生成列的值在写入(插入或更新)数据时由generation\_expr计算得到,STORED表示像普通列一样存储生成列的值。 + + >![](public_sys-resources/icon-note.png) **说明:** + > + >- STORED关键字可省略,与不省略STORED语义相同。 + >- 生成表达式不能以任何方式引用当前行以外的其他数据。生成表达式不能引用其他生成列,不能引用系统列。生成表达式不能返回结果集,不能使用子查询,不能使用聚集函数,不能使用窗口函数。生成表达式调用的函数只能是不可变(IMMUTABLE)函数。 + >- 不能为生成列指定默认值。 + >- 生成列不能作为分区键的一部分。 + >- 生成列不能和ON UPDATE约束字句的CASCADE、SET NULL、SET DEFAULT动作同时指定。生成列不能和ON DELETE约束字句的SET NULL、SET DEFAULT动作同时指定。 + >- 修改和删除生成列的方法和普通列相同。删除生成列依赖的普通列,生成列被自动删除。不能改变生成列所依赖的列的类型。 + >- 生成列不能被直接写入。在INSERT或UPDATE命令中, 不能为生成列指定值, 但是可以指定关键字DEFAULT。 + >- 生成列的权限控制和普通列一样。 + > + > + >- 不能为生成列指定默认值。 + > + >- 生成列不能作为分区键的一部分。 + > + >- 生成列不能和ON UPDATE约束字句的CASCADE、SET NULL、SET DEFAULT动作同时指定。生成列不能和ON DELETE约束字句的SET NULL、SET DEFAULT动作同时指定。 + > + >- 修改和删除生成列的方法和普通列相同。删除生成列依赖的普通列,生成列被自动删除。不能改变生成列所依赖的列的类型。 + > + >- 生成列不能被直接写入。在INSERT或UPDATE命令中, 不能为生成列指定值, 但是可以指定关键字DEFAULT。 + > + >- 生成列的权限控制和普通列一样。 + > + >- 列存表、内存表MOT不支持生成列。外表中仅postgres\_fdw支持生成列。 + +- **AUTO\_INCREMENT** + + 指定列为自动增长列。 + + 详见:[AUTO\_INCREMENT](CREATE-TABLE.md)。 + +- **UNIQUE index\_parameters** + + **UNIQUE \( column\_name \[, ... \] \) index\_parameters** + + UNIQUE约束表示表里的一个字段或多个字段的组合必须在全表范围内唯一。 + + 对于唯一约束,NULL被认为是互不相等的。 + +- **PRIMARY KEY index\_parameters** + + **PRIMARY KEY \( column\_name \[, ... \] \) index\_parameters** + + 主键约束声明表中的一个或者多个字段只能包含唯一的非NULL值。 + + 一个表只能声明一个主键。 + +- **DEFERRABLE | NOT DEFERRABLE** + + 这两个关键字设置该约束是否可推迟。一个不可推迟的约束将在每条命令之后马上检查。可推迟约束可以推迟到事务结尾使用SET CONSTRAINTS命令检查。缺省是NOT DEFERRABLE。目前,UNIQUE约束、主键约束、外键约束可以接受这个子句。所有其他约束类型都是不可推迟的。 + +- **INITIALLY IMMEDIATE | INITIALLY DEFERRED** + + 如果约束是可推迟的,则这个子句声明检查约束的缺省时间。 + + - 如果约束是INITIALLY IMMEDIATE(缺省),则在每条语句执行之后就立即检查它; + - 如果约束是INITIALLY DEFERRED ,则只有在事务结尾才检查它。 + + 约束检查的时间可以用SET CONSTRAINTS命令修改。 + +- **USING INDEX TABLESPACE tablespace\_name** + + 为UNIQUE或PRIMARY KEY约束相关的索引声明一个表空间。如果没有提供这个子句,这个索引将在default\_tablespace中创建,如果default\_tablespace为空,将使用数据库的缺省表空间。 + +- COMMENT {=| } 'text': + + 二级分区表的分区中,该字段无实际意义,仅作语法兼容。在数据库中使用该语法时会有告警提示。 + +## 示例 + +- 示例1:创建各种组合类型的二级分区表 + + ``` + CREATE TABLE list_list + ( + month_code VARCHAR2 ( 30 ) NOT NULL , + dept_code VARCHAR2 ( 30 ) NOT NULL , + user_no VARCHAR2 ( 30 ) NOT NULL , + sales_amt int + ) + PARTITION BY LIST (month_code) SUBPARTITION BY LIST (dept_code) + ( + PARTITION p_201901 VALUES ( '201902' ) + ( + SUBPARTITION p_201901_a VALUES ( '1' ), + SUBPARTITION p_201901_b VALUES ( '2' ) + ), + PARTITION p_201902 VALUES ( '201903' ) + ( + SUBPARTITION p_201902_a VALUES ( '1' ), + SUBPARTITION p_201902_b VALUES ( '2' ) + ) + ); + insert into list_list values('201902', '1', '1', 1); + insert into list_list values('201902', '2', '1', 1); + insert into list_list values('201902', '1', '1', 1); + insert into list_list values('201903', '2', '1', 1); + insert into list_list values('201903', '1', '1', 1); + insert into list_list values('201903', '2', '1', 1); + select * from list_list; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201903 | 2 | 1 | 1 + 201903 | 2 | 1 | 1 + 201903 | 1 | 1 | 1 + 201902 | 2 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + (6 rows) + + drop table list_list; + CREATE TABLE list_hash + ( + month_code VARCHAR2 ( 30 ) NOT NULL , + dept_code VARCHAR2 ( 30 ) NOT NULL , + user_no VARCHAR2 ( 30 ) NOT NULL , + sales_amt int + ) + PARTITION BY LIST (month_code) SUBPARTITION BY HASH (dept_code) + ( + PARTITION p_201901 VALUES ( '201902' ) + ( + SUBPARTITION p_201901_a, + SUBPARTITION p_201901_b + ), + PARTITION p_201902 VALUES ( '201903' ) + ( + SUBPARTITION p_201902_a, + SUBPARTITION p_201902_b + ) + ); + insert into list_hash values('201902', '1', '1', 1); + insert into list_hash values('201902', '2', '1', 1); + insert into list_hash values('201902', '3', '1', 1); + insert into list_hash values('201903', '4', '1', 1); + insert into list_hash values('201903', '5', '1', 1); + insert into list_hash values('201903', '6', '1', 1); + select * from list_hash; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201903 | 4 | 1 | 1 + 201903 | 5 | 1 | 1 + 201903 | 6 | 1 | 1 + 201902 | 2 | 1 | 1 + 201902 | 3 | 1 | 1 + 201902 | 1 | 1 | 1 + (6 rows) + + drop table list_hash; + CREATE TABLE list_range + ( + month_code VARCHAR2 ( 30 ) NOT NULL , + dept_code VARCHAR2 ( 30 ) NOT NULL , + user_no VARCHAR2 ( 30 ) NOT NULL , + sales_amt int + ) + PARTITION BY LIST (month_code) SUBPARTITION BY RANGE (dept_code) + ( + PARTITION p_201901 VALUES ( '201902' ) + ( + SUBPARTITION p_201901_a values less than ('4'), + SUBPARTITION p_201901_b values less than ('6') + ), + PARTITION p_201902 VALUES ( '201903' ) + ( + SUBPARTITION p_201902_a values less than ('3'), + SUBPARTITION p_201902_b values less than ('6') + ) + ); + insert into list_range values('201902', '1', '1', 1); + insert into list_range values('201902', '2', '1', 1); + insert into list_range values('201902', '3', '1', 1); + insert into list_range values('201903', '4', '1', 1); + insert into list_range values('201903', '5', '1', 1); + insert into list_range values('201903', '6', '1', 1); + ERROR: inserted partition key does not map to any table partition + select * from list_range; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201903 | 4 | 1 | 1 + 201903 | 5 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 2 | 1 | 1 + 201902 | 3 | 1 | 1 + (5 rows) + + drop table list_range; + CREATE TABLE range_list + ( + month_code VARCHAR2 ( 30 ) NOT NULL , + dept_code VARCHAR2 ( 30 ) NOT NULL , + user_no VARCHAR2 ( 30 ) NOT NULL , + sales_amt int + ) + PARTITION BY RANGE (month_code) SUBPARTITION BY LIST (dept_code) + ( + PARTITION p_201901 VALUES LESS THAN( '201903' ) + ( + SUBPARTITION p_201901_a values ('1'), + SUBPARTITION p_201901_b values ('2') + ), + PARTITION p_201902 VALUES LESS THAN( '201904' ) + ( + SUBPARTITION p_201902_a values ('1'), + SUBPARTITION p_201902_b values ('2') + ) + ); + insert into range_list values('201902', '1', '1', 1); + insert into range_list values('201902', '2', '1', 1); + insert into range_list values('201902', '1', '1', 1); + insert into range_list values('201903', '2', '1', 1); + insert into range_list values('201903', '1', '1', 1); + insert into range_list values('201903', '2', '1', 1); + select * from range_list; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 2 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201903 | 2 | 1 | 1 + 201903 | 2 | 1 | 1 + 201903 | 1 | 1 | 1 + (6 rows) + + drop table range_list; + CREATE TABLE range_hash + ( + month_code VARCHAR2 ( 30 ) NOT NULL , + dept_code VARCHAR2 ( 30 ) NOT NULL , + user_no VARCHAR2 ( 30 ) NOT NULL , + sales_amt int + ) + PARTITION BY RANGE (month_code) SUBPARTITION BY HASH (dept_code) + ( + PARTITION p_201901 VALUES LESS THAN( '201903' ) + ( + SUBPARTITION p_201901_a, + SUBPARTITION p_201901_b + ), + PARTITION p_201902 VALUES LESS THAN( '201904' ) + ( + SUBPARTITION p_201902_a, + SUBPARTITION p_201902_b + ) + ); + insert into range_hash values('201902', '1', '1', 1); + insert into range_hash values('201902', '2', '1', 1); + insert into range_hash values('201902', '1', '1', 1); + insert into range_hash values('201903', '2', '1', 1); + insert into range_hash values('201903', '1', '1', 1); + insert into range_hash values('201903', '2', '1', 1); + select * from range_hash; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 2 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201903 | 2 | 1 | 1 + 201903 | 2 | 1 | 1 + 201903 | 1 | 1 | 1 + (6 rows) + + drop table range_hash; + CREATE TABLE range_range + ( + month_code VARCHAR2 ( 30 ) NOT NULL , + dept_code VARCHAR2 ( 30 ) NOT NULL , + user_no VARCHAR2 ( 30 ) NOT NULL , + sales_amt int + ) + PARTITION BY RANGE (month_code) SUBPARTITION BY RANGE (dept_code) + ( + PARTITION p_201901 VALUES LESS THAN( '201903' ) + ( + SUBPARTITION p_201901_a VALUES LESS THAN( '2' ), + SUBPARTITION p_201901_b VALUES LESS THAN( '3' ) + ), + PARTITION p_201902 VALUES LESS THAN( '201904' ) + ( + SUBPARTITION p_201902_a VALUES LESS THAN( '2' ), + SUBPARTITION p_201902_b VALUES LESS THAN( '3' ) + ) + ); + insert into range_range values('201902', '1', '1', 1); + insert into range_range values('201902', '2', '1', 1); + insert into range_range values('201902', '1', '1', 1); + insert into range_range values('201903', '2', '1', 1); + insert into range_range values('201903', '1', '1', 1); + insert into range_range values('201903', '2', '1', 1); + select * from range_range; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 2 | 1 | 1 + 201903 | 1 | 1 | 1 + 201903 | 2 | 1 | 1 + 201903 | 2 | 1 | 1 + (6 rows) + + drop table range_range; + CREATE TABLE hash_list + ( + month_code VARCHAR2 ( 30 ) NOT NULL , + dept_code VARCHAR2 ( 30 ) NOT NULL , + user_no VARCHAR2 ( 30 ) NOT NULL , + sales_amt int + ) + PARTITION BY hash (month_code) SUBPARTITION BY LIST (dept_code) + ( + PARTITION p_201901 + ( + SUBPARTITION p_201901_a VALUES ( '1' ), + SUBPARTITION p_201901_b VALUES ( '2' ) + ), + PARTITION p_201902 + ( + SUBPARTITION p_201902_a VALUES ( '1' ), + SUBPARTITION p_201902_b VALUES ( '2' ) + ) + ); + insert into hash_list values('201901', '1', '1', 1); + insert into hash_list values('201901', '2', '1', 1); + insert into hash_list values('201901', '1', '1', 1); + insert into hash_list values('201903', '2', '1', 1); + insert into hash_list values('201903', '1', '1', 1); + insert into hash_list values('201903', '2', '1', 1); + select * from hash_list; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201903 | 2 | 1 | 1 + 201903 | 2 | 1 | 1 + 201903 | 1 | 1 | 1 + 201901 | 2 | 1 | 1 + 201901 | 1 | 1 | 1 + 201901 | 1 | 1 | 1 + (6 rows) + + drop table hash_list; + CREATE TABLE hash_hash + ( + month_code VARCHAR2 ( 30 ) NOT NULL , + dept_code VARCHAR2 ( 30 ) NOT NULL , + user_no VARCHAR2 ( 30 ) NOT NULL , + sales_amt int + ) + PARTITION BY hash (month_code) SUBPARTITION BY hash (dept_code) + ( + PARTITION p_201901 + ( + SUBPARTITION p_201901_a, + SUBPARTITION p_201901_b + ), + PARTITION p_201902 + ( + SUBPARTITION p_201902_a, + SUBPARTITION p_201902_b + ) + ); + insert into hash_hash values('201901', '1', '1', 1); + insert into hash_hash values('201901', '2', '1', 1); + insert into hash_hash values('201901', '1', '1', 1); + insert into hash_hash values('201903', '2', '1', 1); + insert into hash_hash values('201903', '1', '1', 1); + insert into hash_hash values('201903', '2', '1', 1); + select * from hash_hash; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201903 | 2 | 1 | 1 + 201903 | 2 | 1 | 1 + 201903 | 1 | 1 | 1 + 201901 | 2 | 1 | 1 + 201901 | 1 | 1 | 1 + 201901 | 1 | 1 | 1 + (6 rows) + + drop table hash_hash; + CREATE TABLE hash_range + ( + month_code VARCHAR2 ( 30 ) NOT NULL , + dept_code VARCHAR2 ( 30 ) NOT NULL , + user_no VARCHAR2 ( 30 ) NOT NULL , + sales_amt int + ) + PARTITION BY hash (month_code) SUBPARTITION BY range (dept_code) + ( + PARTITION p_201901 + ( + SUBPARTITION p_201901_a VALUES LESS THAN ( '2' ), + SUBPARTITION p_201901_b VALUES LESS THAN ( '3' ) + ), + PARTITION p_201902 + ( + SUBPARTITION p_201902_a VALUES LESS THAN ( '2' ), + SUBPARTITION p_201902_b VALUES LESS THAN ( '3' ) + ) + ); + insert into hash_range values('201901', '1', '1', 1); + insert into hash_range values('201901', '2', '1', 1); + insert into hash_range values('201901', '1', '1', 1); + insert into hash_range values('201903', '2', '1', 1); + insert into hash_range values('201903', '1', '1', 1); + insert into hash_range values('201903', '2', '1', 1); + select * from hash_range; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201903 | 1 | 1 | 1 + 201903 | 2 | 1 | 1 + 201903 | 2 | 1 | 1 + 201901 | 1 | 1 | 1 + 201901 | 1 | 1 | 1 + 201901 | 2 | 1 | 1 + (6 rows) + ``` + +- 示例2:对二级分区表进行DML指定分区操作 + + ``` + CREATE TABLE range_list + ( + month_code VARCHAR2 ( 30 ) NOT NULL , + dept_code VARCHAR2 ( 30 ) NOT NULL , + user_no VARCHAR2 ( 30 ) NOT NULL , + sales_amt int + ) + PARTITION BY RANGE (month_code) SUBPARTITION BY LIST (dept_code) + ( + PARTITION p_201901 VALUES LESS THAN( '201903' ) + ( + SUBPARTITION p_201901_a values ('1'), + SUBPARTITION p_201901_b values ('2') + ), + PARTITION p_201902 VALUES LESS THAN( '201910' ) + ( + SUBPARTITION p_201902_a values ('1'), + SUBPARTITION p_201902_b values ('2') + ) + ); + --指定一级分区插入数据 + insert into range_list partition (p_201901) values('201902', '1', '1', 1); + --实际分区和指定分区不一致,报错 + insert into range_list partition (p_201902) values('201902', '1', '1', 1); + ERROR: inserted partition key does not map to the table partition + DETAIL: N/A. + --指定二级分区插入数据 + insert into range_list subpartition (p_201901_a) values('201902', '1', '1', 1); + --实际分区和指定分区不一致,报错 + insert into range_list subpartition (p_201901_b) values('201902', '1', '1', 1); + ERROR: inserted subpartition key does not map to the table subpartition + DETAIL: N/A. + insert into range_list partition for ('201902') values('201902', '1', '1', 1); + insert into range_list subpartition for ('201902','1') values('201902', '1', '1', 1); + + --指定分区查询数据 + select * from range_list partition (p_201901); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + (4 rows) + + select * from range_list subpartition (p_201901_a); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + (4 rows) + + select * from range_list partition for ('201902'); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + (4 rows) + + select * from range_list subpartition for ('201902','1'); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + (4 rows) + + --指定分区更新数据 + update range_list partition (p_201901) set user_no = '2'; + select * from range_list; + select *from range_list; month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 1 | 2 | 1 + 201902 | 1 | 2 | 1 + 201902 | 1 | 2 | 1 + 201902 | 1 | 2 | 1 + (4 rows) + update range_list subpartition (p_201901_a) set user_no = '3'; + select * from range_list; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 1 | 3 | 1 + 201902 | 1 | 3 | 1 + 201902 | 1 | 3 | 1 + 201902 | 1 | 3 | 1 + (4 rows) + update range_list partition for ('201902') set user_no = '4'; + select * from range_list; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 1 | 4 | 1 + 201902 | 1 | 4 | 1 + 201902 | 1 | 4 | 1 + 201902 | 1 | 4 | 1 + (4 rows) + update range_list subpartition for ('201902','2') set user_no = '5'; + openGauss=# select *from range_list; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 1 | 4 | 1 + 201902 | 1 | 4 | 1 + 201902 | 1 | 4 | 1 + 201902 | 1 | 4 | 1 + (4 rows) + select * from range_list; + + --指定分区删除数据 + delete from range_list partition (p_201901); + DELETE 4 + delete from range_list partition for ('201903'); + DELETE 0 + delete from range_list subpartition (p_201901_a); + DELETE 0 + delete from range_list subpartition for ('201903','2'); + DELETE 0 + --参数sql_compatibility=B时,可指定多分区删除数据 + delete from range_list as t partition (p_201901_a, p_201901); + DELETE 0 + + --指定分区insert数据 + insert into range_list partition (p_201901) values('201902', '1', '1', 1) ON DUPLICATE KEY UPDATE sales_amt = 5; + insert into range_list subpartition (p_201901_a) values('201902', '1', '1', 1) ON DUPLICATE KEY UPDATE sales_amt = 10; + insert into range_list partition for ('201902') values('201902', '1', '1', 1) ON DUPLICATE KEY UPDATE sales_amt = 30; + insert into range_list subpartition for ('201902','1') values('201902', '1', '1', 1) ON DUPLICATE KEY UPDATE sales_amt = 40; + select * from range_list; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + (4 rows) + + --指定分区merge into数据 + CREATE TABLE newrange_list + ( + month_code VARCHAR2 ( 30 ) NOT NULL , + dept_code VARCHAR2 ( 30 ) NOT NULL , + user_no VARCHAR2 ( 30 ) NOT NULL , + sales_amt int + ) + PARTITION BY RANGE (month_code) SUBPARTITION BY LIST (dept_code) + ( + PARTITION p_201901 VALUES LESS THAN( '201903' ) + ( + SUBPARTITION p_201901_a values ('1'), + SUBPARTITION p_201901_b values ('2') + ), + PARTITION p_201902 VALUES LESS THAN( '201910' ) + ( + SUBPARTITION p_201902_a values ('1'), + SUBPARTITION p_201902_b values ('2') + ) + ); + insert into newrange_list values('201902', '1', '1', 1); + insert into newrange_list values('201903', '1', '1', 2); + + MERGE INTO range_list partition (p_201901) p + USING newrange_list partition (p_201901) np + ON p.month_code= np.month_code + WHEN MATCHED THEN + UPDATE SET dept_code = np.dept_code, user_no = np.user_no, sales_amt = np.sales_amt + WHEN NOT MATCHED THEN + INSERT VALUES (np.month_code, np.dept_code, np.user_no, np.sales_amt); + + select * from range_list; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + (4 rows) + + MERGE INTO range_list partition for ('201901') p + USING newrange_list partition for ('201901') np + ON p.month_code= np.month_code + WHEN MATCHED THEN + UPDATE SET dept_code = np.dept_code, user_no = np.user_no, sales_amt = np.sales_amt + WHEN NOT MATCHED THEN + INSERT VALUES (np.month_code, np.dept_code, np.user_no, np.sales_amt); + + select * from range_list; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + (4 rows) + + MERGE INTO range_list subpartition (p_201901_a) p + USING newrange_list subpartition (p_201901_a) np + ON p.month_code= np.month_code + WHEN MATCHED THEN + UPDATE SET dept_code = np.dept_code, user_no = np.user_no, sales_amt = np.sales_amt + WHEN NOT MATCHED THEN + INSERT VALUES (np.month_code, np.dept_code, np.user_no, np.sales_amt); + + select * from range_list; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + (4 rows) + + MERGE INTO range_list subpartition for ('201901', '1') p + USING newrange_list subpartition for ('201901', '1') np + ON p.month_code= np.month_code + WHEN MATCHED THEN + UPDATE SET dept_code = np.dept_code, user_no = np.user_no, sales_amt = np.sales_amt + WHEN NOT MATCHED THEN + INSERT VALUES (np.month_code, np.dept_code, np.user_no, np.sales_amt); + + select * from range_list; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + (4 rows) + ``` + +- 示例3:对二级分区表进行truncate操作 + + ``` + CREATE TABLE list_list + ( + month_code VARCHAR2 ( 30 ) NOT NULL , + dept_code VARCHAR2 ( 30 ) NOT NULL , + user_no VARCHAR2 ( 30 ) NOT NULL , + sales_amt int + ) + PARTITION BY LIST (month_code) SUBPARTITION BY LIST (dept_code) + ( + PARTITION p_201901 VALUES ( '201902' ) + ( + SUBPARTITION p_201901_a VALUES ( '1' ), + SUBPARTITION p_201901_b VALUES ( default ) + ), + PARTITION p_201902 VALUES ( '201903' ) + ( + SUBPARTITION p_201902_a VALUES ( '1' ), + SUBPARTITION p_201902_b VALUES ( '2' ) + ) + ); + insert into list_list values('201902', '1', '1', 1); + insert into list_list values('201902', '2', '1', 1); + insert into list_list values('201902', '1', '1', 1); + insert into list_list values('201903', '2', '1', 1); + insert into list_list values('201903', '1', '1', 1); + insert into list_list values('201903', '2', '1', 1); + select * from list_list; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201903 | 2 | 1 | 1 + 201903 | 2 | 1 | 1 + 201903 | 1 | 1 | 1 + 201902 | 2 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + (6 rows) + + select * from list_list partition (p_201901); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 2 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + (3 rows) + + alter table list_list truncate partition p_201901; + select * from list_list partition (p_201901); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + (0 rows) + + select * from list_list partition (p_201902); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201903 | 2 | 1 | 1 + 201903 | 2 | 1 | 1 + 201903 | 1 | 1 | 1 + (3 rows) + + alter table list_list truncate partition p_201902; + select * from list_list partition (p_201902); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + (0 rows) + + select * from list_list; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + (0 rows) + + insert into list_list values('201902', '1', '1', 1); + insert into list_list values('201902', '2', '1', 1); + insert into list_list values('201902', '1', '1', 1); + insert into list_list values('201903', '2', '1', 1); + insert into list_list values('201903', '1', '1', 1); + insert into list_list values('201903', '2', '1', 1); + select * from list_list subpartition (p_201901_a); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + (2 rows) + + alter table list_list truncate subpartition p_201901_a; + select * from list_list subpartition (p_201901_a); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + (0 rows) + + select * from list_list subpartition (p_201901_b); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 2 | 1 | 1 + (1 row) + + alter table list_list truncate subpartition p_201901_b; + select * from list_list subpartition (p_201901_b); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + (0 rows) + + select * from list_list subpartition (p_201902_a); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201903 | 1 | 1 | 1 + (1 row) + + alter table list_list truncate subpartition p_201902_a; + select * from list_list subpartition (p_201902_a); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + (0 rows) + + select * from list_list subpartition (p_201902_b); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201903 | 2 | 1 | 1 + 201903 | 2 | 1 | 1 + (2 rows) + + alter table list_list truncate subpartition p_201902_b; + select * from list_list subpartition (p_201902_b); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + (0 rows) + + select * from list_list; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + (0 rows) + + drop table list_list; + + ``` + +- 示例4:对二级分区表进行split操作 + + ``` + CREATE TABLE list_list + ( + month_code VARCHAR2 ( 30 ) NOT NULL , + dept_code VARCHAR2 ( 30 ) NOT NULL , + user_no VARCHAR2 ( 30 ) NOT NULL , + sales_amt int + ) + PARTITION BY LIST (month_code) SUBPARTITION BY LIST (dept_code) + ( + PARTITION p_201901 VALUES ( '201902' ) + ( + SUBPARTITION p_201901_a VALUES ( '1' ), + SUBPARTITION p_201901_b VALUES ( default ) + ), + PARTITION p_201902 VALUES ( '201903' ) + ( + SUBPARTITION p_201902_a VALUES ( '1' ), + SUBPARTITION p_201902_b VALUES ( default ) + ) + ); + insert into list_list values('201902', '1', '1', 1); + insert into list_list values('201902', '2', '1', 1); + insert into list_list values('201902', '1', '1', 1); + insert into list_list values('201903', '2', '1', 1); + insert into list_list values('201903', '1', '1', 1); + insert into list_list values('201903', '2', '1', 1); + select * from list_list; + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201903 | 2 | 1 | 1 + 201903 | 2 | 1 | 1 + 201903 | 1 | 1 | 1 + 201902 | 2 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + (6 rows) + + select * from list_list subpartition (p_201901_a); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + (2 rows) + + select * from list_list subpartition (p_201901_b); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 2 | 1 | 1 + (1 row) + + alter table list_list split subpartition p_201901_b values (2) into + ( + subpartition p_201901_b, + subpartition p_201901_c + ); + select * from list_list subpartition (p_201901_a); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + (2 rows) + + select * from list_list subpartition (p_201901_b); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 2 | 1 | 1 + (1 row) + + select * from list_list subpartition (p_201901_c); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + (0 rows) + + select * from list_list partition (p_201901); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201902 | 2 | 1 | 1 + 201902 | 1 | 1 | 1 + 201902 | 1 | 1 | 1 + (3 rows) + + select * from list_list subpartition (p_201902_a); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201903 | 1 | 1 | 1 + (1 row) + + select * from list_list subpartition (p_201902_b); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201903 | 2 | 1 | 1 + 201903 | 2 | 1 | 1 + (2 rows) + + alter table list_list split subpartition p_201902_b values (3) into + ( + subpartition p_201902_b, + subpartition p_201902_c + ); + select * from list_list subpartition (p_201902_a); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201903 | 1 | 1 | 1 + (1 row) + + select * from list_list subpartition (p_201902_b); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + (0 rows) + + select * from list_list subpartition (p_201902_c); + month_code | dept_code | user_no | sales_amt + ------------+-----------+---------+----------- + 201903 | 2 | 1 | 1 + 201903 | 2 | 1 | 1 + (2 rows) + + drop table list_list; + ``` + + diff --git a/content/zh/docs/SQLReference/CREATE-TABLE.md b/content/zh/docs/SQLReference/CREATE-TABLE.md index eb102611d2134d1136afa1b0f909fc90ef827b16..a9cb7db7705117e1e4e77e86390f8c1b61a92eac 100644 --- a/content/zh/docs/SQLReference/CREATE-TABLE.md +++ b/content/zh/docs/SQLReference/CREATE-TABLE.md @@ -1,1338 +1,1339 @@ -# CREATE TABLE - -## 功能描述 - -在当前数据库中创建一个新的空白表,该表由命令执行者所有。 - -## 注意事项 - -- 列存表支持的数据类型请参考[列存表支持的数据类型](列存表支持的数据类型.md)。 -- 列存表不支持数组。 -- 列存表不支持生成列。 -- 列存表不支持创建全局临时表。 -- 创建列存表的数量建议不超过1000个。 -- 如果在建表过程中数据库系统发生故障,系统恢复后可能无法自动清除之前已创建的、大小为0的磁盘文件。此种情况出现概率小,不影响数据库系统的正常运行。 -- 列存表的表级约束只支持PARTIAL CLUSTER KEY、UNIQUE、PRIAMRY KEY,不支持外键等表级约束。 -- 列存表的字段约束只支持NULL、NOT NULL、DEFAULT常量值、UNIQUE和PRIMARY KEY。 -- 列存表支持delta表,受参数enable\_delta\_store控制是否开启,受参数deltarow\_threshold控制进入delta表的阀值。 -- 列存表的字段的字符集必须与数据库字符集一致。 -- 使用JDBC时,支持通过PrepareStatement对DEFAULT值进行参数化设置。 -- 每张表的列数最大为1600,具体取决于列的类型,所有列的大小加起来不能超过8192 byte(由于数据存储形式原因,实际上限略小于8192 byte),text、varchar、char等长度可变的类型除外。 -- 被授予CREATE ANY TABLE权限的用户,可以在public模式和用户模式下创建表。如果想要创建包含serial类型列的表,还需要授予CREATE ANY SEQUENCE创建序列的权限。 -- 不可与同一模式下已存在的synonym产生命名冲突。 -- 仅支持在B兼容性数据库下指定COMMENT和可见性VISIBLE\INVISIBLE。 - -## 语法格式 - -创建表。 - -``` -CREATE [ [ GLOBAL | LOCAL ] [ TEMPORARY | TEMP ] | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name - ({ column_name data_type [ CHARACTER SET | CHARSET charset ] [ compress_mode ] [ COLLATE collation ] [ column_constraint [ ... ] ] - | table_constraint - | LIKE source_table [ like_option [...] ] } - [, ... ]) - [ AUTO_INCREMENT [ = ] value ] - [ [DEFAULT] CHARACTER SET | CHARSET [ = ] default_charset ] [ [DEFAULT] COLLATE [ = ] default_collation ] - [ WITH ( {storage_parameter = value} [, ... ] ) ] - [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] - [ COMPRESS | NOCOMPRESS ] - [ TABLESPACE tablespace_name ] - [ COMMENT {=| } 'text' ]; -``` - -- 其中列约束column\_constraint为: - - ``` - [ CONSTRAINT constraint_name ] - { NOT NULL | - NULL | - CHECK ( expression ) | - DEFAULT default_expr | - GENERATED ALWAYS AS ( generation_expr ) [STORED] | - AUTO_INCREMENT | - ON UPDATE update_expr | - UNIQUE [KEY] index_parameters | - ENCRYPTED WITH ( COLUMN_ENCRYPTION_KEY = column_encryption_key, ENCRYPTION_TYPE = encryption_type_value ) | - 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 ] - [ COMMENT {=| } 'text' ] - ``` - - -- 其中列的压缩可选项compress\_mode为: - - ``` - { DELTA | PREFIX | DICTIONARY | NUMSTR | NOCOMPRESS } - ``` - -- 其中表约束table\_constraint为: - - ``` - [ CONSTRAINT [ constraint_name ] ] - { CHECK ( expression ) | - UNIQUE [ index_name ][ USING method ] ( { { column_name | ( expression ) } [ ASC | DESC ] } [, ... ] ) index_parameters [ VISIBLE | INVISIBLE ] | - PRIMARY KEY [ USING method ] ( { column_name [ ASC | DESC ] } [, ... ] ) index_parameters [ VISIBLE | INVISIBLE ] | - FOREIGN KEY [ index_name ] ( column_name [, ... ] ) REFERENCES reftable [ (refcolumn [, ... ] ) ] - [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] | - PARTIAL CLUSTER KEY ( column_name [, ... ] ) } - [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] - [ COMMENT {=| } 'text' ] - ``` - - -- 其中like选项like\_option为: - - ``` - { INCLUDING | EXCLUDING } { DEFAULTS | GENERATED | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | PARTITION | RELOPTIONS | ALL } - ``` - -- 其中索引参数index\_parameters为: - - ``` - [ WITH ( {storage_parameter = value} [, ... ] ) ] - [ USING INDEX TABLESPACE tablespace_name ] - ``` - - -## 参数说明 - -- **UNLOGGED** - - 如果指定此关键字,则创建的表为非日志表。在非日志表中写入的数据不会被写入到预写日志中,这样就会比普通表快很多。但是非日志表在冲突、执行操作系统重启、数据库重启、主备切换、切断电源操作或异常关机后会被自动截断,会造成数据丢失的风险。非日志表中的内容也不会被复制到备服务器中。在非日志表中创建的索引也不会被自动记录。 - - 使用场景:非日志表不能保证数据的安全性,用户应该在确保数据已经做好备份的前提下使用,例如系统升级时进行数据的备份。 - - 故障处理:当异常关机等操作导致非日志表上的索引发生数据丢失时,用户应该对发生错误的索引进行重建。 - -- **GLOBAL | LOCAL** - - 创建临时表时可以在TEMP或TEMPORARY前指定GLOBAL或LOCAL关键字。如果指定GLOBAL关键字,openGauss会创建全局临时表,否则openGauss会创建本地临时表。 - -- **TEMPORARY | TEMP** - - 如果指定TEMP或TEMPORARY关键字,则创建的表为临时表。临时表分为全局临时表和本地临时表两种类型。创建临时表时如果指定GLOBAL关键字则为全局临时表,否则为本地临时表。 - - 全局临时表的元数据对所有会话可见,会话结束后元数据继续存在。会话与会话之间的用户数据、索引和统计信息相互隔离,每个会话只能看到和更改自己提交的数据。全局临时表有两种模式:一种是基于会话级别的\(ON COMMIT PRESERVE ROWS\), 当会话结束时自动清空用户数据;一种是基于事务级别的\(ON COMMIT DELETE ROWS\), 当执行commit或rollback时自动清空用户数据。建表时如果没有指定ON COMMIT选项,则缺省为会话级别。与本地临时表不同,全局临时表建表时可以指定非pg\_temp\_开头的schema。 - - 本地临时表只在当前会话可见,本会话结束后会自动删除。因此,在除当前会话连接的数据库节点故障时,仍然可以在当前会话上创建和使用临时表。由于临时表只在当前会话创建,对于涉及对临时表操作的DDL语句,会产生DDL失败的报错。因此,建议DDL语句中不要对临时表进行操作。TEMP和TEMPORARY等价。 - - >![](public_sys-resources/icon-notice.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](../DatabaseReference/全局临时表.md#section18307271684)控制是否启用。如果max\_active\_global\_temporary\_table=0,关闭全局临时表功能。 - >- 临时表只对当前会话可见,因此不支持与\\parallel on并行执行一起使用。 - >- 临时表不支持主备切换。 - >- 全局临时表不响应自动清理,在长链接场景使用时尽量使用on commit delete rows的全局临时表,或定期手动执行vacuum,否则可能导致clog日志不回收。 - -- **IF NOT EXISTS** - - 如果已经存在相同名称的表,不会报出错误,而会发出通知,告知通知此表已存在。 - -- **table\_name** - - 要创建的表名。 - - ![](public_sys-resources/icon-notice.png) **须知:** - - 物化视图的一些处理逻辑会通过表名的前缀来识别是不是物化视图日志表和物化视图关联表,因此,用户不要创建表名以mlog\_或matviewmap\_为前缀的表,否则会影响此表的一些功能。 - -- **column\_name** - - 新表中要创建的字段名。 - -- **constraint\_name** - - 建表时指定的约束名称。 - - >![](public_sys-resources/icon-notice.png) **须知:** - > - >在B模式数据库下(即sql\_compatibility = 'B')constraint\_name为可选项,在其他模式数据库下,必须加上constraint\_name。 - -- **index\_name** - - 索引名。 - - >![](public_sys-resources/icon-notice.png) **须知:** - > - >- index\_name仅在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库下不支持。 - >- 对于外键约束,constraint\_name和index\_name同时指定时,索引名为constraint\_name。 - >- 对于唯一键约束,constraint\_name和index\_name同时指定时,索引名以index\_name。 - -- **USING method** - - 指定创建索引的方法。 - - 取值范围参考[参数说明](CREATE-INDEX.md)中的USING method。 - - >![](public_sys-resources/icon-notice.png) **须知:** - > - >- USING method仅在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库下不支持。 - >- 在B模式下,未指定USING method时,对于ASTORE的存储方式,默认索引方法为btree;对于USTORE的存储方式,默认索引方法为ubtree。 - -- **ASC | DESC** - - ASC表示指定按升序排序(默认)。DESC指定按降序排序。 - - >![](public_sys-resources/icon-notice.png) **须知:** - > - >ASC|DESC只在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库不支持。 - -- **expression** - - 创建一个基于该表的一个或多个字段的表达式索引约束,必须写在圆括弧中。 - - >![](public_sys-resources/icon-notice.png) **须知:** - > - >表达式索引只在B模式数据库下支持(即sql\_compatibility = 'B'),其他模式数据库不支持。 - - -- **data\_type** - - 字段的数据类型。 - - -- **column\_constraint** - - 字段的类型约束中,添加了mysql的ON UPDATE特性,归类于字段类型约束。与DEFAULT属性属于同类约束。该ON UPDATE属性用于,执行UPDATE操作timestamp字段为缺省时,则自动更新timestamp字段的时间截。如果更新字段的数据内容与原来的数据内容一致,则其他含有ON UPDATE的字段的时间截不会自动更新。 - - ```sql - CREATE TABLE table_name(column_name timestamp ON UPDATE CURRENT_TIMESTAMP); - ``` - -- **compress\_mode** - - 表字段的压缩选项。该选项指定表字段优先使用的压缩算法。行存表不支持压缩。 - - 取值范围:DELTA、PREFIX、DICTIONARY、NUMSTR、NOCOMPRESS - - - DELTA压缩仅支持长度为1-8字节的数据类型(0 < pg_type.typlen <= 8)。 - - PREFIX、NUMSTR压缩仅支持变长数据类型(pg_type.typlen = -1)和NULL结尾的C字符串(pg_type.typlen = -2)。 - - 该压缩选项与列存表自适应压缩算法无关,后者为列存表内部数据存储采用的压缩算法,不支持用户指定。 - -- **CHARACTER SET | CHARSET charset** - - 只在B模式数据库下(即sql\_compatibility = 'B')支持该语法,其他模式数据库不支持。指定表字段的字符集,单独指定时会将字段的字符序设置为指定的字符集的默认字符序。 - -- **COLLATE collation** - - COLLATE子句指定列的排序规则(字符序)(该列必须是可排列的数据类型)。如果没有指定,则使用默认的排序规则。排序规则可以使用“select \* from pg\_collation;”命令从pg\_collation系统表中查询,默认的排序规则为查询结果中以default开始的行。对于B模式数据库下(即sql\_compatibility = 'B')还支持utf8mb4\_bin、utf8mb4\_general\_ci、utf8mb4\_unicode\_ci、binary字符序。 - - > **说明:** - > - >- 仅字符类型支持指定字符集,指定为binary字符集或字符序实际是将字符类型转化为对应的二进制类型,若类型映射不存在则报错。当前仅有TEXT类型转化为BLOB的映射。 - >- 除binary字符集和字符序外,当前仅支持指定与数据库编码相同的字符集。 - >- 未显式指定字段字符集或字符序时,若指定了表的默认字符集或字符序,字段字符集和字符序将从表上继承。若表的默认字符集或字符序不存在,当b\_format\_behavior\_compat\_options = 'default\_collation'时,字段的字符集和字符序将继承当前数据库的字符集及其对应的默认字符序。 - - **表 1** B模式(即sql\_compatibility = 'B')下支持的字符集和字符序介绍 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

字符序名称

-

对应的字符集

-

描述

-

utf8mb4_general_ci

-

utf8mb4(即utf8)

-

使用通用排序规则,不区分大小写。

-

utf8mb4_unicode_ci

-

utf8mb4(即utf8)

-

使用通用排序规则,不区分大小写。

-

utf8mb4_bin

-

utf8mb4(即utf8)

-

使用二进制排序规则,区分大小写。

-

binary

-

binary

-

使用二进制排序规则。

-

utf8_general_ci

-

utf8

-

使用通用排序规则,不区分大小写。

-

utf8_unicode_ci

-

utf8

-

使用通用排序规则,不区分大小写。

-

utf8_bin

-

utf8

-

使用二进制排序规则,区分大小写。

-
- -- **LIKE source\_table \[ like\_option ... \]** - - LIKE子句声明一个表,新表自动从这个表中继承所有字段名及其数据类型和非空约束。 - - 新表与源表之间在创建动作完毕之后是完全无关的。在源表做的任何修改都不会传播到新表中,并且也不可能在扫描源表的时候包含新表的数据。 - - 被复制的列和约束并不使用相同的名称进行融合。如果明确的指定了相同的名称或者在另外一个LIKE子句中,将会报错。 - - - 源表上的字段缺省表达式只有在指定INCLUDING DEFAULTS时,才会复制到新表中。缺省是不包含缺省表达式的,即新表中的所有字段的缺省值都是NULL。 - - 源表上的CHECK约束仅在指定INCLUDING CONSTRAINTS时,会复制到新表中,而其他类型的约束永远不会复制到新表中。非空约束总是复制到新表中。此规则同时适用于表约束和列约束。 - - 如果指定了INCLUDING INDEXES,则源表上的索引也将在新表上创建,默认不建立索引。 - - 如果指定了INCLUDING STORAGE,则复制列的STORAGE设置会复制到新表中,默认情况下不包含STORAGE设置。 - - 如果指定了INCLUDING COMMENTS,则源表列、约束和索引的注释会复制到新表中。默认情况下,不复制源表的注释。 - - 如果指定了INCLUDING PARTITION,则源表的分区定义会复制到新表中,同时新表将不能再使用PARTITION BY子句。默认情况下,不拷贝源表的分区定义。如果源表上带有索引,可以使用INCLUDING PARTITION INCLUDING INDEXES语法实现。如果对分区表只使用INCLUDING INDEXES,目标表定义将是普通表,但是索引是分区索引,最后结果会报错,因为普通表不支持分区索引。 - - 如果指定了INCLUDING RELOPTIONS,则源表的存储参数(即源表的WITH子句)会复制到新表中。默认情况下,不复制源表的存储参数。 - - INCLUDING ALL包含了INCLUDING DEFAULTS、INCLUDING CONSTRAINTS、INCLUDING INDEXES、INCLUDING STORAGE、INCLUDING COMMENTS、INCLUDING PARTITION和INCLUDING RELOPTIONS的内容。 - - ATUO_INCREMENT列需要为主键或唯一约束的第一个字段,若复制包含AUTO_INCREAMENT列的表时指定EXCLUDING INDEX,将会报错。其中AUTO_INCREAMENT只在B库中生效。 - - >![](public_sys-resources/icon-notice.png) **须知:** - > - >- 如果源表包含serial、bigserial、smallserial、largeserial类型,或者源表字段的默认值是sequence,且sequence属于源表(通过CREATE SEQUENCE ... OWNED BY创建),这些Sequence不会关联到新表中,新表中会重新创建属于自己的sequence。这和之前版本的处理逻辑不同。如果用户希望源表和新表共享Sequence,需要首先创建一个共享的Sequence(避免使用OWNED BY),并配置为源表字段默认值,这样创建的新表会和源表共享该Sequence。 - > - >- 不建议将其他表私有的Sequence配置为源表字段的默认值,尤其是其他表只分布在特定的NodeGroup上,这可能导致CREATE TABLE ... LIKE执行失败。另外,如果源表配置其他表私有的Sequence,当该表删除时Sequence也会连带删除,这样源表的Sequence将不可用。如果用户希望多个表共享Sequence,建议创建共享的Sequence。 - > - >- 对于分区表EXCLUDING,需要配合INCLUDING ALL使用,如INCLUDING ALL EXCLUDING DEFAULTS,除源分区表的DEFAULTS,其它全包含。 - > - >- 如果源表是本地临时表,则新表也必须是本地临时表,否则会报错。 - > - >- 如果源表是hash或list分区表,则在CREATE TABLE ... (LIKE ... INCLUDIING PARTITION)时会报错,不支持复制hash或list分区表的分区,仅支持range分区。对于二级分区表,同样只支持range-range二级分区。 - -- **WITH \( \{ storage\_parameter = value \} \[, ... \] \)** - - 这个子句为表或索引指定一个可选的存储参数。用于表的WITH子句还可以包含OIDS=FALSE表示不分配OID。 - - >![](public_sys-resources/icon-note.png) **说明:** - > - >使用任意精度类型Numeric定义列时,建议指定精度p以及刻度s。在不指定精度和刻度时,会按输入的显示出来。 - - 参数的详细描述如下所示。 - - - FILLFACTOR - - 一个表的填充因子(fillfactor)是一个介于10和100之间的百分数。100(完全填充)是默认值。如果指定了较小的填充因子,INSERT操作仅按照填充因子指定的百分率填充表页。每个页上的剩余空间将用于在该页上更新行,这就使得UPDATE有机会在同一页上放置同一条记录的新版本,这比把新版本放置在其他页上更有效。对于一个从不更新的表将填充因子设为100是最佳选择,但是对于频繁更新的表,选择较小的填充因子则更加合适。该参数对于列存表没有意义。 - - 取值范围:10\~100 - - - ORIENTATION - - 指定表数据的存储方式,即行存方式、列存方式,该参数设置成功后就不再支持修改。 - - 取值范围: - - - ROW,表示表的数据将以行式存储。 - - 行存储适合于OLTP业务,适用于点查询或者增删操作较多的场景。 - - - COLUMN,表示表的数据将以列式存储。 - - 列存储适合于数据仓库业务,此类型的表上会做大量的汇聚计算,且涉及的列操作较少。 - - 默认值: - - 若指定表空间为普通表空间,默认值为ROW。 - - - STORAGE\_TYPE - - 指定存储引擎类型,该参数设置成功后就不再支持修改。 - - 取值范围: - - - USTORE,表示表支持Inplace-Update存储引擎。 - - ASTORE,表示表支持Append-Only存储引擎。 - - 默认值: - - 不指定表时,默认是Append-Only存储。 - - - INIT\_TD - - 创建Ustore表时,指定初始化的TD个数,该参数只在创建Ustore表时才能设置生效。 - - 取值范围:2\~128,默认值为4。 - - - COMPRESSION - - 指定表数据的压缩级别,它决定了表数据的压缩比以及压缩时间。一般来讲,压缩级别越高,压缩比也越大,压缩时间也越长;反之亦然。实际压缩比取决于加载的表数据的分布特征。行存表默认增加COMPRESSION=NO字段。 - - 取值范围: - - 列存表的有效值为YES/NO/LOW/MIDDLE/HIGH,默认值为LOW。 - - - COMPRESSLEVEL - - 指定表数据同一压缩级别下的不同压缩水平,它决定了同一压缩级别下表数据的压缩比以及压缩时间。对同一压缩级别进行了更加详细的划分,为用户选择压缩比和压缩时间提供了更多的空间。总体来讲,此值越大,表示同一压缩级别下压缩比越大,压缩时间越长;反之亦然。 - - 取值范围:0\~3,默认值为0。 - - - COMPRESSTYPE - - 行存表参数,设置行存表压缩算法。1代表pglz算法(不推荐使用),2代表zstd算法,默认不压缩。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。(仅支持ASTORE和USTORE下的普通表和分区表) - - 取值范围:0\~2,默认值为0。 - - - COMPRESS\_LEVEL - - 行存表参数,设置行存表压缩算法等级,仅当COMPRESSTYPE为2时生效。压缩等级越高,表的压缩效果越好,表的访问速度越慢。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - - 取值范围:-31\~31,默认值为0。 - - - COMPRESS\_CHUNK_SIZE - - 行存表参数,设置行存表压缩chunk块大小,仅当COMPRESSTYPE不为0时生效。chunk数据块越小,预期能达到的压缩效果越好,同时数据越离散,影响表的访问速度。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - 取值范围:与页面大小有关。在页面大小为8k场景,取值范围为:512、1024、2048、4096。 - - 默认值:4096 - - - COMPRESS_PREALLOC_CHUNKS - - 行存表参数,设置行存表压缩chunk块预分配数量。预分配数量越大,表的压缩率相对越差,离散度越小,访问性能越好。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - - 取值范围:0\~7,默认值为0。 - - - 当COMPRESS\_CHUNK_SIZE为512和1024时,支持预分配设置最大为7。 - - 当COMPRESS\_CHUNK_SIZE为2048时,支持预分配设置最大为3。 - - 当COMPRESS\_CHUNK_SIZE为4096时,支持预分配设置最大为1。 - - - COMPRESS_BYTE_CONVERT - - 行存表参数,设置行存表压缩字节转换预处理,仅当COMPRESSTYPE不为0时生效。在一些场景下可以提升压缩效果,同时会导致一定性能劣化。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - - 取值范围:布尔值,默认关闭。 - - - COMPRESS_DIFF_CONVERT - - 行存表参数,设置行存表压缩字节差分预处理。只能与compress_byte_convert一起使用。在一些场景下可以提升压缩效果,同时会导致一定性能劣化。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 - - 取值范围:布尔值,默认关闭。 - - - MAX\_BATCHROW - - 指定了在数据加载过程中一个存储单元可以容纳记录的最大数目。该参数只对列存表有效。 - - 取值范围:10000\~60000,默认60000。 - - - PARTIAL\_CLUSTER\_ROWS - - 指定了在数据加载过程中进行将局部聚簇存储的记录数目。该参数只对列存表有效。 - - 取值范围:大于等于MAX\_BATCHROW,建议取值为MAX\_BATCHROW的整数倍。 - - - DELTAROW\_THRESHOLD - - 指定列存表导入时小于多少行的数据进入delta表,只在GUC参数enable\_delta\_store开启时生效。该参数只对列存表有效。 - - 取值范围:0~9999,默认值为100 - - - segment - - 使用段页式的方式存储。本参数仅支持行存表。不支持列存表、临时表、unlog表。不支持ustore存储引擎。 - - 取值范围:on/off - - 默认值:off - - - dek\_cipher - - 透明数据加密密钥的密文。当开启enable\_tde选项时会自动申请创建,用户不可单独指定。通过密钥轮转功能可以对密钥进行更新。 - - 取值范围:字符串。 - - 默认值:不开启加密时默认为空。 - - - hasuids - - 参数开启:更新表元组时,为元组分配表级唯一标识id。 - - 取值范围:on/off。 - - 默认值:off。 - - + collate - - 在B模式数据库下(即sql\_compatibility = 'B')用于记录表的默认字符序,一般只用于内部存储和导入导出,不推荐用户指定或修改。 - - 取值范围:B模式数据库中独立支持的字符序的oid。 - - 默认值:0。 - -- **WITHOUT OIDS** - - 等价于WITH(OIDS=FALSE)的语法。 - -- **ON COMMIT \{ PRESERVE ROWS | DELETE ROWS | DROP \}** - - ON COMMIT选项决定在事务中执行创建临时表操作,当事务提交时,此临时表的后续操作。有以下三个选项,当前支持PRESERVE ROWS和DELETE ROWS选项。 - - - PRESERVE ROWS(缺省值):提交时不对临时表做任何操作,临时表及其表数据保持不变。 - - DELETE ROWS:提交时删除临时表中数据。 - - DROP:提交时删除此临时表。只支持本地临时表,不支持全局临时表。 - -- **COMPRESS | NOCOMPRESS** - - 创建新表时,需要在CREATE TABLE语句中指定关键字COMPRESS,这样,当对该表进行批量插入时就会触发压缩特性。该特性会在页范围内扫描所有元组数据,生成字典、压缩元组数据并进行存储。指定关键字NOCOMPRESS则不对表进行压缩。行存表不支持压缩。 - - 缺省值:NOCOMPRESS,即不对元组数据进行压缩。 - -- **TABLESPACE tablespace\_name** - - 创建新表时指定此关键字,表示新表将要在指定表空间内创建。如果没有声明,将使用默认表空间。 - -- **COMMNET {=| } text** - - 创建新表时指定此关键字,表示新表的注释内容。如果没有声明,则不创建注释。 - -- **CONSTRAINT constraint\_name** - - 列约束或表约束的名称。可选的约束子句用于声明约束,新行或者更新的行必须满足这些约束才能成功插入或更新。 - - 定义约束有两种方法: - - - 列约束:作为一个列定义的一部分,仅影响该列。 - - 表约束:不和某个列绑在一起,可以作用于多个列。 - -- **NOT NULL** - - 字段值不允许为NULL。 - -- **NULL** - - 字段值允许为NULL ,这是缺省值。 - - 这个子句只是为和非标准SQL数据库兼容。不建议使用。 - -- **CHECK \( expression \)** - - CHECK约束声明一个布尔表达式,每次要插入的新行或者要更新的行的新值必须使表达式结果为真或未知才能成功,否则会抛出一个异常并且不会修改数据库。 - - 声明为字段约束的检查约束应该只引用该字段的数值,而在表约束里出现的表达式可以引用多个字段。 - - >![](public_sys-resources/icon-note.png) **说明:** - > - >expression表达式中,如果存在“<\>NULL”或“!=NULL”,这种写法是无效的,需要写成“is NOT NULL”。 - - -- **DEFAULT default\_expr** - - DEFAULT子句给字段指定缺省值。该数值可以是任何不含变量的表达式\(不允许使用子查询和对本表中的其他字段的交叉引用\)。缺省表达式的数据类型必须和字段类型匹配。 - - 缺省表达式将被用于任何未声明该字段数值的插入操作。如果没有指定缺省值则缺省值为NULL 。 - -+ **GENERATED ALWAYS AS \( generation\_expr \) \[STORED\]** - - 该子句将字段创建为生成列,生成列的值在写入(插入或更新)数据时由generation\_expr计算得到,STORED表示像普通列一样存储生成列的值。 - - >![](public_sys-resources/icon-note.png) **说明:** - > - >- STORED关键字可省略,与不省略STORED语义相同。 - >- 生成表达式不能以任何方式引用当前行以外的其他数据。生成表达式不能引用其他生成列,不能引用系统列。生成表达式不能返回结果集,不能使用子查询,不能使用聚集函数,不能使用窗口函数。生成表达式调用的函数只能是不可变(IMMUTABLE)函数。 - >- 不能为生成列指定默认值。 - >- 生成列不能作为分区键的一部分。 - >- 生成列不能和ON UPDATE约束字句的CASCADE,SET NULL,SET DEFAULT动作同时指定。生成列不能和ON DELETE约束字句的SET NULL,SET DEFAULT动作同时指定。 - >- 修改和删除生成列的方法和普通列相同。删除生成列依赖的普通列,生成列被自动删除。不能改变生成列所依赖的列的类型。 - >- 生成列不能被直接写入。在INSERT或UPDATE命令中, 不能为生成列指定值, 但是可以指定关键字DEFAULT。 - >- 生成列的权限控制和普通列一样。 - >- 列存表、内存表MOT不支持生成列。外表中仅postgres\_fdw支持生成列。 - - -- **AUTO\_INCREMENT** - - 该关键字将字段指定为自动增长列。 - - 若在插入时不指定此列的值(或指定此列的值为0、NULL、DEFAULT),此列的值将由自增计数器自动增长得到。 - - 若插入或更新此列为一个大于当前自增计数器的值,执行成功后,自增计数器将刷新为此值。 - - 自增初始值由“AUTO\_INCREMENT \[ = \] value”子句设置,若不设置,默认为1。 - - >![](public_sys-resources/icon-note.png) **说明:** - > - >- 仅在参数sql\_compatibility=B时可以指定自动增长列。 - >- 自动增长列数据类型只能为整数类型、4字节或8字节浮点类型。 - >- 每个表只能有一个自动增长列。 - >- 自动增长列必须是主键约束或唯一约束的第一个字段。 - >- 自动增长列不能指定DEFAULT缺省值。 - >- CHECK约束的表达式中不能含有自动增长列。 - >- 可以指定自动增长列允许NULL,若不指定,默认自动增长列含有NOT NULL约束。 - >- 含有自动增长列的表创建时,会创建一个依赖于此列的序列作为自增计数器,不允许通过序列相关功能修改或删除此序列,可以查看序列的值。 - >- 本地临时表中的自动增长列不会创建序列。 - >- 自动增长列不支持列式存储。 - >- 自增计数器自增和刷新操作不会回滚。 - - -- **\[DEFAULT\] CHARACTER SET | CHARSET \[ = \] default\_charset** - - 仅在sql\_compatibility='B'时支持该语法。指定表的默认字符集,单独指定时会将表的默认字符序设置为指定的字符集的默认字符序。 - -- **\[DEFAULT\] COLLATE \[ = \] default\_collation** - - 仅在sql\_compatibility='B'时支持该语法。指定表的默认字符序,单独指定时会将表的默认字符集设置为指定的字符序对应的字符集。字符序参见[表1 B模式(即sql\_compatibility = 'B')下支持的字符集和字符序介绍](#table8163190152)。 - - >![](public_sys-resources/icon-note.png) **说明:** - >未显式指定表的字符集或字符序时,若指定了模式的默认字符集或字符序,表字符集和字符序将从模式上继承。若模式的默认字符集或字符序不存在,当b\_format\_behavior\_compat\_options = 'default\_collation'时,表的字符集和字符序将继承当前数据库的字符集及其对应的默认字符序。 - -- **UNIQUE \[KEY\] index\_parameters** - - **UNIQUE \( column\_name \[, ... \] \) index\_parameters** - - UNIQUE约束表示表里的一个字段或多个字段的组合必须在全表范围内唯一。 - - 对于唯一约束,NULL被认为是互不相等的。 - - UNIQUE KEY只能在sql\_compatibility='B'时使用,与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** - - 这两个关键字设置该约束是否可推迟。一个不可推迟的约束将在每条命令之后马上检查。可推迟约束可以推迟到事务结尾使用SET CONSTRAINTS命令检查。缺省是NOT DEFERRABLE。目前,UNIQUE约束、主键约束、外键约束可以接受这个子句。所有其他约束类型都是不可推迟的。 - - ![](public_sys-resources/icon-note.png) **说明:** - Ustore表不支持**DEFERRABLE以及INITIALLY DEFERRED**关键字。 - -- **COMMENT text** - - 注释。 - -- **VISIBLE | INVISIBLE** - - 指定索引是否可见,如果没有声明则默认为VISIBLE。 - -- **PARTIAL CLUSTER KEY** - - 局部聚簇存储,列存表导入数据时按照指定的列\(单列或多列\),进行局部排序。 - -- **INITIALLY IMMEDIATE | INITIALLY DEFERRED** - - 如果约束是可推迟的,则这个子句声明检查约束的缺省时间。 - - - 如果约束是INITIALLY IMMEDIATE(缺省),则在每条语句执行之后就立即检查它; - - 如果约束是INITIALLY DEFERRED ,则只有在事务结尾才检查它。 - - 约束检查的时间可以用SET CONSTRAINTS命令修改。 - -- **USING INDEX TABLESPACE tablespace\_name** - - 为UNIQUE或PRIMARY KEY约束相关的索引声明一个表空间。如果没有提供这个子句,这个索引将在default\_tablespace中创建,如果default\_tablespace为空,将使用数据库的缺省表空间。 - -- **ENCRYPTION\_TYPE = encryption\_type\_value** - - 为ENCRYPTED WITH约束中的加密类型,encryption\_type\_value的值为\[ DETERMINISTIC | RANDOMIZED \] - - -## 示例 - -``` ---创建简单的表。 -openGauss=# CREATE TABLE tpcds.warehouse_t1 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); - -openGauss=# CREATE TABLE tpcds.warehouse_t2 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60), - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); -``` - -``` ---创建表,并指定W_STATE字段的缺省值为GA。 -openGauss=# CREATE TABLE tpcds.warehouse_t3 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) DEFAULT 'GA', - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); - ---创建表,并在事务结束时检查W_WAREHOUSE_NAME字段是否有重复。 -openGauss=# CREATE TABLE tpcds.warehouse_t4 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) UNIQUE DEFERRABLE, - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); -``` - -``` ---创建一个带有70%填充因子的表。 -openGauss=# CREATE TABLE tpcds.warehouse_t5 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2), - UNIQUE(W_WAREHOUSE_NAME) WITH(fillfactor=70) -); - ---或者用下面的语法。 -openGauss=# CREATE TABLE tpcds.warehouse_t6 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) UNIQUE, - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -) WITH(fillfactor=70); - ---创建表,并指定该表数据不写入预写日志。 -openGauss=# CREATE UNLOGGED TABLE tpcds.warehouse_t7 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); - ---创建表临时表。 -openGauss=# CREATE TEMPORARY TABLE warehouse_t24 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); - ---创建本地临时表,并指定提交事务时删除该临时表数据。 -openGauss=# CREATE TEMPORARY TABLE warehouse_t25 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -) ON COMMIT DELETE ROWS; - ---创建全局临时表,并指定会话结束时删除该临时表数据。当前Ustore存储引擎不支持全局临时表。 -openGauss=# CREATE GLOBAL TEMPORARY TABLE gtt1 -( - ID INTEGER NOT NULL, - NAME CHAR(16) NOT NULL, - ADDRESS VARCHAR(50) , - POSTCODE CHAR(6) -) ON COMMIT PRESERVE ROWS; - ---创建表时,不希望因为表已存在而报错。 -openGauss=# CREATE TABLE IF NOT EXISTS tpcds.warehouse_t8 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); - ---创建普通表空间。 -openGauss=# CREATE TABLESPACE DS_TABLESPACE1 RELATIVE LOCATION 'tablespace/tablespace_1'; ---创建表时,指定表空间。 -openGauss=# CREATE TABLE tpcds.warehouse_t9 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -) TABLESPACE DS_TABLESPACE1; - ---创建表时,单独指定W_WAREHOUSE_NAME的索引表空间。 -openGauss=# CREATE TABLE tpcds.warehouse_t10 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) UNIQUE USING INDEX TABLESPACE DS_TABLESPACE1, - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); -``` - -``` ---创建一个有主键约束的表。 -openGauss=# CREATE TABLE tpcds.warehouse_t11 -( - W_WAREHOUSE_SK INTEGER PRIMARY KEY, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); - ----或是用下面的语法,效果完全一样。 -openGauss=# CREATE TABLE tpcds.warehouse_t12 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2), - PRIMARY KEY(W_WAREHOUSE_SK) -); - ---或是用下面的语法,指定约束的名称。 -openGauss=# CREATE TABLE tpcds.warehouse_t13 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2), - CONSTRAINT W_CSTR_KEY1 PRIMARY KEY(W_WAREHOUSE_SK) -); - ---创建一个有复合主键约束的表。 -openGauss=# CREATE TABLE tpcds.warehouse_t14 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2), - CONSTRAINT W_CSTR_KEY2 PRIMARY KEY(W_WAREHOUSE_SK, W_WAREHOUSE_ID) -); ---创建列存表。 -openGauss=# CREATE TABLE tpcds.warehouse_t15 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -) WITH (ORIENTATION = COLUMN); - ---创建局部聚簇存储的列存表。 -openGauss=# CREATE TABLE tpcds.warehouse_t16 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2), - PARTIAL CLUSTER KEY(W_WAREHOUSE_SK, W_WAREHOUSE_ID) -) WITH (ORIENTATION = COLUMN); - ---定义一个带压缩的列存表。 -openGauss=# CREATE TABLE tpcds.warehouse_t17 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -) WITH (ORIENTATION = COLUMN, COMPRESSION=HIGH); - - ---定义一个检查列约束。 -openGauss=# CREATE TABLE tpcds.warehouse_t19 -( - W_WAREHOUSE_SK INTEGER PRIMARY KEY CHECK (W_WAREHOUSE_SK > 0), - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) CHECK (W_WAREHOUSE_NAME IS NOT NULL), - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); - -openGauss=# CREATE TABLE tpcds.warehouse_t20 -( - W_WAREHOUSE_SK INTEGER PRIMARY KEY, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) CHECK (W_WAREHOUSE_NAME IS NOT NULL), - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2), - CONSTRAINT W_CONSTR_KEY2 CHECK(W_WAREHOUSE_SK > 0 AND W_WAREHOUSE_NAME IS NOT NULL) -); - ---创建一个有外键约束的表。 -openGauss=# CREATE TABLE tpcds.city_t23 -( - W_CITY VARCHAR(60) PRIMARY KEY, - W_ADDRESS TEXT -); -openGauss=# CREATE TABLE tpcds.warehouse_t23 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) REFERENCES tpcds.city_t23(W_CITY), - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) -); - ---或是用下面的语法,效果完全一样。 -openGauss=# CREATE TABLE tpcds.warehouse_t23 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) , - FOREIGN KEY(W_CITY) REFERENCES tpcds.city_t23(W_CITY) -); - ---或是用下面的语法,指定约束的名称。 -openGauss=# CREATE TABLE tpcds.warehouse_t23 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) , - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) , - CONSTRAINT W_FORE_KEY1 FOREIGN KEY(W_CITY) REFERENCES tpcds.city_t23(W_CITY) -); - ---向tpcds.warehouse_t19表中增加一个varchar列。 -``` - -``` -openGauss=# ALTER TABLE tpcds.warehouse_t19 ADD W_GOODS_CATEGORY varchar(30); - ---给tpcds.warehouse_t19表增加一个检查约束。 -openGauss=# ALTER TABLE tpcds.warehouse_t19 ADD CONSTRAINT W_CONSTR_KEY4 CHECK (W_STATE IS NOT NULL); - ---在一个操作中改变两个现存字段的类型。 -openGauss=# ALTER TABLE tpcds.warehouse_t19 - ALTER COLUMN W_GOODS_CATEGORY TYPE varchar(80), - ALTER COLUMN W_STREET_NAME TYPE varchar(100); - ---此语句与上面语句等效。 -openGauss=# ALTER TABLE tpcds.warehouse_t19 MODIFY (W_GOODS_CATEGORY varchar(30), W_STREET_NAME varchar(60)); - ---给一个已存在字段添加非空约束。 -openGauss=# ALTER TABLE tpcds.warehouse_t19 ALTER COLUMN W_GOODS_CATEGORY SET NOT NULL; - ---移除已存在字段的非空约束。 -openGauss=# ALTER TABLE tpcds.warehouse_t19 ALTER COLUMN W_GOODS_CATEGORY DROP NOT NULL; - ---如果列存表中还未指定局部聚簇,向在一个列存表中添加局部聚簇列。 -openGauss=# ALTER TABLE tpcds.warehouse_t17 ADD PARTIAL CLUSTER KEY(W_WAREHOUSE_SK); - ---查看约束的名称,并删除一个列存表中的局部聚簇列。 -openGauss=# \d+ tpcds.warehouse_t17 - Table "tpcds.warehouse_t17" - Column | Type | Modifiers | Storage | Stats target | Description --------------------+-----------------------+-----------+----------+--------------+------------- - w_warehouse_sk | integer | not null | plain | | - w_warehouse_id | character(16) | not null | extended | | - w_warehouse_name | character varying(20) | | extended | | - w_warehouse_sq_ft | integer | | plain | | - w_street_number | character(10) | | extended | | - w_street_name | character varying(60) | | extended | | - w_street_type | character(15) | | extended | | - w_suite_number | character(10) | | extended | | - w_city | character varying(60) | | extended | | - w_county | character varying(30) | | extended | | - w_state | character(2) | | extended | | - w_zip | character(10) | | extended | | - w_country | character varying(20) | | extended | | - w_gmt_offset | numeric(5,2) | | main | | -Partial Cluster : - "warehouse_t17_cluster" PARTIAL CLUSTER KEY (w_warehouse_sk) -Has OIDs: no -Location Nodes: ALL DATANODES -Options: compression=no, version=0.12 -openGauss=# ALTER TABLE tpcds.warehouse_t17 DROP CONSTRAINT warehouse_t17_cluster; - ---将表移动到另一个表空间。 -openGauss=# ALTER TABLE tpcds.warehouse_t19 SET TABLESPACE PG_DEFAULT; ---创建模式joe。 -openGauss=# CREATE SCHEMA joe; - ---将表移动到另一个模式中。 -openGauss=# ALTER TABLE tpcds.warehouse_t19 SET SCHEMA joe; - ---重命名已存在的表。 -openGauss=# ALTER TABLE joe.warehouse_t19 RENAME TO warehouse_t23; - ---从warehouse_t23表中删除一个字段。 -openGauss=# ALTER TABLE joe.warehouse_t23 DROP COLUMN W_STREET_NAME; - ---创建带INVISIBLE唯一索引的表,需要在B兼容性数据库下 -openGauss=# CREATE TABLE tpcds.warehouse_t26 -( - W_WAREHOUSE_SK INTEGER NOT NULL, - W_WAREHOUSE_ID CHAR(16) NOT NULL, - W_WAREHOUSE_NAME VARCHAR(20) UNIQUE, - W_WAREHOUSE_SQ_FT INTEGER , - W_STREET_NUMBER CHAR(10) , - W_STREET_NAME VARCHAR(60) , - W_STREET_TYPE CHAR(15) , - W_SUITE_NUMBER CHAR(10) , - W_CITY VARCHAR(60) , - W_COUNTY VARCHAR(30) , - W_STATE CHAR(2) , - W_ZIP CHAR(10) , - W_COUNTRY VARCHAR(20) , - W_GMT_OFFSET DECIMAL(5,2) , - UNIQUE uni_t26 (W_WAREHOUSE_SK) INVISIBLE -) WITH(fillfactor=70); - ---删除表空间、模式joe和模式表warehouse。 -openGauss=# DROP TABLE tpcds.warehouse_t1; -openGauss=# DROP TABLE tpcds.warehouse_t2; -openGauss=# DROP TABLE tpcds.warehouse_t3; -openGauss=# DROP TABLE tpcds.warehouse_t4; -openGauss=# DROP TABLE tpcds.warehouse_t5; -openGauss=# DROP TABLE tpcds.warehouse_t6; -openGauss=# DROP TABLE tpcds.warehouse_t7; -openGauss=# DROP TABLE tpcds.warehouse_t8; -openGauss=# DROP TABLE tpcds.warehouse_t9; -openGauss=# DROP TABLE tpcds.warehouse_t10; -openGauss=# DROP TABLE tpcds.warehouse_t11; -openGauss=# DROP TABLE tpcds.warehouse_t12; -openGauss=# DROP TABLE tpcds.warehouse_t13; -openGauss=# DROP TABLE tpcds.warehouse_t14; -openGauss=# DROP TABLE tpcds.warehouse_t15; -openGauss=# DROP TABLE tpcds.warehouse_t16; -openGauss=# DROP TABLE tpcds.warehouse_t17; -openGauss=# DROP TABLE tpcds.warehouse_t18; -openGauss=# DROP TABLE tpcds.warehouse_t20; -openGauss=# DROP TABLE tpcds.warehouse_t21; -openGauss=# DROP TABLE tpcds.warehouse_t22; -openGauss=# DROP TABLE joe.warehouse_t23; -openGauss=# DROP TABLE tpcds.warehouse_t24; -openGauss=# DROP TABLE tpcds.warehouse_t25; -openGauss=# DROP TABLE tpcds.warehouse_t26; -openGauss=# DROP TABLESPACE DS_TABLESPACE1; -openGauss=# DROP SCHEMA IF EXISTS joe CASCADE; -``` - -## 相关链接 - -[ALTER TABLE](ALTER-TABLE.md),[DROP TABLE](DROP-TABLE.md),[CREATE TABLESPACE](CREATE-TABLESPACE.md) - -## 优化建议 - -- UNLOGGED - - UNLOGGED表和表上的索引因为数据写入时不通过WAL日志机制,写入速度远高于普通表。因此,可以用于缓冲存储复杂查询的中间结果集,增强复杂查询的性能。 - - UNLOGGED表无主备机制,在系统故障或异常断点等情况下,会有数据丢失风险,因此,不可用来存储基础数据。 - -- TEMPORARY | TEMP - - - 临时表只在当前会话可见,会话结束后会自动删除。 - -- 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子句。默认情况下,不拷贝源表的分区定义。 - - >![](public_sys-resources/icon-notice.png) **须知:** - > - >列表/哈希分区表暂不支持LIKE INCLUDING PARTITION。 - -- LIKE INCLUDING RELOPTIONS - - - 如果指定了INCLUDING RELOPTIONS,则源表的存储参数(即源表的WITH子句)会复制到新表中。默认情况下,不复制源表的存储参数。 - -- LIKE INCLUDING ALL - - - INCLUDING ALL包含了INCLUDING DEFAULTS、INCLUDING CONSTRAINTS、INCLUDING INDEXES、INCLUDING STORAGE、INCLUDING COMMENTS、INCLUDING PARTITION、INCLUDING RELOPTIONS的内容。 - -- ORIENTATION ROW - - - 创建行存表,行存储适合于OLTP业务,此类型的表上交互事务比较多,一次交互会涉及表中的多个列,用行存查询效率较高。 - -- ORIENTATION COLUMN - - - 创建列存表,列存储适合于数据仓库业务,此类型的表上会做大量的汇聚计算,且涉及的列操作较少。 - +# CREATE TABLE + +## 功能描述 + +在当前数据库中创建一个新的空白表,该表由命令执行者所有。 + +## 注意事项 + +- 列存表支持的数据类型请参考[列存表支持的数据类型](列存表支持的数据类型.md)。 +- 列存表不支持数组。 +- 列存表不支持生成列。 +- 列存表不支持创建全局临时表。 +- 创建列存表的数量建议不超过1000个。 +- 如果在建表过程中数据库系统发生故障,系统恢复后可能无法自动清除之前已创建的、大小为0的磁盘文件。此种情况出现概率小,不影响数据库系统的正常运行。 +- 列存表的表级约束只支持PARTIAL CLUSTER KEY、UNIQUE、PRIAMRY KEY,不支持外键等表级约束。 +- 列存表的字段约束只支持NULL、NOT NULL、DEFAULT常量值、UNIQUE和PRIMARY KEY。 +- 列存表支持delta表,受参数enable\_delta\_store控制是否开启,受参数deltarow\_threshold控制进入delta表的阀值。 +- 列存表的字段的字符集必须与数据库字符集一致。 +- 使用JDBC时,支持通过PrepareStatement对DEFAULT值进行参数化设置。 +- 每张表的列数最大为1600,具体取决于列的类型,所有列的大小加起来不能超过8192 byte(由于数据存储形式原因,实际上限略小于8192 byte),text、varchar、char等长度可变的类型除外。 +- 被授予CREATE ANY TABLE权限的用户,可以在public模式和用户模式下创建表。如果想要创建包含serial类型列的表,还需要授予CREATE ANY SEQUENCE创建序列的权限。 +- 不可与同一模式下已存在的synonym产生命名冲突。 +- 仅支持在B兼容性数据库下指定COMMENT和可见性VISIBLE\INVISIBLE。 + +## 语法格式 + +创建表。 + +``` +CREATE [ [ GLOBAL | LOCAL ] [ TEMPORARY | TEMP ] | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name + ({ column_name data_type [ CHARACTER SET | CHARSET charset ] [ compress_mode ] [ COLLATE collation ] [ column_constraint [ ... ] ] + | table_constraint + | LIKE source_table [ like_option [...] ] } + [, ... ]) + [ AUTO_INCREMENT [ = ] value ] + [ [DEFAULT] CHARACTER SET | CHARSET [ = ] default_charset ] [ [DEFAULT] COLLATE [ = ] default_collation ] + [ WITH ( {storage_parameter = value} [, ... ] ) ] + [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] + [ COMPRESS | NOCOMPRESS ] + [ TABLESPACE tablespace_name ] + [ COMMENT {=| } 'text' ]; +``` + +- 其中列约束column\_constraint为: + + ``` + [ CONSTRAINT constraint_name ] + { NOT NULL | + NULL | + CHECK ( expression ) | + DEFAULT default_expr | + GENERATED ALWAYS AS ( generation_expr ) [STORED] | + AUTO_INCREMENT | + ON UPDATE update_expr | + UNIQUE [KEY] index_parameters | + ENCRYPTED WITH ( COLUMN_ENCRYPTION_KEY = column_encryption_key, ENCRYPTION_TYPE = encryption_type_value ) | + 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 ] + [ COMMENT {=| } 'text' ] + ``` + + +- 其中列的压缩可选项compress\_mode为: + + ``` + { DELTA | PREFIX | DICTIONARY | NUMSTR | NOCOMPRESS } + ``` + +- 其中表约束table\_constraint为: + + ``` + [ CONSTRAINT [ constraint_name ] ] + { CHECK ( expression ) | + UNIQUE [ index_name ][ USING method ] ( { { column_name | ( expression ) } [ ASC | DESC ] } [, ... ] ) index_parameters [ VISIBLE | INVISIBLE ] | + PRIMARY KEY [ USING method ] ( { column_name [ ASC | DESC ] } [, ... ] ) index_parameters [ VISIBLE | INVISIBLE ] | + FOREIGN KEY [ index_name ] ( column_name [, ... ] ) REFERENCES reftable [ (refcolumn [, ... ] ) ] + [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] | + PARTIAL CLUSTER KEY ( column_name [, ... ] ) } + [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] + [ COMMENT {=| } 'text' ] + ``` + + +- 其中like选项like\_option为: + + ``` + { INCLUDING | EXCLUDING } { DEFAULTS | GENERATED | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | PARTITION | RELOPTIONS | ALL } + ``` + +- 其中索引参数index\_parameters为: + + ``` + [ WITH ( {storage_parameter = value} [, ... ] ) ] + [ USING INDEX TABLESPACE tablespace_name ] + ``` + + +## 参数说明 + +- **UNLOGGED** + + 如果指定此关键字,则创建的表为非日志表。在非日志表中写入的数据不会被写入到预写日志中,这样就会比普通表快很多。但是非日志表在冲突、执行操作系统重启、数据库重启、主备切换、切断电源操作或异常关机后会被自动截断,会造成数据丢失的风险。非日志表中的内容也不会被复制到备服务器中。在非日志表中创建的索引也不会被自动记录。 + + 使用场景:非日志表不能保证数据的安全性,用户应该在确保数据已经做好备份的前提下使用,例如系统升级时进行数据的备份。 + + 故障处理:当异常关机等操作导致非日志表上的索引发生数据丢失时,用户应该对发生错误的索引进行重建。 + +- **GLOBAL | LOCAL** + + 创建临时表时可以在TEMP或TEMPORARY前指定GLOBAL或LOCAL关键字。如果指定GLOBAL关键字,openGauss会创建全局临时表,否则openGauss会创建本地临时表。 + +- **TEMPORARY | TEMP** + + 如果指定TEMP或TEMPORARY关键字,则创建的表为临时表。临时表分为全局临时表和本地临时表两种类型。创建临时表时如果指定GLOBAL关键字则为全局临时表,否则为本地临时表。 + + 全局临时表的元数据对所有会话可见,会话结束后元数据继续存在。会话与会话之间的用户数据、索引和统计信息相互隔离,每个会话只能看到和更改自己提交的数据。全局临时表有两种模式:一种是基于会话级别的\(ON COMMIT PRESERVE ROWS\), 当会话结束时自动清空用户数据;一种是基于事务级别的\(ON COMMIT DELETE ROWS\), 当执行commit或rollback时自动清空用户数据。建表时如果没有指定ON COMMIT选项,则缺省为会话级别。与本地临时表不同,全局临时表建表时可以指定非pg\_temp\_开头的schema。 + + 本地临时表只在当前会话可见,本会话结束后会自动删除。因此,在除当前会话连接的数据库节点故障时,仍然可以在当前会话上创建和使用临时表。由于临时表只在当前会话创建,对于涉及对临时表操作的DDL语句,会产生DDL失败的报错。因此,建议DDL语句中不要对临时表进行操作。TEMP和TEMPORARY等价。 + + >![](public_sys-resources/icon-notice.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](../DatabaseReference/全局临时表.md#section18307271684)控制是否启用。如果max\_active\_global\_temporary\_table=0,关闭全局临时表功能。 + >- 临时表只对当前会话可见,因此不支持与\\parallel on并行执行一起使用。 + >- 临时表不支持主备切换。 + >- 全局临时表不响应自动清理,在长链接场景使用时尽量使用on commit delete rows的全局临时表,或定期手动执行vacuum,否则可能导致clog日志不回收。 + +- **IF NOT EXISTS** + + 如果已经存在相同名称的表,不会报出错误,而会发出通知,告知通知此表已存在。 + +- **table\_name** + + 要创建的表名。 + + ![](public_sys-resources/icon-notice.png) **须知:** + + 物化视图的一些处理逻辑会通过表名的前缀来识别是不是物化视图日志表和物化视图关联表,因此,用户不要创建表名以mlog\_或matviewmap\_为前缀的表,否则会影响此表的一些功能。 + +- **column\_name** + + 新表中要创建的字段名。 + +- **constraint\_name** + + 建表时指定的约束名称。 + + >![](public_sys-resources/icon-notice.png) **须知:** + > + >在B模式数据库下(即sql\_compatibility = 'B')constraint\_name为可选项,在其他模式数据库下,必须加上constraint\_name。 + +- **index\_name** + + 索引名。 + + >![](public_sys-resources/icon-notice.png) **须知:** + > + >- index\_name仅在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库下不支持。 + >- 对于外键约束,constraint\_name和index\_name同时指定时,索引名为constraint\_name。 + >- 对于唯一键约束,constraint\_name和index\_name同时指定时,索引名以index\_name。 + +- **USING method** + + 指定创建索引的方法。 + + 取值范围参考[参数说明](CREATE-INDEX.md)中的USING method。 + + >![](public_sys-resources/icon-notice.png) **须知:** + > + >- USING method仅在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库下不支持。 + >- 在B模式下,未指定USING method时,对于ASTORE的存储方式,默认索引方法为btree;对于USTORE的存储方式,默认索引方法为ubtree。 + +- **ASC | DESC** + + ASC表示指定按升序排序(默认)。DESC指定按降序排序。 + + >![](public_sys-resources/icon-notice.png) **须知:** + > + >ASC|DESC只在B模式数据库下(即sql\_compatibility = 'B')支持,其他模式数据库不支持。 + +- **expression** + + 创建一个基于该表的一个或多个字段的表达式索引约束,必须写在圆括弧中。 + + >![](public_sys-resources/icon-notice.png) **须知:** + > + >表达式索引只在B模式数据库下支持(即sql\_compatibility = 'B'),其他模式数据库不支持。 + + +- **data\_type** + + 字段的数据类型。 + + +- **column\_constraint** + + 字段的类型约束中,添加了mysql的ON UPDATE特性,归类于字段类型约束。与DEFAULT属性属于同类约束。该ON UPDATE属性用于,执行UPDATE操作timestamp字段为缺省时,则自动更新timestamp字段的时间截。如果更新字段的数据内容与原来的数据内容一致,则其他含有ON UPDATE的字段的时间截不会自动更新。 + + ```sql + CREATE TABLE table_name(column_name timestamp ON UPDATE CURRENT_TIMESTAMP); + ``` + +- **compress\_mode** + + 表字段的压缩选项。该选项指定表字段优先使用的压缩算法。行存表不支持压缩。 + + 取值范围:DELTA、PREFIX、DICTIONARY、NUMSTR、NOCOMPRESS + + - DELTA压缩仅支持长度为1-8字节的数据类型(0 < pg_type.typlen <= 8)。 + - PREFIX、NUMSTR压缩仅支持变长数据类型(pg_type.typlen = -1)和NULL结尾的C字符串(pg_type.typlen = -2)。 + - 该压缩选项与列存表自适应压缩算法无关,后者为列存表内部数据存储采用的压缩算法,不支持用户指定。 + +- **CHARACTER SET | CHARSET charset** + + 只在B模式数据库下(即sql\_compatibility = 'B')支持该语法,其他模式数据库不支持。指定表字段的字符集,单独指定时会将字段的字符序设置为指定的字符集的默认字符序。 + +- **COLLATE collation** + + COLLATE子句指定列的排序规则(字符序)(该列必须是可排列的数据类型)。如果没有指定,则使用默认的排序规则。排序规则可以使用“select \* from pg\_collation;”命令从pg\_collation系统表中查询,默认的排序规则为查询结果中以default开始的行。对于B模式数据库下(即sql\_compatibility = 'B')还支持utf8mb4\_bin、utf8mb4\_general\_ci、utf8mb4\_unicode\_ci、binary字符序。 + + > **说明:** + > + >- 仅字符类型支持指定字符集,指定为binary字符集或字符序实际是将字符类型转化为对应的二进制类型,若类型映射不存在则报错。当前仅有TEXT类型转化为BLOB的映射。 + >- 除binary字符集和字符序外,当前仅支持指定与数据库编码相同的字符集。 + >- 未显式指定字段字符集或字符序时,若指定了表的默认字符集或字符序,字段字符集和字符序将从表上继承。若表的默认字符集或字符序不存在,当b\_format\_behavior\_compat\_options = 'default\_collation'时,字段的字符集和字符序将继承当前数据库的字符集及其对应的默认字符序。 + + **表 1** B模式(即sql\_compatibility = 'B')下支持的字符集和字符序介绍 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

字符序名称

+

对应的字符集

+

描述

+

utf8mb4_general_ci

+

utf8mb4(即utf8)

+

使用通用排序规则,不区分大小写。

+

utf8mb4_unicode_ci

+

utf8mb4(即utf8)

+

使用通用排序规则,不区分大小写。

+

utf8mb4_bin

+

utf8mb4(即utf8)

+

使用二进制排序规则,区分大小写。

+

binary

+

binary

+

使用二进制排序规则。

+

utf8_general_ci

+

utf8

+

使用通用排序规则,不区分大小写。

+

utf8_unicode_ci

+

utf8

+

使用通用排序规则,不区分大小写。

+

utf8_bin

+

utf8

+

使用二进制排序规则,区分大小写。

+
+ +- **LIKE source\_table \[ like\_option ... \]** + + LIKE子句声明一个表,新表自动从这个表中继承所有字段名及其数据类型和非空约束。 + + 新表与源表之间在创建动作完毕之后是完全无关的。在源表做的任何修改都不会传播到新表中,并且也不可能在扫描源表的时候包含新表的数据。 + + 被复制的列和约束并不使用相同的名称进行融合。如果明确的指定了相同的名称或者在另外一个LIKE子句中,将会报错。 + + - 源表上的字段缺省表达式只有在指定INCLUDING DEFAULTS时,才会复制到新表中。缺省是不包含缺省表达式的,即新表中的所有字段的缺省值都是NULL。 + - 源表上的CHECK约束仅在指定INCLUDING CONSTRAINTS时,会复制到新表中,而其他类型的约束永远不会复制到新表中。非空约束总是复制到新表中。此规则同时适用于表约束和列约束。 + - 如果指定了INCLUDING INDEXES,则源表上的索引也将在新表上创建,默认不建立索引。 + - 如果指定了INCLUDING STORAGE,则复制列的STORAGE设置会复制到新表中,默认情况下不包含STORAGE设置。 + - 如果指定了INCLUDING COMMENTS,则源表列、约束和索引的注释会复制到新表中。默认情况下,不复制源表的注释。 + - 如果指定了INCLUDING PARTITION,则源表的分区定义会复制到新表中,同时新表将不能再使用PARTITION BY子句。默认情况下,不拷贝源表的分区定义。如果源表上带有索引,可以使用INCLUDING PARTITION INCLUDING INDEXES语法实现。如果对分区表只使用INCLUDING INDEXES,目标表定义将是普通表,但是索引是分区索引,最后结果会报错,因为普通表不支持分区索引。 + - 如果指定了INCLUDING RELOPTIONS,则源表的存储参数(即源表的WITH子句)会复制到新表中。默认情况下,不复制源表的存储参数。 + - INCLUDING ALL包含了INCLUDING DEFAULTS、INCLUDING CONSTRAINTS、INCLUDING INDEXES、INCLUDING STORAGE、INCLUDING COMMENTS、INCLUDING PARTITION和INCLUDING RELOPTIONS的内容。 + - ATUO_INCREMENT列需要为主键或唯一约束的第一个字段,若复制包含AUTO_INCREAMENT列的表时指定EXCLUDING INDEX,将会报错。其中AUTO_INCREAMENT只在B库中生效。 + + >![](public_sys-resources/icon-notice.png) **须知:** + > + >- 如果源表包含serial、bigserial、smallserial、largeserial类型,或者源表字段的默认值是sequence,且sequence属于源表(通过CREATE SEQUENCE ... OWNED BY创建),这些Sequence不会关联到新表中,新表中会重新创建属于自己的sequence。这和之前版本的处理逻辑不同。如果用户希望源表和新表共享Sequence,需要首先创建一个共享的Sequence(避免使用OWNED BY),并配置为源表字段默认值,这样创建的新表会和源表共享该Sequence。 + > + >- 不建议将其他表私有的Sequence配置为源表字段的默认值,尤其是其他表只分布在特定的NodeGroup上,这可能导致CREATE TABLE ... LIKE执行失败。另外,如果源表配置其他表私有的Sequence,当该表删除时Sequence也会连带删除,这样源表的Sequence将不可用。如果用户希望多个表共享Sequence,建议创建共享的Sequence。 + > + >- 对于分区表EXCLUDING,需要配合INCLUDING ALL使用,如INCLUDING ALL EXCLUDING DEFAULTS,除源分区表的DEFAULTS,其它全包含。 + > + >- 如果源表是本地临时表,则新表也必须是本地临时表,否则会报错。 + > + >- 如果源表是hash或list分区表,则在CREATE TABLE ... (LIKE ... INCLUDIING PARTITION)时会报错,不支持复制hash或list分区表的分区,仅支持range分区。对于二级分区表,同样只支持range-range二级分区。 + +- **WITH \( \{ storage\_parameter = value \} \[, ... \] \)** + + 这个子句为表或索引指定一个可选的存储参数。用于表的WITH子句还可以包含OIDS=FALSE表示不分配OID。 + + >![](public_sys-resources/icon-note.png) **说明:** + > + >使用任意精度类型Numeric定义列时,建议指定精度p以及刻度s。在不指定精度和刻度时,会按输入的显示出来。 + + 参数的详细描述如下所示。 + + - FILLFACTOR + + 一个表的填充因子(fillfactor)是一个介于10和100之间的百分数。100(完全填充)是默认值。如果指定了较小的填充因子,INSERT操作仅按照填充因子指定的百分率填充表页。每个页上的剩余空间将用于在该页上更新行,这就使得UPDATE有机会在同一页上放置同一条记录的新版本,这比把新版本放置在其他页上更有效。对于一个从不更新的表将填充因子设为100是最佳选择,但是对于频繁更新的表,选择较小的填充因子则更加合适。该参数对于列存表没有意义。 + + 取值范围:10\~100 + + - ORIENTATION + + 指定表数据的存储方式,即行存方式、列存方式,该参数设置成功后就不再支持修改。 + + 取值范围: + + - ROW,表示表的数据将以行式存储。 + + 行存储适合于OLTP业务,适用于点查询或者增删操作较多的场景。 + + - COLUMN,表示表的数据将以列式存储。 + + 列存储适合于数据仓库业务,此类型的表上会做大量的汇聚计算,且涉及的列操作较少。该特性在金融版本下不支持 + + 默认值: + + 若指定表空间为普通表空间,默认值为ROW。 + + - STORAGE\_TYPE + + 指定存储引擎类型,该参数设置成功后就不再支持修改。 + + 取值范围: + + - USTORE,表示表支持Inplace-Update存储引擎。该特性在金融版本下不支持。 + - ASTORE,表示表支持Append-Only存储引擎。 + + 默认值: + + 不指定表时,默认是Append-Only存储。 + + - INIT\_TD + + 创建Ustore表时,指定初始化的TD个数,该参数只在创建Ustore表时才能设置生效。 + + 取值范围:2\~128,默认值为4。 + + - COMPRESSION + + 指定表数据的压缩级别,它决定了表数据的压缩比以及压缩时间。一般来讲,压缩级别越高,压缩比也越大,压缩时间也越长;反之亦然。实际压缩比取决于加载的表数据的分布特征。行存表默认增加COMPRESSION=NO字段。 + + 取值范围: + + 列存表的有效值为YES/NO/LOW/MIDDLE/HIGH,默认值为LOW。 + + - COMPRESSLEVEL + + 指定表数据同一压缩级别下的不同压缩水平,它决定了同一压缩级别下表数据的压缩比以及压缩时间。对同一压缩级别进行了更加详细的划分,为用户选择压缩比和压缩时间提供了更多的空间。总体来讲,此值越大,表示同一压缩级别下压缩比越大,压缩时间越长;反之亦然。 + + 取值范围:0\~3,默认值为0。 + + - COMPRESSTYPE + + 行存表参数,设置行存表压缩算法。1代表pglz算法(不推荐使用),2代表zstd算法,默认不压缩。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。(仅支持ASTORE和USTORE下的普通表和分区表) + 该特性在金融版本下不支持 + + 取值范围:0\~2,默认值为0。 + + - COMPRESS\_LEVEL + + 行存表参数,设置行存表压缩算法等级,仅当COMPRESSTYPE为2时生效。压缩等级越高,表的压缩效果越好,表的访问速度越慢。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + + 取值范围:-31\~31,默认值为0。 + + - COMPRESS\_CHUNK_SIZE + + 行存表参数,设置行存表压缩chunk块大小,仅当COMPRESSTYPE不为0时生效。chunk数据块越小,预期能达到的压缩效果越好,同时数据越离散,影响表的访问速度。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + 取值范围:与页面大小有关。在页面大小为8k场景,取值范围为:512、1024、2048、4096。 + + 默认值:4096 + + - COMPRESS_PREALLOC_CHUNKS + + 行存表参数,设置行存表压缩chunk块预分配数量。预分配数量越大,表的压缩率相对越差,离散度越小,访问性能越好。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + + 取值范围:0\~7,默认值为0。 + + - 当COMPRESS\_CHUNK_SIZE为512和1024时,支持预分配设置最大为7。 + - 当COMPRESS\_CHUNK_SIZE为2048时,支持预分配设置最大为3。 + - 当COMPRESS\_CHUNK_SIZE为4096时,支持预分配设置最大为1。 + + - COMPRESS_BYTE_CONVERT + + 行存表参数,设置行存表压缩字节转换预处理,仅当COMPRESSTYPE不为0时生效。在一些场景下可以提升压缩效果,同时会导致一定性能劣化。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + + 取值范围:布尔值,默认关闭。 + + - COMPRESS_DIFF_CONVERT + + 行存表参数,设置行存表压缩字节差分预处理。只能与compress_byte_convert一起使用。在一些场景下可以提升压缩效果,同时会导致一定性能劣化。该参数允许修改, 修改对已有数据、变更数据、新增数据同时生效。 + + 取值范围:布尔值,默认关闭。 + + - MAX\_BATCHROW + + 指定了在数据加载过程中一个存储单元可以容纳记录的最大数目。该参数只对列存表有效。 + + 取值范围:10000\~60000,默认60000。 + + - PARTIAL\_CLUSTER\_ROWS + + 指定了在数据加载过程中进行将局部聚簇存储的记录数目。该参数只对列存表有效。 + + 取值范围:大于等于MAX\_BATCHROW,建议取值为MAX\_BATCHROW的整数倍。 + + - DELTAROW\_THRESHOLD + + 指定列存表导入时小于多少行的数据进入delta表,只在GUC参数enable\_delta\_store开启时生效。该参数只对列存表有效。 + + 取值范围:0~9999,默认值为100 + + - segment + + 使用段页式的方式存储。本参数仅支持行存表。不支持列存表、临时表、unlog表。不支持ustore存储引擎。 + + 取值范围:on/off + + 默认值:off + + - dek\_cipher + + 透明数据加密密钥的密文。当开启enable\_tde选项时会自动申请创建,用户不可单独指定。通过密钥轮转功能可以对密钥进行更新。 + + 取值范围:字符串。 + + 默认值:不开启加密时默认为空。 + + - hasuids + + 参数开启:更新表元组时,为元组分配表级唯一标识id。 + + 取值范围:on/off。 + + 默认值:off。 + + + collate + + 在B模式数据库下(即sql\_compatibility = 'B')用于记录表的默认字符序,一般只用于内部存储和导入导出,不推荐用户指定或修改。 + + 取值范围:B模式数据库中独立支持的字符序的oid。 + + 默认值:0。 + +- **WITHOUT OIDS** + + 等价于WITH(OIDS=FALSE)的语法。 + +- **ON COMMIT \{ PRESERVE ROWS | DELETE ROWS | DROP \}** + + ON COMMIT选项决定在事务中执行创建临时表操作,当事务提交时,此临时表的后续操作。有以下三个选项,当前支持PRESERVE ROWS和DELETE ROWS选项。 + + - PRESERVE ROWS(缺省值):提交时不对临时表做任何操作,临时表及其表数据保持不变。 + - DELETE ROWS:提交时删除临时表中数据。 + - DROP:提交时删除此临时表。只支持本地临时表,不支持全局临时表。 + +- **COMPRESS | NOCOMPRESS** + + 创建新表时,需要在CREATE TABLE语句中指定关键字COMPRESS,这样,当对该表进行批量插入时就会触发压缩特性。该特性会在页范围内扫描所有元组数据,生成字典、压缩元组数据并进行存储。指定关键字NOCOMPRESS则不对表进行压缩。行存表不支持压缩。 + + 缺省值:NOCOMPRESS,即不对元组数据进行压缩。 + +- **TABLESPACE tablespace\_name** + + 创建新表时指定此关键字,表示新表将要在指定表空间内创建。如果没有声明,将使用默认表空间。 + +- **COMMNET {=| } text** + + 创建新表时指定此关键字,表示新表的注释内容。如果没有声明,则不创建注释。 + +- **CONSTRAINT constraint\_name** + + 列约束或表约束的名称。可选的约束子句用于声明约束,新行或者更新的行必须满足这些约束才能成功插入或更新。 + + 定义约束有两种方法: + + - 列约束:作为一个列定义的一部分,仅影响该列。 + - 表约束:不和某个列绑在一起,可以作用于多个列。 + +- **NOT NULL** + + 字段值不允许为NULL。 + +- **NULL** + + 字段值允许为NULL ,这是缺省值。 + + 这个子句只是为和非标准SQL数据库兼容。不建议使用。 + +- **CHECK \( expression \)** + + CHECK约束声明一个布尔表达式,每次要插入的新行或者要更新的行的新值必须使表达式结果为真或未知才能成功,否则会抛出一个异常并且不会修改数据库。 + + 声明为字段约束的检查约束应该只引用该字段的数值,而在表约束里出现的表达式可以引用多个字段。 + + >![](public_sys-resources/icon-note.png) **说明:** + > + >expression表达式中,如果存在“<\>NULL”或“!=NULL”,这种写法是无效的,需要写成“is NOT NULL”。 + + +- **DEFAULT default\_expr** + + DEFAULT子句给字段指定缺省值。该数值可以是任何不含变量的表达式\(不允许使用子查询和对本表中的其他字段的交叉引用\)。缺省表达式的数据类型必须和字段类型匹配。 + + 缺省表达式将被用于任何未声明该字段数值的插入操作。如果没有指定缺省值则缺省值为NULL 。 + ++ **GENERATED ALWAYS AS \( generation\_expr \) \[STORED\]** + + 该子句将字段创建为生成列,生成列的值在写入(插入或更新)数据时由generation\_expr计算得到,STORED表示像普通列一样存储生成列的值。 + + >![](public_sys-resources/icon-note.png) **说明:** + > + >- STORED关键字可省略,与不省略STORED语义相同。 + >- 生成表达式不能以任何方式引用当前行以外的其他数据。生成表达式不能引用其他生成列,不能引用系统列。生成表达式不能返回结果集,不能使用子查询,不能使用聚集函数,不能使用窗口函数。生成表达式调用的函数只能是不可变(IMMUTABLE)函数。 + >- 不能为生成列指定默认值。 + >- 生成列不能作为分区键的一部分。 + >- 生成列不能和ON UPDATE约束字句的CASCADE,SET NULL,SET DEFAULT动作同时指定。生成列不能和ON DELETE约束字句的SET NULL,SET DEFAULT动作同时指定。 + >- 修改和删除生成列的方法和普通列相同。删除生成列依赖的普通列,生成列被自动删除。不能改变生成列所依赖的列的类型。 + >- 生成列不能被直接写入。在INSERT或UPDATE命令中, 不能为生成列指定值, 但是可以指定关键字DEFAULT。 + >- 生成列的权限控制和普通列一样。 + >- 列存表、内存表MOT不支持生成列。外表中仅postgres\_fdw支持生成列。 + + +- **AUTO\_INCREMENT** + + 该关键字将字段指定为自动增长列。 + + 若在插入时不指定此列的值(或指定此列的值为0、NULL、DEFAULT),此列的值将由自增计数器自动增长得到。 + + 若插入或更新此列为一个大于当前自增计数器的值,执行成功后,自增计数器将刷新为此值。 + + 自增初始值由“AUTO\_INCREMENT \[ = \] value”子句设置,若不设置,默认为1。 + + >![](public_sys-resources/icon-note.png) **说明:** + > + >- 仅在参数sql\_compatibility=B时可以指定自动增长列。 + >- 自动增长列数据类型只能为整数类型、4字节或8字节浮点类型。 + >- 每个表只能有一个自动增长列。 + >- 自动增长列必须是主键约束或唯一约束的第一个字段。 + >- 自动增长列不能指定DEFAULT缺省值。 + >- CHECK约束的表达式中不能含有自动增长列。 + >- 可以指定自动增长列允许NULL,若不指定,默认自动增长列含有NOT NULL约束。 + >- 含有自动增长列的表创建时,会创建一个依赖于此列的序列作为自增计数器,不允许通过序列相关功能修改或删除此序列,可以查看序列的值。 + >- 本地临时表中的自动增长列不会创建序列。 + >- 自动增长列不支持列式存储。 + >- 自增计数器自增和刷新操作不会回滚。 + + +- **\[DEFAULT\] CHARACTER SET | CHARSET \[ = \] default\_charset** + + 仅在sql\_compatibility='B'时支持该语法。指定表的默认字符集,单独指定时会将表的默认字符序设置为指定的字符集的默认字符序。 + +- **\[DEFAULT\] COLLATE \[ = \] default\_collation** + + 仅在sql\_compatibility='B'时支持该语法。指定表的默认字符序,单独指定时会将表的默认字符集设置为指定的字符序对应的字符集。字符序参见[表1 B模式(即sql\_compatibility = 'B')下支持的字符集和字符序介绍](#table8163190152)。 + + >![](public_sys-resources/icon-note.png) **说明:** + >未显式指定表的字符集或字符序时,若指定了模式的默认字符集或字符序,表字符集和字符序将从模式上继承。若模式的默认字符集或字符序不存在,当b\_format\_behavior\_compat\_options = 'default\_collation'时,表的字符集和字符序将继承当前数据库的字符集及其对应的默认字符序。 + +- **UNIQUE \[KEY\] index\_parameters** + + **UNIQUE \( column\_name \[, ... \] \) index\_parameters** + + UNIQUE约束表示表里的一个字段或多个字段的组合必须在全表范围内唯一。 + + 对于唯一约束,NULL被认为是互不相等的。 + + UNIQUE KEY只能在sql\_compatibility='B'时使用,与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** + + 这两个关键字设置该约束是否可推迟。一个不可推迟的约束将在每条命令之后马上检查。可推迟约束可以推迟到事务结尾使用SET CONSTRAINTS命令检查。缺省是NOT DEFERRABLE。目前,UNIQUE约束、主键约束、外键约束可以接受这个子句。所有其他约束类型都是不可推迟的。 + + ![](public_sys-resources/icon-note.png) **说明:** + Ustore表不支持**DEFERRABLE以及INITIALLY DEFERRED**关键字。 + +- **COMMENT text** + + 注释。 + +- **VISIBLE | INVISIBLE** + + 指定索引是否可见,如果没有声明则默认为VISIBLE。 + +- **PARTIAL CLUSTER KEY** + + 局部聚簇存储,列存表导入数据时按照指定的列\(单列或多列\),进行局部排序。 + +- **INITIALLY IMMEDIATE | INITIALLY DEFERRED** + + 如果约束是可推迟的,则这个子句声明检查约束的缺省时间。 + + - 如果约束是INITIALLY IMMEDIATE(缺省),则在每条语句执行之后就立即检查它; + - 如果约束是INITIALLY DEFERRED ,则只有在事务结尾才检查它。 + + 约束检查的时间可以用SET CONSTRAINTS命令修改。 + +- **USING INDEX TABLESPACE tablespace\_name** + + 为UNIQUE或PRIMARY KEY约束相关的索引声明一个表空间。如果没有提供这个子句,这个索引将在default\_tablespace中创建,如果default\_tablespace为空,将使用数据库的缺省表空间。 + +- **ENCRYPTION\_TYPE = encryption\_type\_value** + + 为ENCRYPTED WITH约束中的加密类型,encryption\_type\_value的值为\[ DETERMINISTIC | RANDOMIZED \] + + +## 示例 + +``` +--创建简单的表。 +openGauss=# CREATE TABLE tpcds.warehouse_t1 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); + +openGauss=# CREATE TABLE tpcds.warehouse_t2 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60), + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); +``` + +``` +--创建表,并指定W_STATE字段的缺省值为GA。 +openGauss=# CREATE TABLE tpcds.warehouse_t3 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) DEFAULT 'GA', + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); + +--创建表,并在事务结束时检查W_WAREHOUSE_NAME字段是否有重复。 +openGauss=# CREATE TABLE tpcds.warehouse_t4 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) UNIQUE DEFERRABLE, + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); +``` + +``` +--创建一个带有70%填充因子的表。 +openGauss=# CREATE TABLE tpcds.warehouse_t5 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2), + UNIQUE(W_WAREHOUSE_NAME) WITH(fillfactor=70) +); + +--或者用下面的语法。 +openGauss=# CREATE TABLE tpcds.warehouse_t6 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) UNIQUE, + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +) WITH(fillfactor=70); + +--创建表,并指定该表数据不写入预写日志。 +openGauss=# CREATE UNLOGGED TABLE tpcds.warehouse_t7 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); + +--创建表临时表。 +openGauss=# CREATE TEMPORARY TABLE warehouse_t24 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); + +--创建本地临时表,并指定提交事务时删除该临时表数据。 +openGauss=# CREATE TEMPORARY TABLE warehouse_t25 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +) ON COMMIT DELETE ROWS; + +--创建全局临时表,并指定会话结束时删除该临时表数据。当前Ustore存储引擎不支持全局临时表。 +openGauss=# CREATE GLOBAL TEMPORARY TABLE gtt1 +( + ID INTEGER NOT NULL, + NAME CHAR(16) NOT NULL, + ADDRESS VARCHAR(50) , + POSTCODE CHAR(6) +) ON COMMIT PRESERVE ROWS; + +--创建表时,不希望因为表已存在而报错。 +openGauss=# CREATE TABLE IF NOT EXISTS tpcds.warehouse_t8 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); + +--创建普通表空间。 +openGauss=# CREATE TABLESPACE DS_TABLESPACE1 RELATIVE LOCATION 'tablespace/tablespace_1'; +--创建表时,指定表空间。 +openGauss=# CREATE TABLE tpcds.warehouse_t9 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +) TABLESPACE DS_TABLESPACE1; + +--创建表时,单独指定W_WAREHOUSE_NAME的索引表空间。 +openGauss=# CREATE TABLE tpcds.warehouse_t10 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) UNIQUE USING INDEX TABLESPACE DS_TABLESPACE1, + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); +``` + +``` +--创建一个有主键约束的表。 +openGauss=# CREATE TABLE tpcds.warehouse_t11 +( + W_WAREHOUSE_SK INTEGER PRIMARY KEY, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); + +---或是用下面的语法,效果完全一样。 +openGauss=# CREATE TABLE tpcds.warehouse_t12 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2), + PRIMARY KEY(W_WAREHOUSE_SK) +); + +--或是用下面的语法,指定约束的名称。 +openGauss=# CREATE TABLE tpcds.warehouse_t13 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2), + CONSTRAINT W_CSTR_KEY1 PRIMARY KEY(W_WAREHOUSE_SK) +); + +--创建一个有复合主键约束的表。 +openGauss=# CREATE TABLE tpcds.warehouse_t14 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2), + CONSTRAINT W_CSTR_KEY2 PRIMARY KEY(W_WAREHOUSE_SK, W_WAREHOUSE_ID) +); +--创建列存表。 +openGauss=# CREATE TABLE tpcds.warehouse_t15 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +) WITH (ORIENTATION = COLUMN); + +--创建局部聚簇存储的列存表。 +openGauss=# CREATE TABLE tpcds.warehouse_t16 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2), + PARTIAL CLUSTER KEY(W_WAREHOUSE_SK, W_WAREHOUSE_ID) +) WITH (ORIENTATION = COLUMN); + +--定义一个带压缩的列存表。 +openGauss=# CREATE TABLE tpcds.warehouse_t17 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +) WITH (ORIENTATION = COLUMN, COMPRESSION=HIGH); + + +--定义一个检查列约束。 +openGauss=# CREATE TABLE tpcds.warehouse_t19 +( + W_WAREHOUSE_SK INTEGER PRIMARY KEY CHECK (W_WAREHOUSE_SK > 0), + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) CHECK (W_WAREHOUSE_NAME IS NOT NULL), + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); + +openGauss=# CREATE TABLE tpcds.warehouse_t20 +( + W_WAREHOUSE_SK INTEGER PRIMARY KEY, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) CHECK (W_WAREHOUSE_NAME IS NOT NULL), + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2), + CONSTRAINT W_CONSTR_KEY2 CHECK(W_WAREHOUSE_SK > 0 AND W_WAREHOUSE_NAME IS NOT NULL) +); + +--创建一个有外键约束的表。 +openGauss=# CREATE TABLE tpcds.city_t23 +( + W_CITY VARCHAR(60) PRIMARY KEY, + W_ADDRESS TEXT +); +openGauss=# CREATE TABLE tpcds.warehouse_t23 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) REFERENCES tpcds.city_t23(W_CITY), + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) +); + +--或是用下面的语法,效果完全一样。 +openGauss=# CREATE TABLE tpcds.warehouse_t23 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) , + FOREIGN KEY(W_CITY) REFERENCES tpcds.city_t23(W_CITY) +); + +--或是用下面的语法,指定约束的名称。 +openGauss=# CREATE TABLE tpcds.warehouse_t23 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) , + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) , + CONSTRAINT W_FORE_KEY1 FOREIGN KEY(W_CITY) REFERENCES tpcds.city_t23(W_CITY) +); + +--向tpcds.warehouse_t19表中增加一个varchar列。 +``` + +``` +openGauss=# ALTER TABLE tpcds.warehouse_t19 ADD W_GOODS_CATEGORY varchar(30); + +--给tpcds.warehouse_t19表增加一个检查约束。 +openGauss=# ALTER TABLE tpcds.warehouse_t19 ADD CONSTRAINT W_CONSTR_KEY4 CHECK (W_STATE IS NOT NULL); + +--在一个操作中改变两个现存字段的类型。 +openGauss=# ALTER TABLE tpcds.warehouse_t19 + ALTER COLUMN W_GOODS_CATEGORY TYPE varchar(80), + ALTER COLUMN W_STREET_NAME TYPE varchar(100); + +--此语句与上面语句等效。 +openGauss=# ALTER TABLE tpcds.warehouse_t19 MODIFY (W_GOODS_CATEGORY varchar(30), W_STREET_NAME varchar(60)); + +--给一个已存在字段添加非空约束。 +openGauss=# ALTER TABLE tpcds.warehouse_t19 ALTER COLUMN W_GOODS_CATEGORY SET NOT NULL; + +--移除已存在字段的非空约束。 +openGauss=# ALTER TABLE tpcds.warehouse_t19 ALTER COLUMN W_GOODS_CATEGORY DROP NOT NULL; + +--如果列存表中还未指定局部聚簇,向在一个列存表中添加局部聚簇列。 +openGauss=# ALTER TABLE tpcds.warehouse_t17 ADD PARTIAL CLUSTER KEY(W_WAREHOUSE_SK); + +--查看约束的名称,并删除一个列存表中的局部聚簇列。 +openGauss=# \d+ tpcds.warehouse_t17 + Table "tpcds.warehouse_t17" + Column | Type | Modifiers | Storage | Stats target | Description +-------------------+-----------------------+-----------+----------+--------------+------------- + w_warehouse_sk | integer | not null | plain | | + w_warehouse_id | character(16) | not null | extended | | + w_warehouse_name | character varying(20) | | extended | | + w_warehouse_sq_ft | integer | | plain | | + w_street_number | character(10) | | extended | | + w_street_name | character varying(60) | | extended | | + w_street_type | character(15) | | extended | | + w_suite_number | character(10) | | extended | | + w_city | character varying(60) | | extended | | + w_county | character varying(30) | | extended | | + w_state | character(2) | | extended | | + w_zip | character(10) | | extended | | + w_country | character varying(20) | | extended | | + w_gmt_offset | numeric(5,2) | | main | | +Partial Cluster : + "warehouse_t17_cluster" PARTIAL CLUSTER KEY (w_warehouse_sk) +Has OIDs: no +Location Nodes: ALL DATANODES +Options: compression=no, version=0.12 +openGauss=# ALTER TABLE tpcds.warehouse_t17 DROP CONSTRAINT warehouse_t17_cluster; + +--将表移动到另一个表空间。 +openGauss=# ALTER TABLE tpcds.warehouse_t19 SET TABLESPACE PG_DEFAULT; +--创建模式joe。 +openGauss=# CREATE SCHEMA joe; + +--将表移动到另一个模式中。 +openGauss=# ALTER TABLE tpcds.warehouse_t19 SET SCHEMA joe; + +--重命名已存在的表。 +openGauss=# ALTER TABLE joe.warehouse_t19 RENAME TO warehouse_t23; + +--从warehouse_t23表中删除一个字段。 +openGauss=# ALTER TABLE joe.warehouse_t23 DROP COLUMN W_STREET_NAME; + +--创建带INVISIBLE唯一索引的表,需要在B兼容性数据库下 +openGauss=# CREATE TABLE tpcds.warehouse_t26 +( + W_WAREHOUSE_SK INTEGER NOT NULL, + W_WAREHOUSE_ID CHAR(16) NOT NULL, + W_WAREHOUSE_NAME VARCHAR(20) UNIQUE, + W_WAREHOUSE_SQ_FT INTEGER , + W_STREET_NUMBER CHAR(10) , + W_STREET_NAME VARCHAR(60) , + W_STREET_TYPE CHAR(15) , + W_SUITE_NUMBER CHAR(10) , + W_CITY VARCHAR(60) , + W_COUNTY VARCHAR(30) , + W_STATE CHAR(2) , + W_ZIP CHAR(10) , + W_COUNTRY VARCHAR(20) , + W_GMT_OFFSET DECIMAL(5,2) , + UNIQUE uni_t26 (W_WAREHOUSE_SK) INVISIBLE +) WITH(fillfactor=70); + +--删除表空间、模式joe和模式表warehouse。 +openGauss=# DROP TABLE tpcds.warehouse_t1; +openGauss=# DROP TABLE tpcds.warehouse_t2; +openGauss=# DROP TABLE tpcds.warehouse_t3; +openGauss=# DROP TABLE tpcds.warehouse_t4; +openGauss=# DROP TABLE tpcds.warehouse_t5; +openGauss=# DROP TABLE tpcds.warehouse_t6; +openGauss=# DROP TABLE tpcds.warehouse_t7; +openGauss=# DROP TABLE tpcds.warehouse_t8; +openGauss=# DROP TABLE tpcds.warehouse_t9; +openGauss=# DROP TABLE tpcds.warehouse_t10; +openGauss=# DROP TABLE tpcds.warehouse_t11; +openGauss=# DROP TABLE tpcds.warehouse_t12; +openGauss=# DROP TABLE tpcds.warehouse_t13; +openGauss=# DROP TABLE tpcds.warehouse_t14; +openGauss=# DROP TABLE tpcds.warehouse_t15; +openGauss=# DROP TABLE tpcds.warehouse_t16; +openGauss=# DROP TABLE tpcds.warehouse_t17; +openGauss=# DROP TABLE tpcds.warehouse_t18; +openGauss=# DROP TABLE tpcds.warehouse_t20; +openGauss=# DROP TABLE tpcds.warehouse_t21; +openGauss=# DROP TABLE tpcds.warehouse_t22; +openGauss=# DROP TABLE joe.warehouse_t23; +openGauss=# DROP TABLE tpcds.warehouse_t24; +openGauss=# DROP TABLE tpcds.warehouse_t25; +openGauss=# DROP TABLE tpcds.warehouse_t26; +openGauss=# DROP TABLESPACE DS_TABLESPACE1; +openGauss=# DROP SCHEMA IF EXISTS joe CASCADE; +``` + +## 相关链接 + +[ALTER TABLE](ALTER-TABLE.md),[DROP TABLE](DROP-TABLE.md),[CREATE TABLESPACE](CREATE-TABLESPACE.md) + +## 优化建议 + +- UNLOGGED + - UNLOGGED表和表上的索引因为数据写入时不通过WAL日志机制,写入速度远高于普通表。因此,可以用于缓冲存储复杂查询的中间结果集,增强复杂查询的性能。 + - UNLOGGED表无主备机制,在系统故障或异常断点等情况下,会有数据丢失风险,因此,不可用来存储基础数据。 + +- TEMPORARY | TEMP + + - 临时表只在当前会话可见,会话结束后会自动删除。 + +- 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子句。默认情况下,不拷贝源表的分区定义。 + + >![](public_sys-resources/icon-notice.png) **须知:** + > + >列表/哈希分区表暂不支持LIKE INCLUDING PARTITION。 + +- LIKE INCLUDING RELOPTIONS + + - 如果指定了INCLUDING RELOPTIONS,则源表的存储参数(即源表的WITH子句)会复制到新表中。默认情况下,不复制源表的存储参数。 + +- LIKE INCLUDING ALL + + - INCLUDING ALL包含了INCLUDING DEFAULTS、INCLUDING CONSTRAINTS、INCLUDING INDEXES、INCLUDING STORAGE、INCLUDING COMMENTS、INCLUDING PARTITION、INCLUDING RELOPTIONS的内容。 + +- ORIENTATION ROW + + - 创建行存表,行存储适合于OLTP业务,此类型的表上交互事务比较多,一次交互会涉及表中的多个列,用行存查询效率较高。 + +- ORIENTATION COLUMN + + - 创建列存表,列存储适合于数据仓库业务,此类型的表上会做大量的汇聚计算,且涉及的列操作较少。 + diff --git a/content/zh/docs/ToolandCommandReference/gs_cgroup.md b/content/zh/docs/ToolandCommandReference/gs_cgroup.md index f402d1c5f1df47bfa93264cc1b7f2ad8b55620af..4c7126cc8f6b920cf2784ecfe6b6453fa3ae3aff 100644 --- a/content/zh/docs/ToolandCommandReference/gs_cgroup.md +++ b/content/zh/docs/ToolandCommandReference/gs_cgroup.md @@ -1,622 +1,624 @@ -# gs\_cgroup - -## 背景信息 - -集群环境下做批量任务处理时,多任务复杂性,会导致不同机器间的负载差距很大。为了充分利用集群资源,负载管理变得尤为重要。gs\_cgroup是openGauss提供的负载管理工具。负责创建默认控制组、创建用户自定义控制组、删除用户自定义控制组、更新用户自定义组的资源配额和资源限额、显示控制组配置文件内容、显示控制组树形结构和删除用户的所有控制组。 - -gs\_cgroup工具为使用数据库的操作系统用户创建Cgroups配置文件,并且在操作系统中生成用户设定的Cgroups。同时为用户提供增加、删除Cgroups、更新Cgroups资源配额、设定Cgroups的CPU或IO限额、设定异常处理阈值及相应操作等服务。此工具只负责当前操作系统节点的Cgroups操作,使用时需在各个节点上调用相同命令语句进行统一配置。 - -这里假设读者已经了解了负载管理的相关原理,具体请参考《性能优化指南》中“资源负载管理”章节。 - -## 使用示例 - -- 使用普通用户或数据库管理员执行命令。 - - 1.前置条件:需设置GAUSSHOME环境变量为数据库安装目录;且root用户已创建普通用户默认的控制组。 - - 2.创建控制组及设置对应的资源配额,以便在数据库中运行作业时,指定到此控制组,使用此控制组管理的资源;通常数据库管理员为每个数据库用户创建Class组。 - a. 创建Class控制组和Workload控制组。 - - ``` - gs_cgroup -c -S class1 -s 40 - ``` - - 创建当前用户新的Class Cgroups命名为“class1”,资源配额为总Class的40%。 - - ``` - gs_cgroup -c -S class1 -G grp1 -g 20 - ``` - - 创建当前用户新的“class1” Cgroups下属的Workload控制组,命名为“grp1”,资源配额为“class1” Cgroups的20%。 - - b. 删除grp1控制组和Class控制组。 - - ``` - gs_cgroup -d -S class1 -G grp1 - ``` - - ​ 删除当前用户已建的“grp1”Cgroups。 - - ``` - gs_cgroup -d -S class1 - ``` - - - ​ 删除当前用户已建的“class1”Cgroups。 - - >![](public_sys-resources/icon-notice.png) **须知:** - >如果删除Class控制组,则Workload控制组也被删除。 - -3.更新已创建控制组的资源配额。 -a. 更新动态资源配额。 - -``` -gs_cgroup -u -S class1 -G grp1 -g 30 -``` - -​ 更新当前用户的class1 Cgroups下属grp1 Cgroups资源配额为class1 Cgroups的30%。 - -b. 更新限制资源配额。 - -``` -gs_cgroup --fixed -u -S class1 -G grp1 -g 30 -``` - - -​ 更新当前用户的class1 Cgroups下属grp1 Cgroups限制使用CPU核数范围占上一级class1可用核数的30%。 - -4.更新Gaussdb的CPU核数范围。 - -``` -gs_cgroup -u -T Gaussdb -f 0-20 -``` - -更新Gaussdb进程使用的CPU核数为0-20。 - ->![](public_sys-resources/icon-note.png) **说明:** ->-f参数只适用于对Gaussdb设置核数范围。对于其他各控制组,如需设置核数范围,需要使用--fixed参数。 - -5.设置异常处理信息(class:wg组需存在)。 -a. 设置组class:wg下的作业阻塞到1200秒或执行2400秒时执行终止动作: - -``` -gs_cgroup -S class -G wg -E "blocktime=1200,elapsedtime=2400" -a -``` - -b. 设置组class:wg下的作业下盘数据量达到256MB或大表广播数据量达到100MB时执行终止动作: - -``` -gs_cgroup -S class -G wg -E "spillsize=256,broadcastsize=100" -a -``` - -c. 设置组Class下的作业在所有数据库节点上CPU总时间到达100s时执行降级动作: - -``` -gs_cgroup -S class -E "allcputime=100" --penalty -``` - -d. 设置组Class下的作业在所有数据库节点上执行时间到达2400秒,倾斜率达到90时执行降级动作: - -``` -gs_cgroup -S class -E "qualificationtime=2400,cpuskewpercent=90" -``` - ->![](public_sys-resources/icon-notice.png) **须知:** ->给控制组设置异常处理信息,需要确保对应的控制组已经创建。指定多个阈值时用“,”分隔,不指定任何动作时默认为“penalty”操作。 - -6.设置控制组使用的核数范围。 - -设置组class:wg的核数范围占Class控制组的20% - -``` -gs_cgroup -S class -G wg -g 20 --fixed -u -``` - ->![](public_sys-resources/icon-notice.png) **须知:** ->Class或Workload核数范围必须通过指定--fixed参数设置。 - -7.回退上一个步骤。 - -``` -gs_cgroup --recover -``` - ->![](public_sys-resources/icon-note.png) **说明:** -> ->--recover只支持对Class控制组和Workload控制组的增删改操作进行回退,且只支持回退一次操作。 - -8.查看已创建的控制组信息。 -a. 查看配置文件中控制组信息。 - -``` -gs_cgroup -p -``` - -控制组配置信息 - -``` -gs_cgroup -p - -Top Group information is listed: -GID: 0 Type: Top Percent(%): 1000( 50) Name: Root Cores: 0-47 -GID: 1 Type: Top Percent(%): 833( 83) Name: Gaussdb:omm Cores: 0-20 -GID: 2 Type: Top Percent(%): 333( 40) Name: Backend Cores: 0-20 -GID: 3 Type: Top Percent(%): 499( 60) Name: Class Cores: 0-20 - -Backend Group information is listed: -GID: 4 Type: BAKWD Name: DefaultBackend TopGID: 2 Percent(%): 266(80) Cores: 0-20 -GID: 5 Type: BAKWD Name: Vacuum TopGID: 2 Percent(%): 66(20) Cores: 0-20 - -Class Group information is listed: -GID: 20 Type: CLASS Name: DefaultClass TopGID: 3 Percent(%): 166(20) MaxLevel: 1 RemPCT: 100 Cores: 0-20 -GID: 21 Type: CLASS Name: class1 TopGID: 3 Percent(%): 332(40) MaxLevel: 2 RemPCT: 70 Cores: 0-20 - -Workload Group information is listed: -GID: 86 Type: DEFWD Name: grp1:2 ClsGID: 21 Percent(%): 99(30) WDLevel: 2 Quota(%): 30 Cores: 0-5 - -Timeshare Group information is listed: -GID: 724 Type: TSWD Name: Low Rate: 1 -GID: 725 Type: TSWD Name: Medium Rate: 2 -GID: 726 Type: TSWD Name: High Rate: 4 -GID: 727 Type: TSWD Name: Rush Rate: 8 - -Group Exception information is listed: -GID: 20 Type: EXCEPTION Class: DefaultClass -PENALTY: QualificationTime=1800 CPUSkewPercent=30 - -GID: 21 Type: EXCEPTION Class: class1 -PENALTY: AllCpuTime=100 QualificationTime=2400 CPUSkewPercent=90 - -GID: 86 Type: EXCEPTION Group: class1:grp1:2 -ABORT: BlockTime=1200 ElapsedTime=2400 -``` - - 上述示例查看到的控制组配置信息如下表所示。 - -**表 1** 控制组配置信息 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

GID

-

类型

-

名称

-

Percent(%)信息

-

特定信息

-

0

-

Top控制组

-

Root

-

1000代表总的系统资源为1000份。

-

括号中的50代表IO资源的50%。

-

openGauss不通过控制组对IO资源做控制,因此下面其他控制组信息中仅涉及CPU配额情况。

-

-

-

1

-

Gaussdb:omm

-

系统中只运行一套数据库程序,Gaussdb:omm控制组默认配额为833,数据库程序和非数据库程序的比值为(833:167=5:1)。

-

-

-

2

-

Backend

-

Backend和Class括号中的40和60,代表Backend占用Gaussdb:dbuser控制组40%的资源,Class占用Gaussdb:dbuser控制组60%的资源。

-

-

-

3

-

Class

-

-

-

4

-

Backend控制组

-

DefaultBackend

-

括号中的80和20代表DefaultBackend和Vacuum占用Backend控制组80%和20%的资源。

-

TopGID:代表Top类型控制组中Backend组的GID,即2。

-

5

-

Vacuum

-

20

-

Class控制组

-

DefaultClass

-

DefaultClass和class1的20和40代表占Class控制组20%和40%的资源。因为当前只有两个Class组,所有它们按照20:40的比例分配Class控制组499的系统配额,则分别为166和332。

-
  • TopGID:代表DefaultClass和class1所属的上层控制(Top控制组中的Class组)的GID,即3。
  • MaxLevel:Class组当前含有的Workload组的最大层次,DefaultClass没有Workload Cgroup,其数值为1。
  • RemPCT:代表Class组分配Workload组后剩余的资源百分比。如class1中剩余的百分比为70。
-

21

-

class1

-

86

-

Workload控制组

-

grp1:2

-

(该名称由Workload Cgroup Name和其在class中的层级组成,它是class1的第一个Workload组,层级为2,每个Class组最多10层Workload Cgroup。)

-

根据设置,其占class1的百分比为30,则为332*30%=99。

-
  • ClsGID:代表Workload控制组所属的上层控制组(class1控制组)的GID。
  • WDLevel:代表当前Workload Cgroup在对应的Class组所在的层次。
-

724

-

Timeshare控制组

-

Low

-

-

-

Rate:代表Timeshare中的分配比例,Low最少为1,Rush最高为8。这四个Timeshare组的资源配比为Rush:High:Medium:Low=8:4:2:1。

-

725

-

Medium

-

-

-

726

-

High

-

-

-

727

-

Rush

-

-

-
- -​ b. 查看操作系统中树形结构的控制组信息 -​ gs\_cgroup -P显示控制组树形结构信息,其中shares代表操作系统中CPU资源的动态资源配额“cpu.shares”的数值,cpus代表操作系统中CPUSET资源的动态资源限额“cpuset.cpus”的数值,指的是该控制组能够使用的核数范围。 - - gs_cgroup -P - Mount Information: - cpu:/dev/cgroup/cpu - blkio:/dev/cgroup/blkio - cpuset:/dev/cgroup/cpuset - cpuacct:/dev/cgroup/cpuacct - - Group Tree Information: - - Gaussdb:wangrui (shares: 5120, cpus: 0-20, weight: 1000) - - Backend (shares: 4096, cpus: 0-20, weight: 400) - - Vacuum (shares: 2048, cpus: 0-20, weight: 200) - - DefaultBackend (shares: 8192, cpus: 0-20, weight: 800) - - Class (shares: 6144, cpus: 0-20, weight: 600) - - class1 (shares: 4096, cpus: 0-20, weight: 400) - - RemainWD:1 (shares: 1000, cpus: 0-20, weight: 100) - - RemainWD:2 (shares: 7000, cpus: 0-20, weight: 700) - - Timeshare (shares: 1024, cpus: 0-20, weight: 500) - - Rush (shares: 8192, cpus: 0-20, weight: 800) - - High (shares: 4096, cpus: 0-20, weight: 400) - - Medium (shares: 2048, cpus: 0-20, weight: 200) - - Low (shares: 1024, cpus: 0-20, weight: 100) - - grp1:2 (shares: 3000, cpus: 0-5, weight: 300) - - TopWD:1 (shares: 9000, cpus: 0-20, weight: 900) - - DefaultClass (shares: 2048, cpus: 0-20, weight: 200) - - RemainWD:1 (shares: 1000, cpus: 0-20, weight: 100) - - Timeshare (shares: 1024, cpus: 0-20, weight: 500) - - Rush (shares: 8192, cpus: 0-20, weight: 800) - - High (shares: 4096, cpus: 0-20, weight: 400) - - Medium (shares: 2048, cpus: 0-20, weight: 200) - - Low (shares: 1024, cpus: 0-20, weight: 100) - - TopWD:1 (shares: 9000, cpus: 0-20, weight: 900) - - - - -## 参数说明 - -- -a \[--abort\] - - 对满足设定的异常阈值的作业执行终止动作。 - -- -b pct - - Backend Cgroups占用Top Backend资源的百分比,需同时指定“-B backendname”参数。 - - 取值范围 - - - 为1 \~ 99。在不进行设置的情况下,默认CPU配额设置为Vacuum控制组占20%,DefaultBackend控制组占80%。Vacuum和DefaultBackend控制组配额之和设置应小于100%。 - -- -B name - - Backend Cgroups名称,仅可指定“-u”参数来更新此Cgroups的资源配额。 - - -b percent和-B backendname参数共同作用来控制数据库后备线程的资源比例。 - - 取值范围:字符串,最长为64个字节。 - -- -c - - 创建Cgroups并指定其标识。 - - 普通用户指定“-c”和“-S classname”可以创建新的Class Cgroups,如果再指定“-G groupname”则创建属于Class Cgroups的Workload Cgroups,新的Workload Cgroups位于Class Cgroups的最底层(4层是最底层)。 - -- -d - - 删除Cgroups及标识。 - - 普通用户指定“-d”和“-S classname”可以删除已有的Class Cgroups,如果再指定“-G groupname”则删除属于Class Cgroups的Workload Cgroups,并将附属的线程重置到“DefaultClass:DefaultWD:1”Cgroups中;若删除的Workload Cgroups位于Class Cgroups的高层(1层是最高层),则需调整低层的Cgroups的层级,重建新的Cgroups附属的线程加载到新的Cgroups。 - -- -E data - - 设定异常阈值,目前阈值包括:blocktime、elapsedtime、allcputime、spillsize、broadcastsize以及qualificationtime和cpuskewpercent,指定多个阈值时用“,”分隔。参数值0表示取消设置,设置不合法的值时会提示。 - - **表 2** 异常阈值类型 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

异常阈值类型

-

说明

-

取值范围(0表示取消设置)

-

支持的异常操作

-

blocktime

-

作业的阻塞时间,单位秒。包括全局并发排队以及局部并发排队的总时间。

-

0~UINT_MAX

-

abort

-

elapsedtime

-

作业的已被执行时间,单位秒。从开始执行到当前所消耗的时间。

-

0~UINT_MAX

-

abort

-

allcputime

-

作业在所有数据库节点上执行时所耗费的CPU总时间,单位秒。

-

0~UINT_MAX

-

abort,penalty

-

cpuskewpercent

-

作业在数据库节点上执行时的CPU时间的倾斜率,依赖于qualificationtime的设置。

-

0~100

-

abort,penalty

-

qualificationtime

-

检查作业执行cpu倾斜率的间隔时间,单位秒,需同cpuskewpercent一起设置。

-

0~UINT_MAX

-

none

-

spillsize

-

作业在数据库节点上下盘的数据量,单位MB。

-

0~UINT_MAX

-

abort

-

broadcastsize

-

作业在数据库节点上算子大表广播数据量,单位MB。

-

0~UINT_MAX

-

abort

-
- -- -h \[--help\] - - 显示命令帮助信息。 - -- -H - - 用户环境中$GAUSSHOME信息。 - - 取值范围:字符串,最长为1023个字符。 - -- -f - - 设置Gaussdb控制组使用的核数范围,范围必须是a-b或a的形式。其他控制组可以使用--fixed进行设置核数范围。 - -- --fixed - - 设置控制组使用的核数范围比例占上一层级的百分比或者设置IO资源。 - - 设置核数范围比例时--fixed设置核数范围与'-s' '-g' '-t' '-b' 一起使用。 - - 核数比例范围0-100,同一层级的核数比例总和小于或者等于100,0代表核数与上一层级相同,对于所有的控制组,CPU限额默认设置为0。-f和--fixed不能同时设置。设置--fixed之后,-f设置的范围自动失效。设置的比例以quota值在-p中进行显示。 - - 设置IO资源配额时,与'-R' '-r' '-W' '-w'一起使用。 - -- -g pct - - 指定Workload Cgroups的资源占用“Class”Cgroups资源的百分比,需同时指定“-G groupname”参数;用于创建“-c”或更新“-u”Workload Cgroups。 - - 取值范围为1 \~ 99。默认Workload控制组CPU配额设置为20%。各Workload控制组配额之和应小于99%。 - -- -G name - - 指定Workload Cgroups的名称,需同时指定“-S classname”参数来表示该group属于哪个Class Cgroups;可以连同“-c”参数创建新的Cgroups、“-d”参数删除此Cgroups及“-u”更新此Cgroups的资源配额;需要注意,此名称不可是Timeshare Cgroups的默认名称,如“Low”、“Medium”、“High”或“Rush”。 - - 如果用户自己创建Workload控制组,指定名称时不能指定带 ':' 的名称。不能创建同名控制组。 - - 取值范围:字符串,最长为28个字节。 - -- -N \[--group\] name - - 可以将组名简写成class:wg。 - -- -p - - 显示Cgroups配置文件的信息。 - -- -P - - 显示Cgroups树形结构信息。 - -- --penalty - - 对满足设定的异常阈值的作业执行降级动作,如果没有设定任何操作,则该操作将为默认操作。 - -- -r data - - 仅用于更新I/O资源读数据上限,用于设置“blkio.throttle.read\_bps\_device”的数值;为字符串类型,该字符串由“major:minor value”构成,其中major为要访问的磁盘的主设备号,minor为要访问的磁盘的次设备号,value为设备每秒读操作次数上限数值,取值范围为0 \~ ULONG\_MAX,其中取值0用来初始化此字段为空;需和“-u”参数及Cgroups名称一同使用;如果Class Cgroups和Workload Cgroups的名称同时指定,则只应用到Workload Cgroups。 - - 取值范围:字符串,最长为32个字符。 - -- -R data - - 仅用于更新IO资源每秒读操作次数上限,用于设置“blkio.throttle.read\_iops\_device”的数值;取值信息同“-r”参数;需和“-u”参数及Cgroups名称一同使用;如果Class Cgroups和Workload Cgroups的名称同时指定,则只应用到Workload Cgroups。 - - 取值范围:字符串,最长为32个字符。 - -- --recover - - 仅用于回退Class控制组和Workload控制组的增删改操作,且只能回退一步。 - -- --revert - - 恢复控制组为默认状态。 - -- -D mpoint - - 指定的挂载点,默认的挂载点“/dev/cgroup/subsystem”。 - -- -m - - 挂载cgroup。 - -- -M - - 取消挂载cgroup。 - -- -U - - 数据库用户名称。 - -- --refresh - - 刷新控制组状态。 - -- -s pct - - 指定Class Cgroups的资源占用“Top Class”Cgroups资源的百分比,需同时指定“-S classname”参数;用于创建“-c”或更新“-u”Class Cgroups。 - - 取值范围为1-99。默认Class控制组的CPU配额设置为20%,R6C10版本中,Class控制组的CPU配额设置为40%,升级过程中,不会对此配额做更新。新创建的Class控制组的CPU配额以及默认的DefaultClass之和应小于100%。 - -- -S name - - 指定Class group的名称;可以连同“-c”参数创建新的Cgroups、“-d”参数删除此Cgroups及“-u”更新此Cgroups的资源配额。创建子Class名称不能带‘:’。 - - 取值范围:字符串,最长为31个字节。 - -- -t percent - - 指定Top Cgroups(Root、Gaussdb:omm、Backend和Class Cgroups)占用资源的百分比,需同时指定“-T name”参数。若指定“-T Root”所在的Cgroups,其在Cgroups配置文件中显示的名称为“Root”,此数值代表的含义是blkio.weight值的百分比,最小值为10%,CPU资源配额如cpu.shares的数值不可修改;若指定“Gaussdb:omm” Cgroups,则表示占用整个系统CPU资源的百分比(可根据Root Cgroups的默认CPU配额1024得出该组的cpu.shares数值,此数值默认当前系统仅含有1套数据库环境),对于IO资源配额为1000,不再变化;若指定“Class”或“Backend”Cgroups,则表示资源占用“Gaussdb”Cgroups资源的百分比。 - - 取值范围为1 \~ 99。默认Class控制组配额为60%, Backend控制组配额为40%。修改Class控制组配额,同时会自动更新Backend控制组配额,使两者之和保持100%。 - -- -T name - - 指定Top Cgroups的名称。 - - 取值范围:字符串,最长为64个字节。 - -- -u - - 更新Cgroups。 - -- -V \[--version\] - - 显示gs\_cgroup工具的版本信息。 - -- -w data - - 仅用于更新I/O资源每秒写数据上限,用于设置“blkio.throttle.write\_bps\_device”的数值。取值信息同“-r”参数,需和“-u”参数及Cgroups名称一同使用。如果Class Cgroups和Workload Cgroups的名称同时指定,则只应用到Workload Cgroups。 - - 取值范围:字符串,最长为32个字符。 - -- -W data - - 仅用于更新IO资源每秒写操作次数上限,用于设置“blkio.throttle.write\_iops\_device”的数值。取值信息同“-r”参数,需和“-u”参数及Cgroups名称一同使用。如果Class Cgroups和Workload Cgroups的名称同时指定,则只应用到Workload Cgroups。 - - 取值范围:字符串,最长为32个字符。 - - ->![](public_sys-resources/icon-note.png) **说明:** -> ->对于磁盘major:minor的编号获取,可以通过下面方式。如获取/mpp目录对应的磁盘编号: ->``` ->> df ->Filesystem 1K-blocks Used Available Use% Mounted on ->/dev/sda1 524173248 41012784 456534008 9% / ->devtmpfs 66059264 236 66059028 1% /dev ->tmpfs 66059264 88 66059176 1% /dev/shm ->/dev/sdb1 2920486864 135987592 2784499272 5% /data ->/dev/sdc1 2920486864 24747868 2895738996 1% /data1 ->/dev/sdd1 2920486864 24736704 2895750160 1% /mpp ->/dev/sde1 2920486864 24750068 2895736796 1% /mpp1 ->> ls -l /dev/sdd ->brw-rw---- 1 root disk 8, 48 Feb 26 11:20 /dev/sdd ->``` - - ->![](public_sys-resources/icon-notice.png) **须知:** ->这里一定要查sdd的磁盘号,不能是sdd1的磁盘号。否则执行时会报错。 ->如果更新IO的限额配置信息超过了可允许的最大配置字串,则新的更新不存储在配置文件中。如当前设置的字串长度为96,更新IO的磁盘数量大于8个,则有可能超出字串限制,更新成功,但是不存储在配置文件中。 - +# gs\_cgroup + +## 背景信息 + +集群环境下做批量任务处理时,多任务复杂性,会导致不同机器间的负载差距很大。为了充分利用集群资源,负载管理变得尤为重要。gs\_cgroup是openGauss提供的负载管理工具。负责创建默认控制组、创建用户自定义控制组、删除用户自定义控制组、更新用户自定义组的资源配额和资源限额、显示控制组配置文件内容、显示控制组树形结构和删除用户的所有控制组。 + +gs\_cgroup工具为使用数据库的操作系统用户创建Cgroups配置文件,并且在操作系统中生成用户设定的Cgroups。同时为用户提供增加、删除Cgroups、更新Cgroups资源配额、设定Cgroups的CPU或IO限额、设定异常处理阈值及相应操作等服务。此工具只负责当前操作系统节点的Cgroups操作,使用时需在各个节点上调用相同命令语句进行统一配置。 + +这里假设读者已经了解了负载管理的相关原理,具体请参考《性能优化指南》中“资源负载管理”章节。 + +注:该特性在金融版本下不支持 + +## 使用示例 + +- 使用普通用户或数据库管理员执行命令。 + + 1.前置条件:需设置GAUSSHOME环境变量为数据库安装目录;且root用户已创建普通用户默认的控制组。 + + 2.创建控制组及设置对应的资源配额,以便在数据库中运行作业时,指定到此控制组,使用此控制组管理的资源;通常数据库管理员为每个数据库用户创建Class组。 + a. 创建Class控制组和Workload控制组。 + + ``` + gs_cgroup -c -S class1 -s 40 + ``` + + 创建当前用户新的Class Cgroups命名为“class1”,资源配额为总Class的40%。 + + ``` + gs_cgroup -c -S class1 -G grp1 -g 20 + ``` + + 创建当前用户新的“class1” Cgroups下属的Workload控制组,命名为“grp1”,资源配额为“class1” Cgroups的20%。 + + b. 删除grp1控制组和Class控制组。 + + ``` + gs_cgroup -d -S class1 -G grp1 + ``` + + ​ 删除当前用户已建的“grp1”Cgroups。 + + ``` + gs_cgroup -d -S class1 + ``` + + + ​ 删除当前用户已建的“class1”Cgroups。 + + >![](public_sys-resources/icon-notice.png) **须知:** + >如果删除Class控制组,则Workload控制组也被删除。 + +3.更新已创建控制组的资源配额。 +a. 更新动态资源配额。 + +``` +gs_cgroup -u -S class1 -G grp1 -g 30 +``` + +​ 更新当前用户的class1 Cgroups下属grp1 Cgroups资源配额为class1 Cgroups的30%。 + +b. 更新限制资源配额。 + +``` +gs_cgroup --fixed -u -S class1 -G grp1 -g 30 +``` + + +​ 更新当前用户的class1 Cgroups下属grp1 Cgroups限制使用CPU核数范围占上一级class1可用核数的30%。 + +4.更新Gaussdb的CPU核数范围。 + +``` +gs_cgroup -u -T Gaussdb -f 0-20 +``` + +更新Gaussdb进程使用的CPU核数为0-20。 + +>![](public_sys-resources/icon-note.png) **说明:** +>-f参数只适用于对Gaussdb设置核数范围。对于其他各控制组,如需设置核数范围,需要使用--fixed参数。 + +5.设置异常处理信息(class:wg组需存在)。 +a. 设置组class:wg下的作业阻塞到1200秒或执行2400秒时执行终止动作: + +``` +gs_cgroup -S class -G wg -E "blocktime=1200,elapsedtime=2400" -a +``` + +b. 设置组class:wg下的作业下盘数据量达到256MB或大表广播数据量达到100MB时执行终止动作: + +``` +gs_cgroup -S class -G wg -E "spillsize=256,broadcastsize=100" -a +``` + +c. 设置组Class下的作业在所有数据库节点上CPU总时间到达100s时执行降级动作: + +``` +gs_cgroup -S class -E "allcputime=100" --penalty +``` + +d. 设置组Class下的作业在所有数据库节点上执行时间到达2400秒,倾斜率达到90时执行降级动作: + +``` +gs_cgroup -S class -E "qualificationtime=2400,cpuskewpercent=90" +``` + +>![](public_sys-resources/icon-notice.png) **须知:** +>给控制组设置异常处理信息,需要确保对应的控制组已经创建。指定多个阈值时用“,”分隔,不指定任何动作时默认为“penalty”操作。 + +6.设置控制组使用的核数范围。 + +设置组class:wg的核数范围占Class控制组的20% + +``` +gs_cgroup -S class -G wg -g 20 --fixed -u +``` + +>![](public_sys-resources/icon-notice.png) **须知:** +>Class或Workload核数范围必须通过指定--fixed参数设置。 + +7.回退上一个步骤。 + +``` +gs_cgroup --recover +``` + +>![](public_sys-resources/icon-note.png) **说明:** +> +>--recover只支持对Class控制组和Workload控制组的增删改操作进行回退,且只支持回退一次操作。 + +8.查看已创建的控制组信息。 +a. 查看配置文件中控制组信息。 + +``` +gs_cgroup -p +``` + +控制组配置信息 + +``` +gs_cgroup -p + +Top Group information is listed: +GID: 0 Type: Top Percent(%): 1000( 50) Name: Root Cores: 0-47 +GID: 1 Type: Top Percent(%): 833( 83) Name: Gaussdb:omm Cores: 0-20 +GID: 2 Type: Top Percent(%): 333( 40) Name: Backend Cores: 0-20 +GID: 3 Type: Top Percent(%): 499( 60) Name: Class Cores: 0-20 + +Backend Group information is listed: +GID: 4 Type: BAKWD Name: DefaultBackend TopGID: 2 Percent(%): 266(80) Cores: 0-20 +GID: 5 Type: BAKWD Name: Vacuum TopGID: 2 Percent(%): 66(20) Cores: 0-20 + +Class Group information is listed: +GID: 20 Type: CLASS Name: DefaultClass TopGID: 3 Percent(%): 166(20) MaxLevel: 1 RemPCT: 100 Cores: 0-20 +GID: 21 Type: CLASS Name: class1 TopGID: 3 Percent(%): 332(40) MaxLevel: 2 RemPCT: 70 Cores: 0-20 + +Workload Group information is listed: +GID: 86 Type: DEFWD Name: grp1:2 ClsGID: 21 Percent(%): 99(30) WDLevel: 2 Quota(%): 30 Cores: 0-5 + +Timeshare Group information is listed: +GID: 724 Type: TSWD Name: Low Rate: 1 +GID: 725 Type: TSWD Name: Medium Rate: 2 +GID: 726 Type: TSWD Name: High Rate: 4 +GID: 727 Type: TSWD Name: Rush Rate: 8 + +Group Exception information is listed: +GID: 20 Type: EXCEPTION Class: DefaultClass +PENALTY: QualificationTime=1800 CPUSkewPercent=30 + +GID: 21 Type: EXCEPTION Class: class1 +PENALTY: AllCpuTime=100 QualificationTime=2400 CPUSkewPercent=90 + +GID: 86 Type: EXCEPTION Group: class1:grp1:2 +ABORT: BlockTime=1200 ElapsedTime=2400 +``` + + 上述示例查看到的控制组配置信息如下表所示。 + +**表 1** 控制组配置信息 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

GID

+

类型

+

名称

+

Percent(%)信息

+

特定信息

+

0

+

Top控制组

+

Root

+

1000代表总的系统资源为1000份。

+

括号中的50代表IO资源的50%。

+

openGauss不通过控制组对IO资源做控制,因此下面其他控制组信息中仅涉及CPU配额情况。

+

-

+

1

+

Gaussdb:omm

+

系统中只运行一套数据库程序,Gaussdb:omm控制组默认配额为833,数据库程序和非数据库程序的比值为(833:167=5:1)。

+

-

+

2

+

Backend

+

Backend和Class括号中的40和60,代表Backend占用Gaussdb:dbuser控制组40%的资源,Class占用Gaussdb:dbuser控制组60%的资源。

+

-

+

3

+

Class

+

-

+

4

+

Backend控制组

+

DefaultBackend

+

括号中的80和20代表DefaultBackend和Vacuum占用Backend控制组80%和20%的资源。

+

TopGID:代表Top类型控制组中Backend组的GID,即2。

+

5

+

Vacuum

+

20

+

Class控制组

+

DefaultClass

+

DefaultClass和class1的20和40代表占Class控制组20%和40%的资源。因为当前只有两个Class组,所有它们按照20:40的比例分配Class控制组499的系统配额,则分别为166和332。

+
  • TopGID:代表DefaultClass和class1所属的上层控制(Top控制组中的Class组)的GID,即3。
  • MaxLevel:Class组当前含有的Workload组的最大层次,DefaultClass没有Workload Cgroup,其数值为1。
  • RemPCT:代表Class组分配Workload组后剩余的资源百分比。如class1中剩余的百分比为70。
+

21

+

class1

+

86

+

Workload控制组

+

grp1:2

+

(该名称由Workload Cgroup Name和其在class中的层级组成,它是class1的第一个Workload组,层级为2,每个Class组最多10层Workload Cgroup。)

+

根据设置,其占class1的百分比为30,则为332*30%=99。

+
  • ClsGID:代表Workload控制组所属的上层控制组(class1控制组)的GID。
  • WDLevel:代表当前Workload Cgroup在对应的Class组所在的层次。
+

724

+

Timeshare控制组

+

Low

+

-

+

Rate:代表Timeshare中的分配比例,Low最少为1,Rush最高为8。这四个Timeshare组的资源配比为Rush:High:Medium:Low=8:4:2:1。

+

725

+

Medium

+

-

+

726

+

High

+

-

+

727

+

Rush

+

-

+
+ +​ b. 查看操作系统中树形结构的控制组信息 +​ gs\_cgroup -P显示控制组树形结构信息,其中shares代表操作系统中CPU资源的动态资源配额“cpu.shares”的数值,cpus代表操作系统中CPUSET资源的动态资源限额“cpuset.cpus”的数值,指的是该控制组能够使用的核数范围。 + + gs_cgroup -P + Mount Information: + cpu:/dev/cgroup/cpu + blkio:/dev/cgroup/blkio + cpuset:/dev/cgroup/cpuset + cpuacct:/dev/cgroup/cpuacct + + Group Tree Information: + - Gaussdb:wangrui (shares: 5120, cpus: 0-20, weight: 1000) + - Backend (shares: 4096, cpus: 0-20, weight: 400) + - Vacuum (shares: 2048, cpus: 0-20, weight: 200) + - DefaultBackend (shares: 8192, cpus: 0-20, weight: 800) + - Class (shares: 6144, cpus: 0-20, weight: 600) + - class1 (shares: 4096, cpus: 0-20, weight: 400) + - RemainWD:1 (shares: 1000, cpus: 0-20, weight: 100) + - RemainWD:2 (shares: 7000, cpus: 0-20, weight: 700) + - Timeshare (shares: 1024, cpus: 0-20, weight: 500) + - Rush (shares: 8192, cpus: 0-20, weight: 800) + - High (shares: 4096, cpus: 0-20, weight: 400) + - Medium (shares: 2048, cpus: 0-20, weight: 200) + - Low (shares: 1024, cpus: 0-20, weight: 100) + - grp1:2 (shares: 3000, cpus: 0-5, weight: 300) + - TopWD:1 (shares: 9000, cpus: 0-20, weight: 900) + - DefaultClass (shares: 2048, cpus: 0-20, weight: 200) + - RemainWD:1 (shares: 1000, cpus: 0-20, weight: 100) + - Timeshare (shares: 1024, cpus: 0-20, weight: 500) + - Rush (shares: 8192, cpus: 0-20, weight: 800) + - High (shares: 4096, cpus: 0-20, weight: 400) + - Medium (shares: 2048, cpus: 0-20, weight: 200) + - Low (shares: 1024, cpus: 0-20, weight: 100) + - TopWD:1 (shares: 9000, cpus: 0-20, weight: 900) + + + + +## 参数说明 + +- -a \[--abort\] + + 对满足设定的异常阈值的作业执行终止动作。 + +- -b pct + + Backend Cgroups占用Top Backend资源的百分比,需同时指定“-B backendname”参数。 + + 取值范围 + + - 为1 \~ 99。在不进行设置的情况下,默认CPU配额设置为Vacuum控制组占20%,DefaultBackend控制组占80%。Vacuum和DefaultBackend控制组配额之和设置应小于100%。 + +- -B name + + Backend Cgroups名称,仅可指定“-u”参数来更新此Cgroups的资源配额。 + + -b percent和-B backendname参数共同作用来控制数据库后备线程的资源比例。 + + 取值范围:字符串,最长为64个字节。 + +- -c + + 创建Cgroups并指定其标识。 + + 普通用户指定“-c”和“-S classname”可以创建新的Class Cgroups,如果再指定“-G groupname”则创建属于Class Cgroups的Workload Cgroups,新的Workload Cgroups位于Class Cgroups的最底层(4层是最底层)。 + +- -d + + 删除Cgroups及标识。 + + 普通用户指定“-d”和“-S classname”可以删除已有的Class Cgroups,如果再指定“-G groupname”则删除属于Class Cgroups的Workload Cgroups,并将附属的线程重置到“DefaultClass:DefaultWD:1”Cgroups中;若删除的Workload Cgroups位于Class Cgroups的高层(1层是最高层),则需调整低层的Cgroups的层级,重建新的Cgroups附属的线程加载到新的Cgroups。 + +- -E data + + 设定异常阈值,目前阈值包括:blocktime、elapsedtime、allcputime、spillsize、broadcastsize以及qualificationtime和cpuskewpercent,指定多个阈值时用“,”分隔。参数值0表示取消设置,设置不合法的值时会提示。 + + **表 2** 异常阈值类型 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

异常阈值类型

+

说明

+

取值范围(0表示取消设置)

+

支持的异常操作

+

blocktime

+

作业的阻塞时间,单位秒。包括全局并发排队以及局部并发排队的总时间。

+

0~UINT_MAX

+

abort

+

elapsedtime

+

作业的已被执行时间,单位秒。从开始执行到当前所消耗的时间。

+

0~UINT_MAX

+

abort

+

allcputime

+

作业在所有数据库节点上执行时所耗费的CPU总时间,单位秒。

+

0~UINT_MAX

+

abort,penalty

+

cpuskewpercent

+

作业在数据库节点上执行时的CPU时间的倾斜率,依赖于qualificationtime的设置。

+

0~100

+

abort,penalty

+

qualificationtime

+

检查作业执行cpu倾斜率的间隔时间,单位秒,需同cpuskewpercent一起设置。

+

0~UINT_MAX

+

none

+

spillsize

+

作业在数据库节点上下盘的数据量,单位MB。

+

0~UINT_MAX

+

abort

+

broadcastsize

+

作业在数据库节点上算子大表广播数据量,单位MB。

+

0~UINT_MAX

+

abort

+
+ +- -h \[--help\] + + 显示命令帮助信息。 + +- -H + + 用户环境中$GAUSSHOME信息。 + + 取值范围:字符串,最长为1023个字符。 + +- -f + + 设置Gaussdb控制组使用的核数范围,范围必须是a-b或a的形式。其他控制组可以使用--fixed进行设置核数范围。 + +- --fixed + + 设置控制组使用的核数范围比例占上一层级的百分比或者设置IO资源。 + + 设置核数范围比例时--fixed设置核数范围与'-s' '-g' '-t' '-b' 一起使用。 + + 核数比例范围0-100,同一层级的核数比例总和小于或者等于100,0代表核数与上一层级相同,对于所有的控制组,CPU限额默认设置为0。-f和--fixed不能同时设置。设置--fixed之后,-f设置的范围自动失效。设置的比例以quota值在-p中进行显示。 + + 设置IO资源配额时,与'-R' '-r' '-W' '-w'一起使用。 + +- -g pct + + 指定Workload Cgroups的资源占用“Class”Cgroups资源的百分比,需同时指定“-G groupname”参数;用于创建“-c”或更新“-u”Workload Cgroups。 + + 取值范围为1 \~ 99。默认Workload控制组CPU配额设置为20%。各Workload控制组配额之和应小于99%。 + +- -G name + + 指定Workload Cgroups的名称,需同时指定“-S classname”参数来表示该group属于哪个Class Cgroups;可以连同“-c”参数创建新的Cgroups、“-d”参数删除此Cgroups及“-u”更新此Cgroups的资源配额;需要注意,此名称不可是Timeshare Cgroups的默认名称,如“Low”、“Medium”、“High”或“Rush”。 + + 如果用户自己创建Workload控制组,指定名称时不能指定带 ':' 的名称。不能创建同名控制组。 + + 取值范围:字符串,最长为28个字节。 + +- -N \[--group\] name + + 可以将组名简写成class:wg。 + +- -p + + 显示Cgroups配置文件的信息。 + +- -P + + 显示Cgroups树形结构信息。 + +- --penalty + + 对满足设定的异常阈值的作业执行降级动作,如果没有设定任何操作,则该操作将为默认操作。 + +- -r data + + 仅用于更新I/O资源读数据上限,用于设置“blkio.throttle.read\_bps\_device”的数值;为字符串类型,该字符串由“major:minor value”构成,其中major为要访问的磁盘的主设备号,minor为要访问的磁盘的次设备号,value为设备每秒读操作次数上限数值,取值范围为0 \~ ULONG\_MAX,其中取值0用来初始化此字段为空;需和“-u”参数及Cgroups名称一同使用;如果Class Cgroups和Workload Cgroups的名称同时指定,则只应用到Workload Cgroups。 + + 取值范围:字符串,最长为32个字符。 + +- -R data + + 仅用于更新IO资源每秒读操作次数上限,用于设置“blkio.throttle.read\_iops\_device”的数值;取值信息同“-r”参数;需和“-u”参数及Cgroups名称一同使用;如果Class Cgroups和Workload Cgroups的名称同时指定,则只应用到Workload Cgroups。 + + 取值范围:字符串,最长为32个字符。 + +- --recover + + 仅用于回退Class控制组和Workload控制组的增删改操作,且只能回退一步。 + +- --revert + + 恢复控制组为默认状态。 + +- -D mpoint + + 指定的挂载点,默认的挂载点“/dev/cgroup/subsystem”。 + +- -m + + 挂载cgroup。 + +- -M + + 取消挂载cgroup。 + +- -U + + 数据库用户名称。 + +- --refresh + + 刷新控制组状态。 + +- -s pct + + 指定Class Cgroups的资源占用“Top Class”Cgroups资源的百分比,需同时指定“-S classname”参数;用于创建“-c”或更新“-u”Class Cgroups。 + + 取值范围为1-99。默认Class控制组的CPU配额设置为20%,R6C10版本中,Class控制组的CPU配额设置为40%,升级过程中,不会对此配额做更新。新创建的Class控制组的CPU配额以及默认的DefaultClass之和应小于100%。 + +- -S name + + 指定Class group的名称;可以连同“-c”参数创建新的Cgroups、“-d”参数删除此Cgroups及“-u”更新此Cgroups的资源配额。创建子Class名称不能带‘:’。 + + 取值范围:字符串,最长为31个字节。 + +- -t percent + + 指定Top Cgroups(Root、Gaussdb:omm、Backend和Class Cgroups)占用资源的百分比,需同时指定“-T name”参数。若指定“-T Root”所在的Cgroups,其在Cgroups配置文件中显示的名称为“Root”,此数值代表的含义是blkio.weight值的百分比,最小值为10%,CPU资源配额如cpu.shares的数值不可修改;若指定“Gaussdb:omm” Cgroups,则表示占用整个系统CPU资源的百分比(可根据Root Cgroups的默认CPU配额1024得出该组的cpu.shares数值,此数值默认当前系统仅含有1套数据库环境),对于IO资源配额为1000,不再变化;若指定“Class”或“Backend”Cgroups,则表示资源占用“Gaussdb”Cgroups资源的百分比。 + + 取值范围为1 \~ 99。默认Class控制组配额为60%, Backend控制组配额为40%。修改Class控制组配额,同时会自动更新Backend控制组配额,使两者之和保持100%。 + +- -T name + + 指定Top Cgroups的名称。 + + 取值范围:字符串,最长为64个字节。 + +- -u + + 更新Cgroups。 + +- -V \[--version\] + + 显示gs\_cgroup工具的版本信息。 + +- -w data + + 仅用于更新I/O资源每秒写数据上限,用于设置“blkio.throttle.write\_bps\_device”的数值。取值信息同“-r”参数,需和“-u”参数及Cgroups名称一同使用。如果Class Cgroups和Workload Cgroups的名称同时指定,则只应用到Workload Cgroups。 + + 取值范围:字符串,最长为32个字符。 + +- -W data + + 仅用于更新IO资源每秒写操作次数上限,用于设置“blkio.throttle.write\_iops\_device”的数值。取值信息同“-r”参数,需和“-u”参数及Cgroups名称一同使用。如果Class Cgroups和Workload Cgroups的名称同时指定,则只应用到Workload Cgroups。 + + 取值范围:字符串,最长为32个字符。 + + +>![](public_sys-resources/icon-note.png) **说明:** +> +>对于磁盘major:minor的编号获取,可以通过下面方式。如获取/mpp目录对应的磁盘编号: +>``` +>> df +>Filesystem 1K-blocks Used Available Use% Mounted on +>/dev/sda1 524173248 41012784 456534008 9% / +>devtmpfs 66059264 236 66059028 1% /dev +>tmpfs 66059264 88 66059176 1% /dev/shm +>/dev/sdb1 2920486864 135987592 2784499272 5% /data +>/dev/sdc1 2920486864 24747868 2895738996 1% /data1 +>/dev/sdd1 2920486864 24736704 2895750160 1% /mpp +>/dev/sde1 2920486864 24750068 2895736796 1% /mpp1 +>> ls -l /dev/sdd +>brw-rw---- 1 root disk 8, 48 Feb 26 11:20 /dev/sdd +>``` + + +>![](public_sys-resources/icon-notice.png) **须知:** +>这里一定要查sdd的磁盘号,不能是sdd1的磁盘号。否则执行时会报错。 +>如果更新IO的限额配置信息超过了可允许的最大配置字串,则新的更新不存储在配置文件中。如当前设置的字串长度为96,更新IO的磁盘数量大于8个,则有可能超出字串限制,更新成功,但是不存储在配置文件中。 + diff --git a/content/zh/docs/ToolandCommandReference/gs_check.md b/content/zh/docs/ToolandCommandReference/gs_check.md index 2e60042571f58fcc57c6435b8bb27b5262eaf888..7c2d1e4e29ebcf53025341d26e8606ed32afea42 100644 --- a/content/zh/docs/ToolandCommandReference/gs_check.md +++ b/content/zh/docs/ToolandCommandReference/gs_check.md @@ -1,1342 +1,1342 @@ -# gs\_check - -## 背景信息 - -gs\_check改进增强,统一化当前系统中存在的各种检查工具,例如[gs\_check](gs_check.md)、[gs\_checkos](gs_checkos.md)等,帮助用户在openGauss运行过程中,全量的检查openGauss运行环境、操作系统环境、网络环境及数据库执行环境,也有助于在openGauss重大操作之前对各类环境进行全面检查,有效保证操作执行成功。 - -## 注意事项 - -- 必须指定-i或-e参数,-i会检查指定的单项,-e会检查对应场景配置中的多项。 -- 如果-i参数中不包含root类检查项或-e场景配置列表中没有root类检查项,则不需要交互输入root权限的用户及其密码。 -- 可使用--skip-root-items跳过检查项中包含的root类检查,以免需要输入root权限用户及密码。 -- MTU值不一致时可能导致检查缓慢或进程停止响应,当巡检工具出现提示时请修改各节点MTU值一致后再进行巡检。 -- 交换机不支持当前设置的MTU值时,即使MTU值一致也会出现通信问题引起进程停止响应,需要根据交换机调整MTU大小。 - -## 语法 - -- 单项检查: - - ``` - gs_check -i ITEM [...] [-U USER] [-L] [-l LOGFILE] [-o OUTPUTDIR] [--skip-root-items][--set][--routing] - ``` - -- 场景检查: - - ``` - gs_check -e SCENE_NAME [-U USER] [-L] [-l LOGFILE] [-o OUTPUTDIR] [--skip-root-items] [--time-out=SECS][--set][--routing][--skip-items] - ``` - -- 显示帮助信息: - - ``` - gs_check -? | --help - ``` - -- 显示版本号信息: - - ``` - gs_check -V | --version - ``` - - -## 参数说明 - -- -U - - 运行openGauss的用户名称。 - - 取值范围:运行openGauss的用户名称。 - -- -L - - 本地执行。 - -- -i - - 指定检查项。格式-i CheckXX详细的检查项请参见[表1 openGauss状态检查表](#zh-cn_topic_0237152330_zh-cn_topic_0059777799_t48caf3ebc47a4dce88ed8b7132976edd)。 - -- -e - - 场景检查项。默认的场景有inspect(例行巡检)、upgrade(升级前巡检)、binary\_upgrade(就地升级前巡检)、health(健康检查巡检)、install(安装)等,用户可以根据需求自己编写场景。 - -- -l - - 指定日志文件路径,指定路径时需添加.log后缀。 - -- -o - - 指定检查结果输出文件夹路径。 - -- --skip-root-items - - 跳过需要root权限执行的检查项。 - -- --skip-items - - 跳过指定的检查项。 - -- --format - - 设置结果报告的格式。 - -- --set - - 修复支持设置的Abnormal项。 - -- --cid - - 检查ID,仅被内部check进程使用。 - -- --time-out - - 设置超时时间。单位为秒,默认为1500s,若用户自定义超时时间不得少于1500s。 - -- --routing - - 指定业务IP的网段,格式为IP地址:子网掩码。 - -- --disk-threshold="PERCENT" - - 检查磁盘占用时可选指定告警阈值,可指定1-99之间的整数,不输入则默认为90。检查其他项时不需要该参数。 - -- -?, --help - - 显示帮助信息。 - -- -V, --version - - 显示版本号信息。 - -**表 1** openGauss状态检查表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

状态

-

巡检项

-

检查内容

-

是否支持--set

-

os

-

CheckCPU(检查CPU使用率)

-

检查主机CPU占用率,如果idle大于30%并且iowait小于30%。则检查项通过,否则检查项不通过。

-

-

CheckFirewall(检查防火墙状态)

-

检查主机防火墙状态,如果防火墙关闭则检查项通过,否则检查项不通过。

-

-

CheckTimeZone(检查时区一致性)

-

检查openGauss内各节点时区,如果时区一致则检查通过,否则检查项不通过。

-

-

CheckSysParams(检查系统参数)

-

检查各节点操作系统参数,判断是否等于预期值。检查项不满足warning域则报warning,不满足NG域则检查项不通过,并打印不满足项。

-

详见操作系统参数

-

-

CheckOSVer(检查操作系统版本)

-

检查openGauss内各个节点的操作系统版本信息,如果满足版本兼容列表且openGauss在同一混搭列表中则检查通过,否则检查不通过。

-

-

CheckNTPD(检查NTPD服务)

-

检查系统NTPD服务,如果服务开启且各节点时间误差在1分钟以内则检查项通过,否则检查项不通过。

-

-

CheckTHP(检查THP服务)

-

检查系统THP服务,如果服务开启则检查项通过,否则检查项不通过。

-

-

CheckSshdService(检查sshd服务是否已启动)

-

检查系统是否存在sshd服务,若存在则检查项通过,否则检查项不通过。

-

-

CheckCrondService(检查crontab服务是否已启动)

-

检查系统是否存在crontab服务,若存在则检查项通过,否则检查项不通过。

-

-

CheckCrontabLeft(检查crontab是否有残留Gauss相关信息)

-

检查crontab是否残留Gauss相关信息,若无该信息则检查项通过,否则检查项不通过。

-

-

CheckDirLeft(检查文件目录是否有残留)

-

检查文件目录(/opt/huawei/Bigdata/ ,/var/log/Bigdata/, /home/omm)是否存在,(若mount目录包含此目录则忽略)若不存在则查项通过,否则检查项不通过。

-

-

CheckProcessLeft(检查进程是否有残留)

-

检查是否残留gaussdb和omm进程,若未残留则检查项通过,否则检查项不通过。

-

-

CheckStack(栈深度检查)

-

检查栈深度,若各个节点不一致则报warning ,若大于等于3072则检查项通过,否则不通过。

-

-

CheckOmmUserExist(检查omm用户是否存在)

-

检查是否存在omm用户,若不存在omm用户则检查项通过,否则检查项不通过。

-

-

CheckPortConflict(检查数据库节点端口是否占用)

-

检查数据库节点端口是否已被占用,若未占用则检查项通过,否则检查项不通过。

-

-

CheckSysPortRange(检查ip_local_port_range设置范围)

-

检查ip_local_port_range系统参数范围,若范围在26000~65535则检查项通过,否则检查项不通过。

-

-

CheckEtcHosts(检查/etc/hosts中是否有重复地址以及localhost配置)

-

检查/etc/hosts没有配置localhost检查项不通过,存在带有#openGauss注释的映射则检查项不通过,相同IP不同hostname则检查项不通过,否则通过,若hostname相同,但ip不同检查项不通过。

-

-

CheckCpuCount(检查CPU核数)

-

检查CPU核心与可用CPU不符检查项不通过,相符但存在不可用信息Warning。 所有节点CPU信息不相同检查项不通过。

-

-

CheckHyperThread(检查超线程是否打开)

-

检查超线程,若打开则检查项通过,否则检查项不通过。

-

-

CheckMemInfo(检查内存总大小)

-

检查各节点总内存大小是否一致,若检查结果一致,则检查项通过,否则报warning。

-

-

CheckSshdConfig(检查sshd服务配置是否正确)

-

检查/etc/ssh/sshd_config文件,

-

(a)PasswordAuthentication=yes;

-

(b)MaxStartups=1000;

-

(c)UseDNS=no;

-

(d)ClientAliveInterval大于10800或者等于0

-

配置如上所示则检查项通过,若a、c配置不正确则报warning,b、d配置不正确则检查项不通过。

-

-

CheckMaxHandle(检查句柄最大设置)

-

检查操作系统最大句柄值,如果该值大于等于1000000则检查项通过,否则检查项不通过。

-

-

CheckKernelVer(检查内核版本)

-

检查各节点系统内核版本信息,如果版本信息一致则检查项通过,否则报Warning。

-

-

CheckEncoding(检查编码格式)

-

检查openGauss内各个节点的系统编码,如果编码一致则检查项通过,否则检查项不通过。

-

-

CheckBootItems(检查启动项)

-

检查是否有手动添加的启动项,如果没有则检查通过,否则检查不通过。

-

-

CheckDropCache(检查DropCache进程)

-

检查各节点是否有dropcache进程在运行,若有则检查通过,否则检查不通过。

-

-

CheckFilehandle(检查文件句柄)

-

此检查项检查以下两项,两项都通过为通过,否则为不通过:

-
  • 检查每个gaussdb进程打开的进程数是否超过80万,不超过则检查通过,否则检查不通过。
  • 检查是否有slave进程使用的句柄数超过master进程,如果没有则检查通过,否则检查不通过。
-

-

CheckKeyProAdj(检查关键进程omm_adj的值)

-

检查所有关键进程,如果所有关键进程的omm_adj值为0,则通过,否则不通过。

-

-

CheckMaxProcMemory(检查max_process_memory参数设置是否合理)

-

检查数据库节点的max_process_memory值,判断该参数的值是否大于1G,若不大于则检查项通过,否则检查项不通过。

-

-

device

-

CheckSwapMemory(检查交换内存)

-

检查交换内存和总内存大小,若检查结果为0则检查项通过,否则检查项报Warning大于总内存时检查项不通过。

-

-

CheckLogicalBlock(检查磁盘逻辑块)

-

检查磁盘逻辑块大小,若为512则检查项通过,否则检查项不通过。

-

-

CheckIOrequestqueue(检查IO请求)

-

检查IO值,如果该值为32768则检查项通过,否则检查项不通过。

-

-

CheckMaxAsyIOrequests(检查最大异步IO请求)

-

获取当前异步IO请求值,当前异步IO请求值大于当前节点数据库实例数*1048576和104857600则检查项通过,否则检查项不通过。

-

-

CheckIOConfigure(检查IO配置)

-

检查IO配置,如果是deadline则检查项通过,否则检查项不通过。

-

-

CheckBlockdev(检查磁盘预读块)

-

检查磁盘预读块大小,如果预读块大小为16384则检查项通过,否则检查项不通过。

-

-

CheckDiskFormat(检查磁盘格式参数)

-

检查磁盘XFS格式信息,如果配置为'rw,noatime,inode64,allocsize=16m'则检查项通过,否则报warning。

-

-

CheckInodeUsage(检查磁盘inodes使用率)

-

openGauss路径(GAUSSHOME/PGHOST/GPHOME/GAUSSLOG/tmp及实例目录)

-

检查以上指定目录使用率,如果使用率超过warning阈值(默认为60%) 报warning超过NG阈值(默认为80%)则检查项不通过,否则通过。

-

-

CheckSpaceUsage(检查磁盘使用率)

-

openGauss路径(GAUSSHOME/PGHOST/GPHOME/GAUSSLOG/tmp及实例目录)

-

检查磁盘以上指定目录(目录列表)使用率,如果使用率超过warning阈值(默认为70%) 报warning超过NG阈值(默认为90%)则检查项不通过。openGauss路径下检查GAUSSHOME/PGHOST/GPHOME/GAUSSLOG/tmp/data路径的剩余空间,不满足阈值则检查项不通过,否则通过。

-

-

CheckDiskConfig(检查磁盘空间大小一致性)

-

检查磁盘名大小挂载点是否一致,若一致则检查项通过,否则报warning。

-

-

CheckXid(检查CheckXid数值)

-

查询xid的数值,如果大于10亿报Warning,大于18亿则检查项不通过。

-

-

CheckSysTabSize(检查每个实例的系统表容量)

-

如果每一块磁盘的剩余容量大于该磁盘上所有实例的系统表容量总和则检查项通过,否则检查项不通过。

-

-

cluster

-

CheckClusterState(检查openGauss状态)

-

检查fencedUDF状态,如果fencedUDF状态为down则报warning;检查openGauss状态,如果openGauss状态为Normal则检查项通过,否则检查项不通过。

-

-

CheckDBParams(检查openGauss参数)

-

检查数据库主节点检查共享缓冲区大小和Sem参数。

-

数据库节点检查共享缓冲区大小和最大连接数。

-

共享缓冲区需要大于128KB且大于shmmax且大于shmall*PAGESIZE

-

若存在数据库主节点,则Sem值需大于(数据库节点最大连接数+150)/16向上取整。

-

以上项完全满足则检查项通过,否则检查项不通过。

-

-

CheckDebugSwitch(检查日志级别)

-

在各节点检查各实例的配置文件中log_min_messages参数的值,为空则认为是Warning,判断日志级别非waring,则报warning。

-

-

CheckUpVer(检查升级版本是否一致)

-

检查openGauss各个节点上升级包的版本,如果一致则检查项通过,否则检查项不通过。使用时,需指定升级软件包路径。

-

-

CheckDirPermissions(检查目录权限)

-

检查节点目录(实例Xlog路径、GAUSSHOME、GPHOME、PGHOST、GAUSSLOG)权限,如果目录有写入权限且不大于750则检查项通过,否则检查项不通过。

-

-

CheckEnvProfile(检查环境变量)

-

检查节点环境变量($GAUSSHOME、$LD_LIBRARY_PATH、$PATH),检查CMS/CMA/数据库节点进程的环境变量。如果环境变量存在并配置正确,进程的环境变量存在则检查项通过,否则检查项不通过。

-

-

CheckGaussVer(检查gaussdb版本)

-

检查各个节点gaussdb版本是否一致,如果版本一致则检查项通过,否则检查项不通过。

-

-

CheckPortRange(检查端口范围)

-

若ip_local_port_range的范围在阈值范围内(默认是26000 65535),并且实例端口不在ip_local_port_range范围内则检查项通过,否则检查项不通过。

-

-

CheckReadonlyMode(检查只读模式)

-

检查openGauss数据库主节点default_transaction_read_only值若为off则检查通过,否则不通过。

-

-

CheckCatchup(检查Catchup)

-

检查gaussdb进程堆栈是否能搜索到CatchupMain函数,若搜索不到则检查项通过,否则检查项不通过。

-

-

CheckProcessStatus(检查openGauss进程属主)

-

检查 'gaussdb'进程属主,若不存在omm以外的属主则检查项通过,否则检查项不通过。

-

-

CheckSpecialFile(特殊文件检查)

-

检查tmp目录(PGHOST)、OM目录(GPHOME)、日志目录(GAUSSLOG)、data目录、程序目录(GAUSSHOME)下文件是否存在特殊字符以及非omm用户的文件,若不存在则检查项通过,否则检查项不通过。

-

-

CheckCollector(检查openGauss的信息收集)

-

在output目录下查看信息收集是否成功,若收集成功则检查项通过,否则检查项不通过。

-

-

CheckLargeFile(检查数据目录大文件)

-

检查各个数据库节点目录是否存在超过4G的文件。任一数据库节点目录及其子目录有超过4G的单个文件,则检查不通过,否则检查通过。

-

-

CheckProStartTime(关键进程启动时间检测)

-

检查关键进程启动时间是否间隔超过5分钟,超过则检查不通过,否则检查通过。

-

-

CheckDilateSysTab(检查系统表膨胀)

-

检查系统表是否膨胀,若膨胀则不通过,否则检查通过。

-

-

CheckMpprcFile(检测环境变量分离文件改动)

-

检查是否存在对环境变量分离文件的改动,若存在则检查不通过,否则检查通过。

-

-

database

-

CheckLockNum(检查锁数量)

-

检查数据库锁数量,查询成功检查项通过。

-

-

CheckArchiveParameter(检查归档参数)

-

检查数据库归档参数,如果未打开或打开且在数据库节点下则检查项通过, 打开且不在数据库主节点目录下则检查项不通过。

-

-

CheckCurConnCount(检查当前连接数)

-

检查数据库连接数,如果连接数小于最大连接数的90%则检查项通过,否则检查项不通过。

-

-

CheckCursorNum(检查当前游标数)

-

检查数据库的游标数,检查成功则检查项通过,否则检查项不通过。

-

-

CheckMaxDatanode(检查comm_max_datanode参数值范围小于数据库节点个数)

-

检查最大数据库节点数,若最大数据库节点数小于xml配置的节点数*数据库节点数(默认值为90*5)报warning,否则检查项通过。

-

-

CheckPgPreparedXacts(检查残留两阶段事务)

-

检查pgxc_prepared_xacts参数,如果不存在二阶段事务则检查项通过,否则检查项不通过。

-

-

CheckPgxcgroup(检查pgxc_group表中需要重分布的个数)

-

检查pgxc_group表中需要重分布的个数,检查结果为0则通过, 否则不通过。

-

-

CheckLockState(openGauss是否被锁)

-

检查openGauss是否被锁,若openGauss被锁则不通过,否则检查项通过。

-

-

CheckIdleSession(检查业务停止)

-

检查非空闲会话数,如果数量为0则检查项通过,否则检查项不通过。

-

-

CheckDBConnection(检查数据库连接)

-

检查能否连接数据库,如果连接成功则检查项通过,否则检查项不通过。

-

-

CheckGUCValue(GUC参数检查)

-

检查(max_connections + max_prepared_transactions) * max_locks_per_transaction的值,若该值大于等于1000000则检查项通过,否则检查项不通过。

-

-

CheckPMKData(检查PMK异常数据)

-

检查数据库PMK schema是否包含有异常数据,如果不存在异常数据则检查项通过,否则检查项不通过。

-

-

CheckSysTable(检查系统表)

-

检查系统表,检查成功则检查项通过。

-

-

CheckSysTabSize(检查每个实例的系统表容量)

-

如果每一块磁盘的剩余容量大于该磁盘上所有实例的系统表容量总和则检查项通过,否则检查项不通过。

-

-

CheckTableSpace(检查表空间路径)

-

表空间路径和openGauss路径之间不能存在嵌套且表空间路径相互不能存在嵌套,则检查项通过,否则检查项不通过。

-

-

CheckTableSkew(检查表级别数据倾斜)

-

若存在表在openGauss各数据库节点上的数据分布不均衡,且分布数据最多的数据库节点比最低的数据库节点所分布的数据多100000条以上,则检查不通过,否则检查通过。

-

-

CheckDNSkew(检查数据库节点级别数据分布倾斜)

-

检查数据库节点级别的表倾斜数据,若分布数据最高的数据库节点比分布数据最低的数据库节点数据量高于5%,则检查不通过,否则检查通过。

-

-

CheckUnAnalyzeTable(检查未做analyze的表)

-

若存在未做analyze的表,并且表中至少包含一条数据,则检查不通过,否则检查通过。

-

-

CheckCreateView(创建视图检查)

-

创建视图时,如果查询语句中含有子查询,并且子查询结果查询解析和重写之后存在别名重复,检查不通过,否则检查通过。

-

-

CheckHashIndex(hash index语法检查)

-

如果存在hash index则检查不通过,否则检查通过。

-

-

CheckNextvalInDefault(检查Default表达式中包含nextval(sequence))

-

检查Default表达式中是否包含nextval(sequence),若包含则不通过,否则通过。

-

-

CheckNodeGroupName(Node group编码格式检查)

-

存在非SQL_ASCII字符的Node Group名称则检查不通过,不存在则检查通过 。

-

-

CheckPgxcRedistb(检查重分布残留的临时表 )

-

检查数据库中是否存在重分布残留的临时表,若不存在则检查通过,否则检查不通过 。

-

-

CheckReturnType(用户自定义函数返回值类型检查)

-

检查用户自定义函数是否包含非法返回类型,若包含则检查不通过,否则检查通过。

-

-

CheckSysadminUser(检查sysadmin用户)

-

检查除openGauss属主外是否存在数据库管理员用户,若存在则不通过,否则检查通过。

-

-

CheckTDDate(TD数据库中orc表date类型列检查)

-

检查TD模式数据库下的orc表中是否包含date类型的列,若包含检查不通过,否则检查通过。

-

-

CheckDropColumn(drop column检查)

-

如果存在drop column的表,则检查不通过,否则检查通过。

-

-

CheckDiskFailure(检查磁盘故障)

-

openGauss中的所有数据做全量查询,若存在查询错误则检查不通过,否则检查通过。

-

-

network

-

CheckPing(检查网络通畅)

-

检查openGauss内所有节点的互通性,如果各节点所有IP均可ping通则检查项通过,否则检查项不通过。

-

-

CheckRXTX(检查网卡RXTX值)

-

检查节点backIP的RX/TX值,如果该值为4096则检查项通过,否则检查项不通过。

-

-

CheckMTU(检查网卡MTU值)

-

检查节点backIP对应的网卡MTU值( bond后的物理网卡要确保一致),如果该值不是8192或1500报warning若openGaussMTU值一致则检查项通过,否则检查项不通过。

-

-

CheckNetWorkDrop(检查网络掉包率)

-

检查各IP1分钟内网络掉包率,如果不超过1%则检查项通过,否则检查项不通过。

-

-

CheckBond(检查网卡绑定模式)

-

检查是否有配置BONDING_OPTS或BONDING_MODULE_OPTS,若没有配置则报warning。检查各节点bond模式是否一致,如果同时满足则检查项通过,否则检查项不通过。

-

-

CheckMultiQueue(检查网卡多队列)

-

检查cat /proc/interrupts,判断是否开启网卡多队列且绑定不同CPU,如果满足则检查项通过,否则检查项不通过。

-

-

CheckUsedPort(检查随机端口使用数量)

-

检查net.ipv4.ip_local_port_range,范围大于等于OS默认值通过(32768-61000);

-

检查TCP协议随机端口数,小于总随机端口数的80%通过。

-

-

CheckNICModel(网卡型号和驱动版本一致性检查)

-

检查各个节点的网卡型号以及驱动版本是否一致,一致则通过,否则报warning。

-

-

CheckRouting(本地路由表检查)

-

检查各节点在业务IP网段的IP个数,超过1个则报warning,否则检查通过。

-

-

CheckNetSpeed(检查网卡接收带宽,ping值,丢包率)

-

网络满载时,检查网卡平均接收带宽大于600MB通过;

-

网络满载时,检查网络ping值,小于1秒通过;

-

网络满载时,检查网卡丢包率,小于1%通过。

-

-

other

-

CheckDataDiskUsage(检查数据库节点磁盘空间使用率)

-

检查磁盘数据库节点目录使用率,如果使用率低于90%则检查项通过,否则检查项不通过。

-

-
- - - - - - - ->![](public_sys-resources/icon-note.png) **说明:** ->CheckNetSpeed检查项: -> ->- CheckNetSpeed不支持-L本地检查模式,-L模式无法构造网络压力,检查的结果不准确。 ->- 在节点数小于6时,speed\_test构造的网络压力可能无法跑满带宽,可能会造成检查结果不准确。 - -## 用户自定义场景 - -1. 以操作系统用户omm登录数据库主节点。 -2. 在script/gspylib/inspection/config路径下新建场景配置文件scene\_XXX.xml。 -3. 将检查项写进场景配置文件中,书写格式为: - - ``` - - - - - - - - - ``` - - item name为检查项名称 - - 注:用户需自行保证自定义xml的正确性 - -4. 在home/package/script/gspylib/inspection/config执行如下命令,将此文件分发至执行检查的各个节点 - - ``` - scp scene_upgrade.xml SIA1000068994:home/package/script/gspylib/inspection/config/ - ``` - - >![](public_sys-resources/icon-note.png) **说明:** - > - >home/package/script/gspylib/inspection/config就是新建的场景配置文件的绝对路径。 - -5. 换至omm用户,执行以下命令查看检查结果。 - - ``` - gs_check -e XXX - ``` - - -## 用户自定义检查项 - -1. 新增巡检项配置,修改script/gspylib/inspection/config/items.xml文件,格式如下: - - ``` - - - <zh>检查CPU占用率</zh> - <en>Check CPU Idle and I/O wait</en> - - - StandardCPUIdle=30; - StandardWIO=30 - - - 如果idle不足 CPU负载过高,请扩容CPU节点,如果iowait过高,则磁盘为瓶颈,更换高性能磁盘 - - - 检查主机CPU占用率,如果idle大于30%并且iowait小于30%,则检查项通过,否则检查项不通过 - - os - user - all - default - - ``` - - - id:巡检项id。 - - name:巡检项脚本名, 和巡检项脚本文件名相同。 - - title: 巡检项描述名称 (支持多语言)。 - - :中文版检查内容。 - - :英文版检查内容。 - - - standard:巡检项标准说明(支持多语言)。 - - suggestion: 巡检项修复建议说明(支持多语言)。 - - threshold:巡检项阈值定义,多值之间使用分号隔开,示例Key1=Value1;Key2=Value2。 - - category: 巡检项分类,可选参数:os,device,network,cluster,database,other。 - - permission: 巡检项需要的执行权限,可选参数:root,user默认为user(普通用户)。 - - scope:巡检项执行的节点范围,可选参数:cn-仅在数据库主节点执行,local-仅在当前节点执行,all-在openGauss所有节点执行,默认为all。 - - analysis:巡检项执行结果分析方式,default-检查每个节点的结果,所有节点检查项通过,则最终检查通过,consistent-openGauss内所有节点一致性检查,单节点仅返回结果,各个节点结果一致则判定检查通过,custom-自定义结果分析方式,默认为default。 - - 注:用户需保证自定义xml的正确性 - -2. 新建检查脚本,脚本名称格式遵循CheckXXXX.py,必须以Check开头,脚本放置在script/gspylib/inspection/items目录下,该目录下脚本安装巡检项分类组织,每个分类一个单独的文件夹,巡检项脚本放置在对应的分类文件夹中。格式如下: - - ``` - class CheckCPU(BaseItem): - def __init__(self): - super(CheckCPU, self).__init__(self.__class__.__name__) - self.idle = None - self.wio = None - self.standard = None - - def preCheck(self): - # check the threshold was set correctly - if (not self.threshold.has_key('StandardCPUIdle') - or not self.threshold.has_key('StandardWIO')): - raise Exception("threshold can not be empty") - self.idle = self.threshold['StandardCPUIdle'] - self.wio = self.threshold['StandardWIO'] - - # format the standard by threshold - self.standard = self.standard.format(idle=self.idle, iowait=self.wio) - - def doCheck(self): - cmd = "sar 1 5 2>&1" - output = SharedFuncs.runShellCmd(cmd) - self.result.raw = output - # check the result with threshold - d = next(n.split() for n in output.splitlines() if "Average" in n) - iowait = d[-3] - idle = d[-1] - rst = ResultStatus.OK - vals = [] - if (iowait > self.wio): - rst = ResultStatus.NG - vals.append("The %s actual value %s is greater than expected value %s" % ("IOWait", iowait, self.wio)) - if (idle < self.idle): - rst = ResultStatus.NG - vals.append("The %s actual value %s is less than expected value %s" % ("Idle", idle, self.idle)) - self.result.rst = rst - if (vals): - self.result.val = "\n".join(vals) - ``` - - 所有脚本基于BaseItem基类开发,基类定义的通用的检查流程,通用的检查结果分析方法,默认的结果输出格式。可扩展方法: - - - doCheck: 该方法包含该检查项具体的检查方法,检查结果格式如下: - - result.rst --- 检查结果状态,可选参数: - - - OK – 检查项完成,结果通过。 - - NA – 当前节点不涉及该检查项。 - - NG – 检查项完成,结果不通过。 - - WARNING – 检查项完成,结果警告。 - - ERROR – 检查项发生内部错误,未完成检查。 - - - preCheck: 检查前条件判定,内置两种实现:cnPreCheck – 用于检查当前执行节点是否包含数据库主节点实例,localPreCheck – 用于检查当前执行节点是否指定节点。可通过巡检项配置文件中的scope参数进行配置。 可重载该方法实现自定义的前置检查 - - postAnalysis:检查结果分析方法,内置两种实现:default、consistent。可通过巡检项配置文件中的analysis参数进行配置。可重载该方法实现自定义的结果分析。 - - 注:用户自定义的检查项名称不得与已有检查项名称相同,同时用户需保证自定义检查项脚本的规范性。 - -3. 将此脚本分发至所有的执行节点。 -4. 以omm用户登录,执行以下命令,查看结果。 - - 本地执行: - - ``` - gs_check -i CheckXXX -L - ``` - - 非本地执行: - - ``` - gs_check -i CheckXXX - ``` - - -## 操作系统参数 - -**表 2** 操作系统参数 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数名称

-

参数说明

-

推荐取值

-

net.ipv4.tcp_max_tw_buckets

-

表示同时保持TIME_WAIT状态的TCP/IP连接最大数量。如果超过所配置的取值,TIME_WAIT将立刻被释放并打印警告信息。

-

10000

-

net.ipv4.tcp_tw_reuse

-

允许将TIME-WAIT状态的sockets重新用于新的TCP连接。

-
  • 0表示关闭。
  • 1表示开启。
-

1

-

net.ipv4.tcp_tw_recycle

-

表示开启TCP连接中TIME-WAIT状态sockets的快速回收。

-
  • 0表示关闭。
  • 1表示开启。
-

1

-

net.ipv4.tcp_keepalive_time

-

表示当keepalive启用的时候,TCP发送keepalive消息的频度。

-

30

-

net.ipv4.tcp_keepalive_probes

-

在认定连接失效之前,发送TCP的keepalive探测包数量。这个值乘以tcp_keepalive_intvl之后决定了一个连接发送了keepalive之后可以有多少时间没有回应。

-

9

-

net.ipv4.tcp_keepalive_intvl

-

当探测没有确认时,重新发送探测的频度。

-

30

-

net.ipv4.tcp_retries1

-

在连接建立过程中TCP协议最大重试次数。

-

5

-

net.ipv4.tcp_syn_retries

-

TCP协议SYN报文最大重试次数。

-

5

-

net.ipv4.tcp_synack_retries

-

TCP协议SYN应答报文最大重试次数。

-

5

-

net.ipv4.tcp_retries2

-

控制内核向已经建立连接的远程主机重新发送数据的次数,低值可以更早的检测到与远程主机失效的连接,因此服务器可以更快的释放该连接。

-

发生“connection reset by peer”时可以尝试调大该值规避问题。

-

12

-

vm.overcommit_memory

-

控制在做内存分配的时候,内核的检查方式。

-
  • 0:表示系统会尽量精确计算当前可用的内存。
  • 1:表示不作检查直接返回成功。
  • 2:内存总量×vm.overcommit_ratio/100+SWAP的总量,如果申请空间超过此数值则返回失败。
-

内核默认是2过于保守,推荐设置为0,如果系统压力大可以设置为1。

-

0

-

net.ipv4.tcp_rmem

-

TCP协议接收端缓冲区的可用内存大小。分无压力、有压力、和压力大三个区间,单位为页面。

-

8192 250000 16777216

-

net.ipv4.tcp_wmem

-

TCP协议发送端缓冲区的可用内存大小。分无压力、有压力、和压力大三个区间,单位为页面。

-

8192 250000 16777216

-

net.core.wmem_max

-

socket发送端缓冲区大小的最大值。

-

21299200

-

net.core.rmem_max

-

socket接收端缓冲区大小的最大值。

-

21299200

-

net.core.wmem_default

-

socket发送端缓冲区大小的默认值。

-

21299200

-

net.core.rmem_default

-

socket接收端缓冲区大小的默认值。

-

21299200

-

net.ipv4.ip_local_port_range

-

物理机可用临时端口范围。

-

26000-65535

-

kernel.sem

-

内核信号量参数设置大小。

-

250 6400000 1000 25600

-

vm.min_free_kbytes

-

保证物理内存有足够空闲空间,防止突发性换页。

-

系统总内存的5%

-

net.core.somaxconn

-

定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数。

-

65535

-

net.ipv4.tcp_syncookies

-

当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击。

-
  • 0表示关闭SYN Cookies。
  • 1表示开启SYN Cookies。
-

1

-

net.core.netdev_max_backlog

-

在每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。

-

65535

-

net.ipv4.tcp_max_syn_backlog

-

记录的那些尚未收到客户端确认信息的连接请求的最大值。

-

65535

-

net.ipv4.tcp_fin_timeout

-

系统默认的超时时间。

-

60

-

kernel.shmall

-

内核可用的共享内存总量。

-

1152921504606846720

-

kernel.shmmax

-

内核参数定义单个共享内存段的最大值。

-

18446744073709551615

-

net.ipv4.tcp_sack

-

启用有选择的应答,通过有选择地应答乱序接受到的报文来提高性能,让发送者只发送丢失的报文段(对于广域网来说)这个选项应该启用,但是会增加对CPU的占用。

-
  • 0表示关闭。
  • 1表示开启。
-

1

-

net.ipv4.tcp_timestamps

-

TCP时间戳(会在TCP包头增加12节),以一种比重发超时更精确的方式(参考RFC 1323)来启用对RTT的计算,启用可以实现更好的性能。

-
  • 0表示关闭。
  • 1表示开启。
-

1

-

vm.extfrag_threshold

-

系统内存不够用时,linux会为当前系统内存碎片情况打分,如果超过vm.extfrag_threshold的值,kswapd就会触发memory compaction。所以这个值设置的接近1000,说明系统在内存碎片的处理倾向于把旧的页换出,以符合申请的需要,而设置接近0,表示系统在内存碎片的处理倾向做memory compaction。

-

500

-

vm.overcommit_ratio

-

系统使用绝不过量使用内存的算法时,系统整个内存地址空间不得超过swap+RAM值的此参数百分比,当vm.overcommit_memory=2时此参数生效。

-

90

-

MTU

-

节点网卡最大传输单元。OS默认值为1500,调整为8192可以提升SCTP协议数据收发的性能。

-

8192

-
- - -## 文件系统参数 - -- soft nofile - - 说明:soft nofile表示软限制,用户使用的文件句柄数量可以超过该限制,但是如果超过会有告警信息。 - - 推荐取值:1000000 - -- hard nofile - - 说明:hard nofile表示硬限制,是一个严格的限制,用户使用的文件句柄数量一定不能超过该设置。 - - 推荐取值:1000000 - -- stack size - - 说明:线程堆栈大小。 - - 推荐值:3072 - - -## 示例 - -执行单项检查结果: - -``` -perfadm@lfgp000700749:/opt/huawei/perfadm/tool/script> gs_check -i CheckCPU -Parsing the check items config file successfully -Distribute the context file to remote hosts successfully -Start to health check for the cluster. Total Items:1 Nodes:3 - -Checking... [=========================] 1/1 -Start to analysis the check result -CheckCPU....................................OK -The item run on 3 nodes. success: 3 - -Success. All check items run completed. Total:1 Success:1 Failed:0 -For more information please refer to /opt/huawei/wisequery/script/gspylib/inspection/output/CheckReport_201902193704661604.tar.gz -``` - -本地执行结果: - -``` -perfadm@lfgp000700749:/opt/huawei/perfadm/tool/script> gs_check -i CheckCPU -L - -2017-12-29 17:09:29 [NAM] CheckCPU -2017-12-29 17:09:29 [STD] 检查主机CPU占用率,如果idle 大于30%并且iowait 小于 30%.则检查项通过,否则检查项不通过 -2017-12-29 17:09:29 [RST] OK - -2017-12-29 17:09:29 [RAW] -Linux 4.4.21-69-default (lfgp000700749) 12/29/17 _x86_64_ - -17:09:24 CPU %user %nice %system %iowait %steal %idle -17:09:25 all 0.25 0.00 0.25 0.00 0.00 99.50 -17:09:26 all 0.25 0.00 0.13 0.00 0.00 99.62 -17:09:27 all 0.25 0.00 0.25 0.13 0.00 99.37 -17:09:28 all 0.38 0.00 0.25 0.00 0.13 99.25 -17:09:29 all 1.00 0.00 0.88 0.00 0.00 98.12 -Average: all 0.43 0.00 0.35 0.03 0.03 99.17 -``` - -执行场景检查结果: - -``` -[perfadm@SIA1000131072 Check]$ gs_check -e inspect -Parsing the check items config file successfully -The below items require root privileges to execute:[CheckBlockdev CheckIOConfigure CheckMTU CheckRXTX CheckMultiQueue CheckFirewall CheckSshdService CheckSshdConfig CheckCrondService CheckMaxProcMemory CheckBootItems CheckFilehandle CheckNICModel CheckDropCache] -Please enter root privileges user[root]: -Please enter password for user[root]: -Check root password connection successfully -Distribute the context file to remote hosts successfully -Start to health check for the cluster. Total Items:57 Nodes:3 -Checking... [=========================] 57/57 -Start to analysis the check result -CheckClusterState...........................OK -The item run on 3 nodes. success: 3 -CheckDBParams...............................OK -......................................................................... -CheckMpprcFile..............................OK -The item run on 3 nodes. success: 3 - -Analysis the check result successfully -Failed. All check items run completed. Total:57 Success:49 Warning:5 NG:3 Error:0 -For more information please refer to /opt/huawei/wisequery/script/gspylib/inspection/output/CheckReport_inspect_201902207129254785.tar.gz -``` - -## 相关命令 - -[gs\_checkos](gs_checkos.md),[gs\_checkperf](gs_checkperf.md) - +# gs\_check + +## 背景信息 + +gs\_check改进增强,统一化当前系统中存在的各种检查工具,例如[gs\_check](gs_check.md)、[gs\_checkos](gs_checkos.md)等,帮助用户在openGauss运行过程中,全量的检查openGauss运行环境、操作系统环境、网络环境及数据库执行环境,也有助于在openGauss重大操作之前对各类环境进行全面检查,有效保证操作执行成功。 + +## 注意事项 + +- 必须指定-i或-e参数,-i会检查指定的单项,-e会检查对应场景配置中的多项。 +- 如果-i参数中不包含root类检查项或-e场景配置列表中没有root类检查项,则不需要交互输入root权限的用户及其密码。 +- 可使用--skip-root-items跳过检查项中包含的root类检查,以免需要输入root权限用户及密码。 +- MTU值不一致时可能导致检查缓慢或进程停止响应,当巡检工具出现提示时请修改各节点MTU值一致后再进行巡检。 +- 交换机不支持当前设置的MTU值时,即使MTU值一致也会出现通信问题引起进程停止响应,需要根据交换机调整MTU大小。 + +## 语法 + +- 单项检查: + + ``` + gs_check -i ITEM [...] [-U USER] [-L] [-l LOGFILE] [-o OUTPUTDIR] [--skip-root-items][--set][--routing] + ``` + +- 场景检查: + + ``` + gs_check -e SCENE_NAME [-U USER] [-L] [-l LOGFILE] [-o OUTPUTDIR] [--skip-root-items] [--time-out=SECS][--set][--routing][--skip-items] + ``` + +- 显示帮助信息: + + ``` + gs_check -? | --help + ``` + +- 显示版本号信息: + + ``` + gs_check -V | --version + ``` + + +## 参数说明 + +- -U + + 运行openGauss的用户名称。 + + 取值范围:运行openGauss的用户名称。 + +- -L + + 本地执行。 + +- -i + + 指定检查项。格式-i CheckXX详细的检查项请参见[表1 openGauss状态检查表](#zh-cn_topic_0237152330_zh-cn_topic_0059777799_t48caf3ebc47a4dce88ed8b7132976edd)。 + +- -e + + 场景检查项。默认的场景有inspect(例行巡检)、upgrade(升级前巡检)、binary\_upgrade(就地升级前巡检)、health(健康检查巡检)、install(安装)等,用户可以根据需求自己编写场景。 + +- -l + + 指定日志文件路径,指定路径时需添加.log后缀。 + +- -o + + 指定检查结果输出文件夹路径。 + +- --skip-root-items + + 跳过需要root权限执行的检查项。 + +- --skip-items + + 跳过指定的检查项。 + +- --format + + 设置结果报告的格式。 + +- --set + + 修复支持设置的Abnormal项。 + +- --cid + + 检查ID,仅被内部check进程使用。 + +- --time-out + + 设置超时时间。单位为秒,默认为1500s,若用户自定义超时时间不得少于1500s。 + +- --routing + + 指定业务IP的网段,格式为IP地址:子网掩码。 + +- --disk-threshold="PERCENT" + + 检查磁盘占用时可选指定告警阈值,可指定1-99之间的整数,不输入则默认为90。检查其他项时不需要该参数。 + +- -?, --help + + 显示帮助信息。 + +- -V, --version + + 显示版本号信息。 + +**表 1** openGauss状态检查表 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

状态

+

巡检项

+

检查内容

+

是否支持--set

+

os

+

CheckCPU(检查CPU使用率)

+

检查主机CPU占用率,如果idle大于30%并且iowait小于30%。则检查项通过,否则检查项不通过。

+

+

CheckFirewall(检查防火墙状态)

+

检查主机防火墙状态,如果防火墙关闭则检查项通过,否则检查项不通过。

+

+

CheckTimeZone(检查时区一致性)

+

检查openGauss内各节点时区,如果时区一致则检查通过,否则检查项不通过。

+

+

CheckSysParams(检查系统参数)

+

检查各节点操作系统参数,判断是否等于预期值。检查项不满足warning域则报warning,不满足NG域则检查项不通过,并打印不满足项。

+

详见操作系统参数

+

+

CheckOSVer(检查操作系统版本)

+

检查openGauss内各个节点的操作系统版本信息,如果满足版本兼容列表且openGauss在同一混搭列表中则检查通过,否则检查不通过。

+

+

CheckNTPD(检查NTPD服务)

+

检查系统NTPD服务,如果服务开启且各节点时间误差在1分钟以内则检查项通过,否则检查项不通过。

+

+

CheckTHP(检查THP服务)

+

检查系统THP服务,如果服务开启则检查项通过,否则检查项不通过。

+

+

CheckSshdService(检查sshd服务是否已启动)

+

检查系统是否存在sshd服务,若存在则检查项通过,否则检查项不通过。

+

+

CheckCrondService(检查crontab服务是否已启动)

+

检查系统是否存在crontab服务,若存在则检查项通过,否则检查项不通过。

+

+

CheckCrontabLeft(检查crontab是否有残留Gauss相关信息)

+

检查crontab是否残留Gauss相关信息,若无该信息则检查项通过,否则检查项不通过。

+

+

CheckDirLeft(检查文件目录是否有残留)

+

检查文件目录(/opt/huawei/Bigdata/ ,/var/log/Bigdata/, /home/omm)是否存在,(若mount目录包含此目录则忽略)若不存在则查项通过,否则检查项不通过。

+

+

CheckProcessLeft(检查进程是否有残留)

+

检查是否残留gaussdb和omm进程,若未残留则检查项通过,否则检查项不通过。

+

+

CheckStack(栈深度检查)

+

检查栈深度,若各个节点不一致则报warning ,若大于等于3072则检查项通过,否则不通过。

+

+

CheckOmmUserExist(检查omm用户是否存在)

+

检查是否存在omm用户,若不存在omm用户则检查项通过,否则检查项不通过。

+

+

CheckPortConflict(检查数据库节点端口是否占用)

+

检查数据库节点端口是否已被占用,若未占用则检查项通过,否则检查项不通过。

+

+

CheckSysPortRange(检查ip_local_port_range设置范围)

+

检查ip_local_port_range系统参数范围,若范围在26000~65535则检查项通过,否则检查项不通过。

+

+

CheckEtcHosts(检查/etc/hosts中是否有重复地址以及localhost配置)

+

检查/etc/hosts没有配置localhost检查项不通过,存在带有#openGauss注释的映射则检查项不通过,相同IP不同hostname则检查项不通过,否则通过,若hostname相同,但ip不同检查项不通过。

+

+

CheckCpuCount(检查CPU核数)

+

检查CPU核心与可用CPU不符检查项不通过,相符但存在不可用信息Warning。 所有节点CPU信息不相同检查项不通过。

+

+

CheckHyperThread(检查超线程是否打开)

+

检查超线程,若打开则检查项通过,否则检查项不通过。

+

+

CheckMemInfo(检查内存总大小)

+

检查各节点总内存大小是否一致,若检查结果一致,则检查项通过,否则报warning。

+

+

CheckSshdConfig(检查sshd服务配置是否正确)

+

检查/etc/ssh/sshd_config文件,

+

(a)PasswordAuthentication=yes;

+

(b)MaxStartups=1000;

+

(c)UseDNS=no;

+

(d)ClientAliveInterval大于10800或者等于0

+

配置如上所示则检查项通过,若a、c配置不正确则报warning,b、d配置不正确则检查项不通过。

+

+

CheckMaxHandle(检查句柄最大设置)

+

检查操作系统最大句柄值,如果该值大于等于1000000则检查项通过,否则检查项不通过。

+

+

CheckKernelVer(检查内核版本)

+

检查各节点系统内核版本信息,如果版本信息一致则检查项通过,否则报Warning。

+

+

CheckEncoding(检查编码格式)

+

检查openGauss内各个节点的系统编码,如果编码一致则检查项通过,否则检查项不通过。

+

+

CheckBootItems(检查启动项)

+

检查是否有手动添加的启动项,如果没有则检查通过,否则检查不通过。

+

+

CheckDropCache(检查DropCache进程)

+

检查各节点是否有dropcache进程在运行,若有则检查通过,否则检查不通过。

+

+

CheckFilehandle(检查文件句柄)

+

此检查项检查以下两项,两项都通过为通过,否则为不通过:

+
  • 检查每个gaussdb进程打开的进程数是否超过80万,不超过则检查通过,否则检查不通过。
  • 检查是否有slave进程使用的句柄数超过master进程,如果没有则检查通过,否则检查不通过。
+

+

CheckKeyProAdj(检查关键进程omm_adj的值)

+

检查所有关键进程,如果所有关键进程的omm_adj值为0,则通过,否则不通过。

+

+

CheckMaxProcMemory(检查max_process_memory参数设置是否合理)

+

检查数据库节点的max_process_memory值,判断该参数的值是否大于1G,若不大于则检查项通过,否则检查项不通过。

+

+

device

+

CheckSwapMemory(检查交换内存)

+

检查交换内存和总内存大小,若检查结果为0则检查项通过,否则检查项报Warning大于总内存时检查项不通过。

+

+

CheckLogicalBlock(检查磁盘逻辑块)

+

检查磁盘逻辑块大小,若为512则检查项通过,否则检查项不通过。

+

+

CheckIOrequestqueue(检查IO请求)

+

检查IO值,如果该值为32768则检查项通过,否则检查项不通过。

+

+

CheckMaxAsyIOrequests(检查最大异步IO请求)

+

获取当前异步IO请求值,当前异步IO请求值大于当前节点数据库实例数*1048576和104857600则检查项通过,否则检查项不通过。

+

+

CheckIOConfigure(检查IO配置)

+

检查IO配置,如果是deadline则检查项通过,否则检查项不通过。

+

+

CheckBlockdev(检查磁盘预读块)

+

检查磁盘预读块大小,如果预读块大小为16384则检查项通过,否则检查项不通过。

+

+

CheckDiskFormat(检查磁盘格式参数)

+

检查磁盘XFS格式信息,如果配置为'rw,noatime,inode64,allocsize=16m'则检查项通过,否则报warning。

+

+

CheckInodeUsage(检查磁盘inodes使用率)

+

openGauss路径(GAUSSHOME/PGHOST/GPHOME/GAUSSLOG/tmp及实例目录)

+

检查以上指定目录使用率,如果使用率超过warning阈值(默认为60%) 报warning超过NG阈值(默认为80%)则检查项不通过,否则通过。

+

+

CheckSpaceUsage(检查磁盘使用率)

+

openGauss路径(GAUSSHOME/PGHOST/GPHOME/GAUSSLOG/tmp及实例目录)

+

检查磁盘以上指定目录(目录列表)使用率,如果使用率超过warning阈值(默认为70%) 报warning超过NG阈值(默认为90%)则检查项不通过。openGauss路径下检查GAUSSHOME/PGHOST/GPHOME/GAUSSLOG/tmp/data路径的剩余空间,不满足阈值则检查项不通过,否则通过。

+

+

CheckDiskConfig(检查磁盘空间大小一致性)

+

检查磁盘名大小挂载点是否一致,若一致则检查项通过,否则报warning。

+

+

CheckXid(检查CheckXid数值)

+

查询xid的数值,如果大于10亿报Warning,大于18亿则检查项不通过。

+

+

CheckSysTabSize(检查每个实例的系统表容量)

+

如果每一块磁盘的剩余容量大于该磁盘上所有实例的系统表容量总和则检查项通过,否则检查项不通过。

+

+

cluster

+

CheckClusterState(检查openGauss状态)

+

检查fencedUDF状态,如果fencedUDF状态为down则报warning;检查openGauss状态,如果openGauss状态为Normal则检查项通过,否则检查项不通过。

+

+

CheckDBParams(检查openGauss参数)

+

检查数据库主节点检查共享缓冲区大小和Sem参数。

+

数据库节点检查共享缓冲区大小和最大连接数。

+

共享缓冲区需要大于128KB且大于shmmax且大于shmall*PAGESIZE

+

若存在数据库主节点,则Sem值需大于(数据库节点最大连接数+150)/16向上取整。

+

以上项完全满足则检查项通过,否则检查项不通过。

+

+

CheckDebugSwitch(检查日志级别)

+

在各节点检查各实例的配置文件中log_min_messages参数的值,为空则认为是Warning,判断日志级别非waring,则报warning。

+

+

CheckUpVer(检查升级版本是否一致)

+

检查openGauss各个节点上升级包的版本,如果一致则检查项通过,否则检查项不通过。使用时,需指定升级软件包路径。

+

+

CheckDirPermissions(检查目录权限)

+

检查节点目录(实例Xlog路径、GAUSSHOME、GPHOME、PGHOST、GAUSSLOG)权限,如果目录有写入权限且不大于750则检查项通过,否则检查项不通过。

+

+

CheckEnvProfile(检查环境变量)

+

检查节点环境变量($GAUSSHOME、$LD_LIBRARY_PATH、$PATH),检查CMS/CMA/数据库节点进程的环境变量。如果环境变量存在并配置正确,进程的环境变量存在则检查项通过,否则检查项不通过。

+

+

CheckGaussVer(检查gaussdb版本)

+

检查各个节点gaussdb版本是否一致,如果版本一致则检查项通过,否则检查项不通过。

+

+

CheckPortRange(检查端口范围)

+

若ip_local_port_range的范围在阈值范围内(默认是26000 65535),并且实例端口不在ip_local_port_range范围内则检查项通过,否则检查项不通过。

+

+

CheckReadonlyMode(检查只读模式)

+

检查openGauss数据库主节点default_transaction_read_only值若为off则检查通过,否则不通过。

+

+

CheckCatchup(检查Catchup)

+

检查gaussdb进程堆栈是否能搜索到CatchupMain函数,若搜索不到则检查项通过,否则检查项不通过。

+

+

CheckProcessStatus(检查openGauss进程属主)

+

检查 'gaussdb'进程属主,若不存在omm以外的属主则检查项通过,否则检查项不通过。

+

+

CheckSpecialFile(特殊文件检查)

+

检查tmp目录(PGHOST)、OM目录(GPHOME)、日志目录(GAUSSLOG)、data目录、程序目录(GAUSSHOME)下文件是否存在特殊字符以及非omm用户的文件,若不存在则检查项通过,否则检查项不通过。

+

+

CheckCollector(检查openGauss的信息收集)

+

在output目录下查看信息收集是否成功,若收集成功则检查项通过,否则检查项不通过。

+

+

CheckLargeFile(检查数据目录大文件)

+

检查各个数据库节点目录是否存在超过4G的文件。任一数据库节点目录及其子目录有超过4G的单个文件,则检查不通过,否则检查通过。

+

+

CheckProStartTime(关键进程启动时间检测)

+

检查关键进程启动时间是否间隔超过5分钟,超过则检查不通过,否则检查通过。

+

+

CheckDilateSysTab(检查系统表膨胀)

+

检查系统表是否膨胀,若膨胀则不通过,否则检查通过。

+

+

CheckMpprcFile(检测环境变量分离文件改动)

+

检查是否存在对环境变量分离文件的改动,若存在则检查不通过,否则检查通过。

+

+

database

+

CheckLockNum(检查锁数量)

+

检查数据库锁数量,查询成功检查项通过。

+

+

CheckArchiveParameter(检查归档参数)

+

检查数据库归档参数,如果未打开或打开且在数据库节点下则检查项通过, 打开且不在数据库主节点目录下则检查项不通过。

+

+

CheckCurConnCount(检查当前连接数)

+

检查数据库连接数,如果连接数小于最大连接数的90%则检查项通过,否则检查项不通过。

+

+

CheckCursorNum(检查当前游标数)

+

检查数据库的游标数,检查成功则检查项通过,否则检查项不通过。

+

+

CheckMaxDatanode(检查comm_max_datanode参数值范围小于数据库节点个数)

+

检查最大数据库节点数,若最大数据库节点数小于xml配置的节点数*数据库节点数(默认值为90*5)报warning,否则检查项通过。

+

+

CheckPgPreparedXacts(检查残留两阶段事务)

+

检查pgxc_prepared_xacts参数,如果不存在二阶段事务则检查项通过,否则检查项不通过。

+

+

CheckPgxcgroup(检查pgxc_group表中需要重分布的个数)

+

检查pgxc_group表中需要重分布的个数,检查结果为0则通过, 否则不通过。

+

+

CheckLockState(openGauss是否被锁)

+

检查openGauss是否被锁,若openGauss被锁则不通过,否则检查项通过。

+

+

CheckIdleSession(检查业务停止)

+

检查非空闲会话数,如果数量为0则检查项通过,否则检查项不通过。

+

+

CheckDBConnection(检查数据库连接)

+

检查能否连接数据库,如果连接成功则检查项通过,否则检查项不通过。

+

+

CheckGUCValue(GUC参数检查)

+

检查(max_connections + max_prepared_transactions) * max_locks_per_transaction的值,若该值大于等于1000000则检查项通过,否则检查项不通过。

+

+

CheckPMKData(检查PMK异常数据)

+

检查数据库PMK schema是否包含有异常数据,如果不存在异常数据则检查项通过,否则检查项不通过。

+

+

CheckSysTable(检查系统表)

+

检查系统表,检查成功则检查项通过。

+

+

CheckSysTabSize(检查每个实例的系统表容量)

+

如果每一块磁盘的剩余容量大于该磁盘上所有实例的系统表容量总和则检查项通过,否则检查项不通过。

+

+

CheckTableSpace(检查表空间路径)

+

表空间路径和openGauss路径之间不能存在嵌套且表空间路径相互不能存在嵌套,则检查项通过,否则检查项不通过。

+

+

CheckTableSkew(检查表级别数据倾斜)

+

若存在表在openGauss各数据库节点上的数据分布不均衡,且分布数据最多的数据库节点比最低的数据库节点所分布的数据多100000条以上,则检查不通过,否则检查通过。

+

+

CheckDNSkew(检查数据库节点级别数据分布倾斜)

+

检查数据库节点级别的表倾斜数据,若分布数据最高的数据库节点比分布数据最低的数据库节点数据量高于5%,则检查不通过,否则检查通过。

+

+

CheckUnAnalyzeTable(检查未做analyze的表)

+

若存在未做analyze的表,并且表中至少包含一条数据,则检查不通过,否则检查通过。

+

+

CheckCreateView(创建视图检查)

+

创建视图时,如果查询语句中含有子查询,并且子查询结果查询解析和重写之后存在别名重复,检查不通过,否则检查通过。

+

+

CheckHashIndex(hash index语法检查)

+

如果存在hash index则检查不通过,否则检查通过。

+

+

CheckNextvalInDefault(检查Default表达式中包含nextval(sequence))

+

检查Default表达式中是否包含nextval(sequence),若包含则不通过,否则通过。

+

+

CheckNodeGroupName(Node group编码格式检查)

+

存在非SQL_ASCII字符的Node Group名称则检查不通过,不存在则检查通过 。

+

+

CheckPgxcRedistb(检查重分布残留的临时表 )

+

检查数据库中是否存在重分布残留的临时表,若不存在则检查通过,否则检查不通过 。

+

+

CheckReturnType(用户自定义函数返回值类型检查)

+

检查用户自定义函数是否包含非法返回类型,若包含则检查不通过,否则检查通过。

+

+

CheckSysadminUser(检查sysadmin用户)

+

检查除openGauss属主外是否存在数据库管理员用户,若存在则不通过,否则检查通过。

+

+

CheckTDDate(TD数据库中orc表date类型列检查)

+

检查TD模式数据库下的orc表中是否包含date类型的列,若包含检查不通过,否则检查通过。

+

+

CheckDropColumn(drop column检查)

+

如果存在drop column的表,则检查不通过,否则检查通过。

+

+

CheckDiskFailure(检查磁盘故障)

+

openGauss中的所有数据做全量查询,若存在查询错误则检查不通过,否则检查通过。

+

+

network

+

CheckPing(检查网络通畅)

+

检查openGauss内所有节点的互通性,如果各节点所有IP均可ping通则检查项通过,否则检查项不通过。

+

+

CheckRXTX(检查网卡RXTX值)

+

检查节点backIP的RX/TX值,如果该值为4096则检查项通过,否则检查项不通过。

+

+

CheckMTU(检查网卡MTU值)

+

检查节点backIP对应的网卡MTU值( bond后的物理网卡要确保一致),如果该值不是8192或1500报warning若openGaussMTU值一致则检查项通过,否则检查项不通过。

+

+

CheckNetWorkDrop(检查网络掉包率)

+

检查各IP1分钟内网络掉包率,如果不超过1%则检查项通过,否则检查项不通过。

+

+

CheckBond(检查网卡绑定模式)

+

检查是否有配置BONDING_OPTS或BONDING_MODULE_OPTS或者DEVICE,若没有配置则报warning。检查各节点bond模式是否一致,如果同时满足则检查项通过,否则检查项不通过。

+

+

CheckMultiQueue(检查网卡多队列)

+

检查cat /proc/interrupts,判断是否开启网卡多队列且绑定不同CPU,如果满足则检查项通过,否则检查项不通过。

+

+

CheckUsedPort(检查随机端口使用数量)

+

检查net.ipv4.ip_local_port_range,范围大于等于OS默认值通过(32768-61000);

+

检查TCP协议随机端口数,小于总随机端口数的80%通过。

+

+

CheckNICModel(网卡型号和驱动版本一致性检查)

+

检查各个节点的网卡型号以及驱动版本是否一致,一致则通过,否则报warning。

+

+

CheckRouting(本地路由表检查)

+

检查各节点在业务IP网段的IP个数,超过1个则报warning,否则检查通过。

+

+

CheckNetSpeed(检查网卡接收带宽,ping值,丢包率)

+

网络满载时,检查网卡平均接收带宽大于600MB通过;

+

网络满载时,检查网络ping值,小于1秒通过;

+

网络满载时,检查网卡丢包率,小于1%通过。

+

+

other

+

CheckDataDiskUsage(检查数据库节点磁盘空间使用率)

+

检查磁盘数据库节点目录使用率,如果使用率低于90%则检查项通过,否则检查项不通过。

+

+
+ + + + + + + +>![](public_sys-resources/icon-note.png) **说明:** +>CheckNetSpeed检查项: +> +>- CheckNetSpeed不支持-L本地检查模式,-L模式无法构造网络压力,检查的结果不准确。 +>- 在节点数小于6时,speed\_test构造的网络压力可能无法跑满带宽,可能会造成检查结果不准确。 + +## 用户自定义场景 + +1. 以操作系统用户omm登录数据库主节点。 +2. 在script/gspylib/inspection/config路径下新建场景配置文件scene\_XXX.xml。 +3. 将检查项写进场景配置文件中,书写格式为: + + ``` + + + + + + + + + ``` + + item name为检查项名称 + + 注:用户需自行保证自定义xml的正确性 + +4. 在home/package/script/gspylib/inspection/config执行如下命令,将此文件分发至执行检查的各个节点 + + ``` + scp scene_upgrade.xml SIA1000068994:home/package/script/gspylib/inspection/config/ + ``` + + >![](public_sys-resources/icon-note.png) **说明:** + > + >home/package/script/gspylib/inspection/config就是新建的场景配置文件的绝对路径。 + +5. 换至omm用户,执行以下命令查看检查结果。 + + ``` + gs_check -e XXX + ``` + + +## 用户自定义检查项 + +1. 新增巡检项配置,修改script/gspylib/inspection/config/items.xml文件,格式如下: + + ``` + + + <zh>检查CPU占用率</zh> + <en>Check CPU Idle and I/O wait</en> + + + StandardCPUIdle=30; + StandardWIO=30 + + + 如果idle不足 CPU负载过高,请扩容CPU节点,如果iowait过高,则磁盘为瓶颈,更换高性能磁盘 + + + 检查主机CPU占用率,如果idle大于30%并且iowait小于30%,则检查项通过,否则检查项不通过 + + os + user + all + default + + ``` + + - id:巡检项id。 + - name:巡检项脚本名, 和巡检项脚本文件名相同。 + - title: 巡检项描述名称 (支持多语言)。 + + :中文版检查内容。 + + :英文版检查内容。 + + - standard:巡检项标准说明(支持多语言)。 + - suggestion: 巡检项修复建议说明(支持多语言)。 + - threshold:巡检项阈值定义,多值之间使用分号隔开,示例Key1=Value1;Key2=Value2。 + - category: 巡检项分类,可选参数:os,device,network,cluster,database,other。 + - permission: 巡检项需要的执行权限,可选参数:root,user默认为user(普通用户)。 + - scope:巡检项执行的节点范围,可选参数:cn-仅在数据库主节点执行,local-仅在当前节点执行,all-在openGauss所有节点执行,默认为all。 + - analysis:巡检项执行结果分析方式,default-检查每个节点的结果,所有节点检查项通过,则最终检查通过,consistent-openGauss内所有节点一致性检查,单节点仅返回结果,各个节点结果一致则判定检查通过,custom-自定义结果分析方式,默认为default。 + + 注:用户需保证自定义xml的正确性 + +2. 新建检查脚本,脚本名称格式遵循CheckXXXX.py,必须以Check开头,脚本放置在script/gspylib/inspection/items目录下,该目录下脚本安装巡检项分类组织,每个分类一个单独的文件夹,巡检项脚本放置在对应的分类文件夹中。格式如下: + + ``` + class CheckCPU(BaseItem): + def __init__(self): + super(CheckCPU, self).__init__(self.__class__.__name__) + self.idle = None + self.wio = None + self.standard = None + + def preCheck(self): + # check the threshold was set correctly + if (not self.threshold.has_key('StandardCPUIdle') + or not self.threshold.has_key('StandardWIO')): + raise Exception("threshold can not be empty") + self.idle = self.threshold['StandardCPUIdle'] + self.wio = self.threshold['StandardWIO'] + + # format the standard by threshold + self.standard = self.standard.format(idle=self.idle, iowait=self.wio) + + def doCheck(self): + cmd = "sar 1 5 2>&1" + output = SharedFuncs.runShellCmd(cmd) + self.result.raw = output + # check the result with threshold + d = next(n.split() for n in output.splitlines() if "Average" in n) + iowait = d[-3] + idle = d[-1] + rst = ResultStatus.OK + vals = [] + if (iowait > self.wio): + rst = ResultStatus.NG + vals.append("The %s actual value %s is greater than expected value %s" % ("IOWait", iowait, self.wio)) + if (idle < self.idle): + rst = ResultStatus.NG + vals.append("The %s actual value %s is less than expected value %s" % ("Idle", idle, self.idle)) + self.result.rst = rst + if (vals): + self.result.val = "\n".join(vals) + ``` + + 所有脚本基于BaseItem基类开发,基类定义的通用的检查流程,通用的检查结果分析方法,默认的结果输出格式。可扩展方法: + + - doCheck: 该方法包含该检查项具体的检查方法,检查结果格式如下: + + result.rst --- 检查结果状态,可选参数: + + - OK – 检查项完成,结果通过。 + - NA – 当前节点不涉及该检查项。 + - NG – 检查项完成,结果不通过。 + - WARNING – 检查项完成,结果警告。 + - ERROR – 检查项发生内部错误,未完成检查。 + + - preCheck: 检查前条件判定,内置两种实现:cnPreCheck – 用于检查当前执行节点是否包含数据库主节点实例,localPreCheck – 用于检查当前执行节点是否指定节点。可通过巡检项配置文件中的scope参数进行配置。 可重载该方法实现自定义的前置检查 + - postAnalysis:检查结果分析方法,内置两种实现:default、consistent。可通过巡检项配置文件中的analysis参数进行配置。可重载该方法实现自定义的结果分析。 + + 注:用户自定义的检查项名称不得与已有检查项名称相同,同时用户需保证自定义检查项脚本的规范性。 + +3. 将此脚本分发至所有的执行节点。 +4. 以omm用户登录,执行以下命令,查看结果。 + + 本地执行: + + ``` + gs_check -i CheckXXX -L + ``` + + 非本地执行: + + ``` + gs_check -i CheckXXX + ``` + + +## 操作系统参数 + +**表 2** 操作系统参数 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

参数名称

+

参数说明

+

推荐取值

+

net.ipv4.tcp_max_tw_buckets

+

表示同时保持TIME_WAIT状态的TCP/IP连接最大数量。如果超过所配置的取值,TIME_WAIT将立刻被释放并打印警告信息。

+

10000

+

net.ipv4.tcp_tw_reuse

+

允许将TIME-WAIT状态的sockets重新用于新的TCP连接。

+
  • 0表示关闭。
  • 1表示开启。
+

1

+

net.ipv4.tcp_tw_recycle

+

表示开启TCP连接中TIME-WAIT状态sockets的快速回收。

+
  • 0表示关闭。
  • 1表示开启。
+

1

+

net.ipv4.tcp_keepalive_time

+

表示当keepalive启用的时候,TCP发送keepalive消息的频度。

+

30

+

net.ipv4.tcp_keepalive_probes

+

在认定连接失效之前,发送TCP的keepalive探测包数量。这个值乘以tcp_keepalive_intvl之后决定了一个连接发送了keepalive之后可以有多少时间没有回应。

+

9

+

net.ipv4.tcp_keepalive_intvl

+

当探测没有确认时,重新发送探测的频度。

+

30

+

net.ipv4.tcp_retries1

+

在连接建立过程中TCP协议最大重试次数。

+

5

+

net.ipv4.tcp_syn_retries

+

TCP协议SYN报文最大重试次数。

+

5

+

net.ipv4.tcp_synack_retries

+

TCP协议SYN应答报文最大重试次数。

+

5

+

net.ipv4.tcp_retries2

+

控制内核向已经建立连接的远程主机重新发送数据的次数,低值可以更早的检测到与远程主机失效的连接,因此服务器可以更快的释放该连接。

+

发生“connection reset by peer”时可以尝试调大该值规避问题。

+

12

+

vm.overcommit_memory

+

控制在做内存分配的时候,内核的检查方式。

+
  • 0:表示系统会尽量精确计算当前可用的内存。
  • 1:表示不作检查直接返回成功。
  • 2:内存总量×vm.overcommit_ratio/100+SWAP的总量,如果申请空间超过此数值则返回失败。
+

内核默认是2过于保守,推荐设置为0,如果系统压力大可以设置为1。

+

0

+

net.ipv4.tcp_rmem

+

TCP协议接收端缓冲区的可用内存大小。分无压力、有压力、和压力大三个区间,单位为页面。

+

8192 250000 16777216

+

net.ipv4.tcp_wmem

+

TCP协议发送端缓冲区的可用内存大小。分无压力、有压力、和压力大三个区间,单位为页面。

+

8192 250000 16777216

+

net.core.wmem_max

+

socket发送端缓冲区大小的最大值。

+

21299200

+

net.core.rmem_max

+

socket接收端缓冲区大小的最大值。

+

21299200

+

net.core.wmem_default

+

socket发送端缓冲区大小的默认值。

+

21299200

+

net.core.rmem_default

+

socket接收端缓冲区大小的默认值。

+

21299200

+

net.ipv4.ip_local_port_range

+

物理机可用临时端口范围。

+

26000-65535

+

kernel.sem

+

内核信号量参数设置大小。

+

250 6400000 1000 25600

+

vm.min_free_kbytes

+

保证物理内存有足够空闲空间,防止突发性换页。

+

系统总内存的5%

+

net.core.somaxconn

+

定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数。

+

65535

+

net.ipv4.tcp_syncookies

+

当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击。

+
  • 0表示关闭SYN Cookies。
  • 1表示开启SYN Cookies。
+

1

+

net.core.netdev_max_backlog

+

在每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。

+

65535

+

net.ipv4.tcp_max_syn_backlog

+

记录的那些尚未收到客户端确认信息的连接请求的最大值。

+

65535

+

net.ipv4.tcp_fin_timeout

+

系统默认的超时时间。

+

60

+

kernel.shmall

+

内核可用的共享内存总量。

+

1152921504606846720

+

kernel.shmmax

+

内核参数定义单个共享内存段的最大值。

+

18446744073709551615

+

net.ipv4.tcp_sack

+

启用有选择的应答,通过有选择地应答乱序接受到的报文来提高性能,让发送者只发送丢失的报文段(对于广域网来说)这个选项应该启用,但是会增加对CPU的占用。

+
  • 0表示关闭。
  • 1表示开启。
+

1

+

net.ipv4.tcp_timestamps

+

TCP时间戳(会在TCP包头增加12节),以一种比重发超时更精确的方式(参考RFC 1323)来启用对RTT的计算,启用可以实现更好的性能。

+
  • 0表示关闭。
  • 1表示开启。
+

1

+

vm.extfrag_threshold

+

系统内存不够用时,linux会为当前系统内存碎片情况打分,如果超过vm.extfrag_threshold的值,kswapd就会触发memory compaction。所以这个值设置的接近1000,说明系统在内存碎片的处理倾向于把旧的页换出,以符合申请的需要,而设置接近0,表示系统在内存碎片的处理倾向做memory compaction。

+

500

+

vm.overcommit_ratio

+

系统使用绝不过量使用内存的算法时,系统整个内存地址空间不得超过swap+RAM值的此参数百分比,当vm.overcommit_memory=2时此参数生效。

+

90

+

MTU

+

节点网卡最大传输单元。OS默认值为1500,调整为8192可以提升SCTP协议数据收发的性能。

+

8192

+
+ + +## 文件系统参数 + +- soft nofile + + 说明:soft nofile表示软限制,用户使用的文件句柄数量可以超过该限制,但是如果超过会有告警信息。 + + 推荐取值:1000000 + +- hard nofile + + 说明:hard nofile表示硬限制,是一个严格的限制,用户使用的文件句柄数量一定不能超过该设置。 + + 推荐取值:1000000 + +- stack size + + 说明:线程堆栈大小。 + + 推荐值:3072 + + +## 示例 + +执行单项检查结果: + +``` +perfadm@lfgp000700749:/opt/huawei/perfadm/tool/script> gs_check -i CheckCPU +Parsing the check items config file successfully +Distribute the context file to remote hosts successfully +Start to health check for the cluster. Total Items:1 Nodes:3 + +Checking... [=========================] 1/1 +Start to analysis the check result +CheckCPU....................................OK +The item run on 3 nodes. success: 3 + +Success. All check items run completed. Total:1 Success:1 Failed:0 +For more information please refer to /opt/huawei/wisequery/script/gspylib/inspection/output/CheckReport_201902193704661604.tar.gz +``` + +本地执行结果: + +``` +perfadm@lfgp000700749:/opt/huawei/perfadm/tool/script> gs_check -i CheckCPU -L + +2017-12-29 17:09:29 [NAM] CheckCPU +2017-12-29 17:09:29 [STD] 检查主机CPU占用率,如果idle 大于30%并且iowait 小于 30%.则检查项通过,否则检查项不通过 +2017-12-29 17:09:29 [RST] OK + +2017-12-29 17:09:29 [RAW] +Linux 4.4.21-69-default (lfgp000700749) 12/29/17 _x86_64_ + +17:09:24 CPU %user %nice %system %iowait %steal %idle +17:09:25 all 0.25 0.00 0.25 0.00 0.00 99.50 +17:09:26 all 0.25 0.00 0.13 0.00 0.00 99.62 +17:09:27 all 0.25 0.00 0.25 0.13 0.00 99.37 +17:09:28 all 0.38 0.00 0.25 0.00 0.13 99.25 +17:09:29 all 1.00 0.00 0.88 0.00 0.00 98.12 +Average: all 0.43 0.00 0.35 0.03 0.03 99.17 +``` + +执行场景检查结果: + +``` +[perfadm@SIA1000131072 Check]$ gs_check -e inspect +Parsing the check items config file successfully +The below items require root privileges to execute:[CheckBlockdev CheckIOConfigure CheckMTU CheckRXTX CheckMultiQueue CheckFirewall CheckSshdService CheckSshdConfig CheckCrondService CheckMaxProcMemory CheckBootItems CheckFilehandle CheckNICModel CheckDropCache] +Please enter root privileges user[root]: +Please enter password for user[root]: +Check root password connection successfully +Distribute the context file to remote hosts successfully +Start to health check for the cluster. Total Items:57 Nodes:3 +Checking... [=========================] 57/57 +Start to analysis the check result +CheckClusterState...........................OK +The item run on 3 nodes. success: 3 +CheckDBParams...............................OK +......................................................................... +CheckMpprcFile..............................OK +The item run on 3 nodes. success: 3 + +Analysis the check result successfully +Failed. All check items run completed. Total:57 Success:49 Warning:5 NG:3 Error:0 +For more information please refer to /opt/huawei/wisequery/script/gspylib/inspection/output/CheckReport_inspect_201902207129254785.tar.gz +``` + +## 相关命令 + +[gs\_checkos](gs_checkos.md),[gs\_checkperf](gs_checkperf.md) +