华为云用户手册

  • string_hash_compatible 参数说明:该参数用来说明char类型和varchar/text类型的hash值计算方式是否相同,以此来判断进行分布列从char类型到相同值的varchar/text类型转换,数据分布变化时,是否需要进行重分布。 该参数属于POSTMASTER类型参数,请参考表1中对应设置方法进行设置。 取值范围:布尔型 on表示计算方式相同,不需要进行重分布。 off表示计算方式不同,需要进行重分布。 计算方式的不同主要体现在字符串计算hash值时传入的字节长度上。(如果为char,则会忽略字符串后面空格的长度,如果为text或varchar,则会保留字符串后面空格的长度。)hash值的计算会影响到查询的计算结果,因此此参数一旦设置后,在整个数据库使用过程中不能再对其进行修改,以避免查询错误。 默认值:off
  • zero_damaged_pages 参数说明:控制检测导致 GaussDB 报告错误的损坏的页头,终止当前事务。 该参数属于SUSET类型参数,请参考表1中对应设置方法进行设置。 取值范围:布尔型 设置为on时,会导致系统报告一个警告,把损坏的页面填充为零然后继续处理。这种行为会破坏数据,也就是所有在已经损坏页面上的行记录。但是它允许绕开坏页面然后从表中尚存的未损坏页面上继续检索数据行。因此它在因为硬件或者软件错误导致的崩溃中进行恢复是很有用的。通常不应该把它设置为on,除非不需要从崩溃的页面中恢复数据。 默认值:off
  • trace_recovery_messages 参数说明:启用恢复相关调试输出的日志录,否则将不会被记录。该参数允许覆盖正常设置的log_min_messages,但是仅限于特定的消息,这是为了在调试备机中使用。 该参数属于SIGHUP类型参数,请参考表1中对应设置方法进行设置。 取值范围:枚举类型,有效值有debug5、debug4、debug3、debug2、debug1、log,取值的详细信息请参见log_min_messages。 默认值:log 默认值log表示不影响记录决策。 除默认值外,其他值会导致优先级更高的恢复相关调试信息被记录,因为它们有log优先权。对于常见的log_min_messages设置,这会导致无条件地将它们记录到服务器日志上。
  • allow_create_sysobject 参数说明:设置是否允许在系统模式下创建或修改函数、存储过程、同义词、聚合函数、操作符等对象。此处的系统模式指数据库初始后自带的模式,但不包含public模式。系统模式的oid通常小于16384。 该参数属于POSTMASTER类型参数,请参考表1中对应设置方法进行设置。 取值范围:布尔型 on表示允许初始用户和系统管理员在系统模式下创建或修改函数、存储过程、同义词、聚合函数等对象,并允许初始用户在系统模式下创建操作符。其他用户是否允许创建这些对象请参考对应模式的权限要求。 off表示禁止所有用户在系统模式下创建或修改函数、存储过程、同义词、聚合函数、操作符等对象。 默认值:on
  • allow_system_table_mods 参数说明:设置是否允许修改系统表的结构或系统自带模式名称。 该参数属于POSTMASTER类型参数,请参考表1中对应设置方法进行设置。 取值范围:布尔型 on表示允许修改系统表的结构或系统自带模式名称。 off表示不允许修改系统表的结构或系统自带模式名称。 默认值:off 不建议修改该参数默认值,若设置为on,可能导致系统表损坏,甚至数据库无法启动。
  • 注意事项 游标命令只能在事务块里使用。 通常游标和SELECT一样返回文本格式。因为数据在系统内部是用二进制格式存储的,系统必须对数据做一定转换以生成文本格式。一旦数据是以文本形式返回,客户端应用需要把它们转换成二进制进行操作。使用FETCH语句,游标可以返回文本或二进制格式。 应该小心使用二进制游标。文本格式一般都比对应的二进制格式占用的存储空间大。二进制游标返回内部二进制形态的数据,可能更易于操作。如果想以文本方式显示数据,则以文本方式检索会为用户节约很多客户端的工作。比如,如果查询从某个整数列返回1,在缺省的游标里将获得一个字符串1,但在二进制游标里将得到一个4字节的包含该数值内部形式的数值(大端顺序)。
  • 功能描述 DECLARE命令既可以定义一个游标,用于在一个大的查询里面检索少数几行数据,也可以作为一个匿名块的开始。 本节主要描述定义为游标的用法,开启匿名块的用法见BEGIN。 为了处理SQL语句,存储过程进程分配一段内存区域来保存上下文联系。游标是指向上下文区域的句柄或指针。借助游标,存储过程可以控制上下文区域的变化。 通常游标和SELECT一样返回文本格式。因为数据在系统内部是用二进制格式存储的,系统必须对数据做一定转换以生成文本格式。一旦数据是以文本形式返回,客户端应用需要把它们转换成二进制进行操作。使用FETCH语句,游标可以返回文本或二进制格式。
  • 参数说明 cursor_name 将要创建的游标名。 取值范围:遵循数据库对象命名规范。 BINARY 指明游标以二进制而不是文本格式返回数据。 NO SCROLL 声明游标检索数据行的方式。 NO SCROLL:声明该游标不能用于以倒序的方式检索数据行。 未声明:根据执行计划的不同,自动判断该游标是否可以用于以倒序的方式检索数据行。 WITH HOLD WITHOUT HOLD 声明当创建游标的事务结束后,游标是否能继续使用。 WITH HOLD:声明该游标在创建它的事务结束后仍可继续使用。 WITHOUT HOLD:声明该游标在创建它的事务之外不能再继续使用,此游标将在事务结束时被自动关闭。 如果不指定WITH HOLD或WITHOUT HOLD,默认行为是WITHOUT HOLD。 query 使用SELECT或VALUES子句指定游标返回的行。 取值范围:SELECT或VALUES子句。 declare_statements 声明变量,包括变量名和变量类型,如“sales_cnt int”。 execution_statements 匿名块中要执行的语句。 取值范围:已存在的函数名称。
  • 参数说明 cursor_name 将要创建的游标名。 取值范围:遵循数据库对象命名规范。 BINARY 指明游标以二进制而不是文本格式返回数据。 NO SCROLL 声明游标检索数据行的方式。 NO SCROLL:声明该游标不能用于以倒序的方式检索数据行。 未声明:根据执行计划的不同,自动判断该游标是否可以用于以倒序的方式检索数据行。 WITH HOLD | WITHOUT HOLD 声明当创建游标的事务结束后,游标是否能继续使用。 WITH HOLD:声明该游标在创建它的事务结束后仍可继续使用。 WITHOUT HOLD:声明该游标在创建它的事务之外不能再继续使用,此游标将在事务结束时被自动关闭。 如果不指定WITH HOLD或WITHOUT HOLD,默认行为是WITHOUT HOLD。 跨节点事务不支持WITH HOLD(例如在多DBnode部署数据库中所创建的含有DDL的事务属于跨节点事务)。 query 使用SELECT或VALUES子句指定游标返回的行。 取值范围:SELECT或VALUES子句。
  • 示例 1234 --删除列加密密钥。openGauss=# DROP COLUMN ENCRYPTION KEY ImgCEK CASCADE;ERROR: cannot drop column setting: imgcek cascadely because encrypted column depend on it.HINT: we have to drop encrypted column: name, ... before drop column setting: imgcek cascadely.
  • 注意事项 只有数据库所有者或者被授予了数据库DROP权限的用户有权限执行DROP DATABASE命令,系统管理员默认拥有此权限。 不能对系统默认安装的三个数据库(POSTGRES、TEMPLATE0和TEMPLATE1)执行删除操作,系统做了保护。如果想查看当前服务中有哪几个数据库,可以用gsql的\l命令查看。 如果有用户正在与要删除的数据库连接,则删除操作失败。 不能在事务块中执行DROP DATABASE命令。 如果执行DROP DATABASE失败,事务回滚,需要再次执行一次DROP DATABASE IF EXISTS。 DROP DATABASE一旦执行将无法撤销,请谨慎使用。
  • 语法格式 [ WITH [ RECURSIVE ] with_query [, ...] ]DELETE [/*+ plan_hint */] [FROM] [ ONLY ] table_name [partition_clause] [ * ] [ [ AS ] alias ] [ USING using_list ] [ WHERE condition | WHERE CURRENT OF cursor_name ] [ LIMIT { count } ] [ RETURNING { * | { output_expr [ [ AS ] output_name ] } [, ...] } ];
  • 参数说明 WITH [ RECURSIVE ] with_query [, ...] 用于声明一个或多个可以在主查询中通过名称引用的子查询,相当于临时表。 如果声明了RECURSIVE,那么允许SELECT子查询通过名称引用它自己。 其中with_query的详细格式为: with_query_name [ ( column_name [, ...] ) ] AS [ [ NOT ] MATERIALIZED ]( {select | values | insert | update | delete} ) – with_query_name指定子查询生成的结果集名称,在查询中可使用该名称访问 子查询的结果集。 – column_name指定子查询结果集中显示的列名。 – 每个子查询可以是SELECT,VALUES,INSERT,UPDATE或DELETE语句。 – 用户可以使用MATERIALIZED / NOT MATERIALIZED对CTE进行修饰。 如果声明为MATERIALIZED,WITH查询将被物化,生成一个子查询结果集的拷贝,在引用处直接查询该拷贝,因此WITH子查询无法和主干SELECT语句进行联合优化(如谓词下推、等价类传递等),对于此类场景可以使用NOT MATERIALIZED进行修饰,如果WITH查询语义上可以作为子查询内联执行,则可以进行上述优化。 如果用户没有显示声明物化属性则遵守以下规则:如果CTE只在所属主干语句中被引用一次,且语义上支持内联执行,则会被改写为子查询内联执行,否则以CTE Scan的方式物化执行。 plan_hint子句 以/*+ */的形式在DELETE关键字后,用于对DELETE对应的语句块生成的计划进行hint调优,详细用法请参见章节使用Plan Hint进行调优。每条语句中只有第一个/*+ plan_hint */注释块会作为hint生效,里面可以写多条hint。 ONLY 如果指定ONLY则只有该表被删除;如果没有声明,则该表和它的所有子表将都被删除。 table_name 目标表的名称(可以有模式修饰)。 取值范围:已存在的表名。 partition_clause 指定分区删除操作 PARTITION { ( partition_name ) | FOR ( partition_value [, ...] ) } | SUBPARTITION { ( subpartition_name ) | FOR ( subpartition_value [, ...] ) } 关键字详见SELECT一节介绍 示例详见CREATE TABLE SUBPARTITION alias 目标表的别名。 取值范围:字符串,符合标识符命名规范。 using_list using子句。 condition 一个返回Boolean值的表达式,用于判断哪些行需要被删除。不建议使用int等数值类型作为condition,因为int等数值类型可以隐式转换为bool值(非0值隐式转换为true,0转换为false),可能导致非预期的结果。 WHERE CURRENT OF cursor_name 当前不支持,仅保留语法接口。 LIMIT子句 关键字详见SELECT一节介绍 output_expr DELETE命令删除行之后计算输出结果的表达式。该表达式可以使用表的任意字段。可以使用*返回被删除行的所有字段。 output_name 一个字段的输出名称。 取值范围:字符串,符合标识符命名规范。
  • 参数说明 src_name 待删除的Data Source对象名称。 取值范围:字符串,符合标识符命名规范。 IF EXISTS 如果指定的Data Source不存在,则发出一个notice而不是报错。 CASCADE | RESTRICT CASCADE:表示允许级联删除依赖于Data Source的对象 RESTRICT(缺省值):表示有依赖于该Data Source的对象存在,则该Data Source无法删除。 目前Data Source对象没有被依赖的对象,CASCADE和RESTRICT效果一样,保留此选项是为了向后兼容性。
  • 注意事项 当enable_access_server_directory=off时,只允许初始用户删除directory对象;当enable_access_server_directory=on时,具有SYSADMIN权限的用户、directory对象的属主、被授予了该directory的DROP权限的用户或者继承了内置角色gs_role_directory_drop权限的用户可以删除directory对象。
  • 参数说明 CONCURRENTLY 以不加锁的方式删除索引。删除索引时,一般会阻塞其他语句对该索引所依赖表的访问。加此关键字,可实现删除过程中不做阻塞。 此选项只能指定一个索引的名称, 并且CASCADE选项不支持。 普通DROP INDEX命令可以在事务内执行,但是DROP INDEX CONCURRENTLY不可以在事务内执行。 IF EXISTS 如果指定的索引不存在,则发出一个notice而不是抛出一个错误。 index_name 要删除的索引名。 取值范围:已存在的索引。 CASCADE | RESTRICT CASCADE:表示允许级联删除依赖于该索引的对象。 RESTRICT(缺省值):表示有依赖与此索引的对象存在,则该索引无法被删除。
  • 示例 --创建数据表all_dataopenGauss=# CREATE TABLE all_data(id int, role varchar(100), data varchar(100));--创建行访问控制策略openGauss=# CREATE ROW LEVEL SECURITY POLICY all_data_rls ON all_data USING(role = CURRENT_USER);--删除行访问控制策略openGauss=# DROP ROW LEVEL SECURITY POLICY all_data_rls ON all_data;
  • 示例 示例1:创建各种组合类型的二级分区表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 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 partitionselect * 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 partitionDETAIL: 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 subpartitionDETAIL: 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 4delete from range_list partition for ('201903');DELETE 0delete from range_list subpartition (p_201901_a);DELETE 0delete from range_list subpartition for ('201903','2');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) pUSING newrange_list partition (p_201901) npON p.month_code= np.month_codeWHEN MATCHED THEN UPDATE SET dept_code = np.dept_code, user_no = np.user_no, sales_amt = np.sales_amtWHEN 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') pUSING newrange_list partition for ('201901') npON p.month_code= np.month_codeWHEN MATCHED THEN UPDATE SET dept_code = np.dept_code, user_no = np.user_no, sales_amt = np.sales_amtWHEN 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) pUSING newrange_list subpartition (p_201901_a) npON p.month_code= np.month_codeWHEN MATCHED THEN UPDATE SET dept_code = np.dept_code, user_no = np.user_no, sales_amt = np.sales_amtWHEN 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') pUSING newrange_list subpartition for ('201901', '1') npON p.month_code= np.month_codeWHEN MATCHED THEN UPDATE SET dept_code = np.dept_code, user_no = np.user_no, sales_amt = np.sales_amtWHEN 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操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 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操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99100101102103104105106107108109110111112113114115116117118 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;
  • 注意事项 二级分区表有两个分区键,每个分区键只能支持1列,两个分区键不能是同一列。 唯一约束和主键约束的约束键包含所有分区键将为约束创建LOCAL索引,否则创建GLOBAL索引。如果指定创建local唯一索引,必须包含所有分区键。 创建二级分区表时,如果在其一级分区下不显示指定二级分区,会自动创建一个同范围的二级分区。 二级分区表的二级分区(叶子节点)个数不能超过1048575个,一级分区无限制,但一级分区下面至少有一个二级分区。 二级分区表的总分区数(包括一级分区和二级分区)最大值为1048575个,一般情况下业务不可能创建这么多分区,这样会导致内存不足。应参照参数local_syscache_threshold的值合理创建分区,二级分区表使用内存大致为(总分区数 * 3 / 1024)MB。理论上分区占用内存不允许大于local_syscache_threshold的值,同时还需要预留部分空间以供其他功能使用。 二级分区表只支持行存,不支持列存,hashbucket。 不支持cluster。 指定分区查询时,如select * from tablename partition/subpartition (partitionname),关键字partition和subpartition注意不要写错。如果写错,查询不会报错,这时查询会变为对表起别名进行查询。 不支持密态数据库、账本数据库和行级访问控制。 对于二级分区表PARTITION FOR (values)语法,values只能是常量。 对于二级分区表PARTITION/SUBPARTITION FOR (values)语法,values在需要数据类型转换时,建议使用强制类型转换,以防隐式类型转换结果与预期不符。 指定分区语句目前不能走全局索引扫描。
  • 参数说明 IF NOT EXISTS 如果已经存在相同名称的表,不会抛出一个错误,而会发出一个通知,告知表关系已存在。 subpartition_table_name 二级分区表的名称。 取值范围:字符串,要符合标识符的命名规范。 column_name 新表中要创建的字段名。 取值范围:字符串,要符合标识符的命名规范。 data_type 字段的数据类型。 COLLATE collation COLLATE子句指定列的排序规则(该列必须是可排列的数据类型)。如果没有指定,则使用默认的排序规则。排序规则可以使用“select * from pg_collation;”命令从pg_collation系统表中查询,默认的排序规则为查询结果中以default开始的行。 CONSTRAINT constraint_name 列约束或表约束的名称。可选的约束子句用于声明约束,新行或者更新的行必须满足这些约束才能成功插入或更新。 定义约束有两种方法: 列约束:作为一个列定义的一部分,仅影响该列。 表约束:不和某个列绑在一起,可以作用于多个列。 LIKE source_table [ like_option ... ] 二级分区表暂不支持该功能。 WITH ( storage_parameter [= value] [, ... ] ) 这个子句为表或索引指定一个可选的存储参数。参数的详细描述如下所示: FILLFACTOR 一个表的填充因子(fillfactor)是一个介于10和100之间的百分数。100(完全填充)是默认值。如果指定了较小的填充因子,INSERT操作仅按照填充因子指定的百分率填充表页。每个页上的剩余空间将用于在该页上更新行,这就使得UPDATE有机会在同一页上放置同一条记录的新版本,这比把新版本放置在其他页上更有效。对于一个从不更新的表将填充因子设为100是最佳选择,但是对于频繁更新的表,选择较小的填充因子则更加合适。该参数对于列存表没有意义。 取值范围:10~100 ORIENTATION 决定了表的数据的存储方式。 取值范围: COLUMN:表的数据将以列式存储。 ROW(缺省值):表的数据将以行式存储。 orientation不支持修改。 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则不对表进行压缩。行存表不支持压缩。 缺省值为NOCOMPRESS,即不对元组数据进行压缩。 TABLESPACE tablespace_name 指定新表将要在tablespace_name表空间内创建。如果没有声明,将使用默认表空间。 PARTITION BY {RANGE | LIST | HASH} (partition_key) 对于partition_key,分区策略的分区键仅支持1列。 分区键支持的数据类型和一级分区表约束保持一致。 SUBPARTITION BY {RANGE | LIST | HASH} (subpartition_key) 对于subpartition_key,分区策略的分区键仅支持1列。 分区键支持的数据类型和一级分区表约束保持一致。 { ENABLE | DISABLE } ROW MOVEMENT 行迁移开关。 如果进行UPDATE操作时,更新了元组在分区键上的值,造成了该元组所在分区发生变化,就会根据该开关给出报错信息,或者进行元组在分区间的转移。 取值范围: ENABLE(缺省值):行迁移开关打开。 DISABLE:行迁移开关关闭。 在打开行迁移开关情况下,并发update、delete操作可能会报错,原因如下: 目前GaussDB astore引擎下,update和delete操作对于旧数据都是标记为已删除。在打开行迁移开关情况下,如果更新分区键时,导致了跨分区更新,目前GaussDB astore引擎下,会把旧分区中旧数据标记为已删除,在新分区中新增加一条数据,无法通过旧数据找到新数据。 在以下三个并发场景下,update和update并发,delete和delete并发,update和delete并发,如果并发操作同一行数据时,数据跨分区和非跨分区结果有不同的行为。 对于数据非跨分区结果,第一个操作执行完后,第二个操作不会报错。 如果第一个操作是update,第二个操作能成功找到最新的数据,之后对新数据操作。 如果第一个操作是delete,第二个操作看到当前数据已经被删除而且找不到最新数据,就终止操作。 对于数据跨分区结果,第一个操作执行完后,第二个操作会报错。 如果第一个操作是update,由于新数据在新分区中,第二个操作不能成功找到最新的数据,就无法操作,之后会报错。 如果第一个操作是delete,第二个操作看到当前数据已经被删除而且找不到最新数据,但无法判断删除旧数据的操作是update还是delete。如果是update,报错处理。如果是delete,终止操作。为了保持数据的正确性,只能报错处理。 如果是update和update并发,update和delete并发场景,需要串行执行才能解决问题,如果是delete和delete并发,关闭行迁移开关可以解决问题。 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表示像普通列一样存储生成列的值。 生成表达式不能以任何方式引用当前行以外的其他数据。生成表达式不能引用其他生成列,不能引用系统列。生成表达式不能返回结果集,不能使用子查询,不能使用聚集函数,不能使用窗口函数。生成表达式调用的函数只能是不可变(IMMUTABLE)函数。 不能为生成列指定默认值。 生成列不能作为分区键的一部分。 生成列不能和ON UPDATE约束字句的CASCADE,SET NULL,SET DEFAULT动作同时指定。生成列不能和ON DELETE约束字句的SET NULL,SET DEFAULT动作同时指定。 修改和删除生成列的方法和普通列相同。删除生成列依赖的普通列,生成列被自动删除。不能改变生成列所依赖的列的类型。 生成列不能被直接写入。在INSERT或UPDATE命令中, 不能为生成列指定值, 但是可以指定关键字DEFAULT。 生成列的权限控制和普通列一样。 列存表、内存表MOT不支持生成列。外表中仅postgres_fdw支持生成列。 UNIQUE index_parameters UNIQUE ( column_name [, ... ] ) index_parameters UNIQUE约束表示表里的一个字段或多个字段的组合必须在全表范围内唯一。 对于唯一约束,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为空,将使用数据库的缺省表空间。
  • 功能描述 创建二级分区表。分区表是把逻辑上的一张表根据某种方案分成几张物理块进行存储,这张逻辑上的表称之为分区表,物理块称之为分区。分区表是一张逻辑表,不存储数据,数据实际是存储在分区上的。对于二级分区表,顶层节点表和一级分区都是逻辑表,不存储数据,只有二级分区(叶子节点)存储数据。 二级分区表的分区方案是由两个一级分区的分区方案组合而来的,一级分区的分区方案详见章节CREATE TABLE PARTITION。 常见的二级分区表组合方案有Range-Range分区、Range-List分区、Range-Hash分区、List-Range分区、List-List分区、List-Hash分区、Hash-Range分区、Hash-List分区、Hash-Hash分区等。目前二级分区仅支持行存表。
  • 语法格式 CREATE TABLE [ IF NOT EXISTS ] subpartition_table_name( { column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ]| table_constraint| LIKE source_table [ like_option [...] ] }[, ... ])[ WITH ( {storage_parameter = value} [, ... ] ) ][ COMPRESS | NOCOMPRESS ][ TABLESPACE tablespace_name ]PARTITION BY {RANGE | LIST | HASH} (partition_key) SUBPARTITION BY {RANGE | LIST | HASH} (subpartition_key)( PARTITION partition_name1 [ VALUES LESS THAN (val1) | VALUES (val1[, …]) ] [ TABLESPACE tablespace ] [( { SUBPARTITION subpartition_name1 [ VALUES LESS THAN (val1_1) | VALUES (val1_1[, …])] [ TABLESPACE tablespace ] } [, ...] )][, ...])[ { ENABLE | DISABLE } ROW MOVEMENT ]; 列约束column_constraint: [ CONSTRAINT constraint_name ]{ NOT NULL | NULL | CHECK ( expression ) | DEFAULT default_e xpr | GENERATED ALWAYS AS ( generation_expr ) STORED | UNIQUE index_parameters | PRIMARY KEY index_parameters | REFEREN CES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] }[ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] 表约束table_constraint: [ CONSTRAINT constraint_name ]{ CHECK ( expression ) | UNIQUE ( column_name [, ... ] ) index_parameters | PRIMARY KEY ( column_name [, ... ] ) index_parameters | FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] }[ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] 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 EXISTS 如果指定的模式不存在,发出一个notice而不是抛出一个错误。 schema_name 模式的名称。 取值范围:已存在模式名。 CASCADE | RESTRICT CASCADE:自动删除包含在模式中的对象。 RESTRICT:如果模式包含任何对象,则删除失败(缺省行为)。 不要随意删除pg_temp或pg_toast_temp开头的模式,这些模式是系统内部使用的,如果删除,可能导致无法预知的结果。 无法删除当前模式。如果要删除当前模式,须切换到其他模式下。
  • 参数说明 IF EXISTS 如果指定的全文检索词典不存在,那么发出一个Notice而不是报错。 name 要删除的词典名称(可指定模式名,否则默认在当前模式下)。 取值范围:已存在的词典名。 CASCADE 自动删除依赖于该词典的对象,并依次删除依赖于这些对象的所有对象。 如果存在任何一个使用该词典的文本搜索配置,此DROP命令将不会成功。可添加CASCADE以删除引用该词典的所有文本搜索配置以及词典。 RESTRICT 如果任何对象依赖词典,则拒绝删除该词典。这是缺省值。
  • 参数说明 IF EXISTS 如果指定的表不存在,则发出一个notice而不是抛出一个错误。 schema 模式名称。 table_name 表名称。 CASCADE | RESTRICT CASCADE:级联删除依赖于表的对象(比如视图)。 RESTRICT(缺省项):如果存在依赖对象,则拒绝删除该表。这个是缺省。 PURGE 该参数表示即使开启回收站功能,drop表时,也会直接物理删除表,而不是将其放入回收站中。
  • 参数说明 IF EXISTS 如果指定的触发器不存在,则发出一个notice而不是抛出一个错误。 trigger_name 要删除的触发器名称。 取值范围:已存在的触发器。 table_name 要删除的触发器所在的表名称。 取值范围:已存在的含触发器的表。 CASCADE | RESTRICT CASCADE:级联删除依赖此触发器的对象。 RESTRICT:如果有依赖对象存在,则拒绝删除此触发器。此选项为缺省值。
  • 注意事项 只有表空间所有者或者被授予了表空间DROP权限的用户有权限执行DROP TABLESPACE命令,系统管理员默认拥有此权限。 在删除一个表空间之前,表空间里面不能有任何数据库对象,否则会报错。 DROP TABLESPACE不支持回滚,因此,不能出现在事务块内部。 执行DROP TABLESPACE操作时,如果有另外的会话执行\db查询操作,可能会由于tablespace事务的原因导致查询失败,请重新执行\db查询操作。 如果执行DROP TABLESPACE失败,需要再次执行一次DROP TABLESPACE IF EXISTS。
  • 参数说明 EXPLAIN中的PLAN选项表示需要将计划信息存储于PLAN_TABLE中,存储成功将返回“EXPLAIN SUCCESS”。 STATEMENT_ID用户可以对查询设置标签,输入的标签信息也将存储于PLAN_TABLE中。 用户在执行EXPLAIN PLAN时,如果没有进行SET STATEMENT_ID,则默认为空值。同时,用户可输入的STATEMENT_ID最大长度为30个字节,超过长度将会产生报错。
  • 示例 --创建表reason。openGauss=# CREATE TABLE tpcds.reason ( CD_DEMO_SK INTEGER NOT NULL, CD_GENDER character(16) , CD_MARITAL_STATUS character(100));--插入数据。openGauss=# INSERT INTO tpcds.reason VALUES(51, 'AAAAAAAADDAAAAAA', 'reason 51');--创建表reason_t1。openGauss=# CREATE TABLE tpcds.reason_t1 AS TABLE tpcds.reason;--为一个INSERT语句创建一个预备语句然后执行它。openGauss=# PREPARE insert_reason(integer,character(16),character(100)) AS INSERT INTO tpcds.reason_t1 VALUES($1,$2,$3);openGauss=# EXECUTE insert_reason(52, 'AAAAAAAADDAAAAAA', 'reason 52'); --删除表reason和reason_t1。openGauss=# DROP TABLE tpcds.reason;openGauss=# DROP TABLE tpcds.reason_t1;
  • 语法格式 ALTER [ ROW LEVEL SECURITY ] POLICY [ IF EXISTS ] policy_name ON table_name RENAME TO new_policy_name;ALTER [ ROW LEVEL SECURITY ] POLICY policy_name ON table_name [ TO { role_name | PUBLIC } [, ...] ] [ USING ( using_expression ) ];
共100000条