华为云用户手册

  • max_locks_per_transaction 参数说明:控制每个事务能够得到的平均的对象锁的数量。 共享的锁表的大小是以假设任意时刻最多只有max_locks_per_transaction*(max_connections+max_prepared_transactions) 个独立的对象需要被锁住为基础进行计算的。不超过设定数量的多个对象可以在任一时刻同时被锁定。当在一个事务里面修改很多不同的表时,可能需要提高这个默认数值。只能在数据库启动的时候设置。 增大这个参数可能导致 GaussDB 请求更多的System V共享内存,有可能超过操作系统的缺省配置。 当运行备机时,请将此参数设置不小于主机上的值,否则,在备机上查询操作不会被允许。 该参数属于POSTMASTER类型参数,请参考表1中对应设置方法进行设置。 取值范围:整型,10 ~ INT_MAX 默认值: 256(196核CPU/1536G内存,128核CPU/1024G内存,104核CPU/1024G内存,96核CPU/1024G内存,96核CPU/768G内存,80核CPU/640G内存,64核CPU/512G内存,60核CPU/480G内存,32核CPU/256G内存,16核CPU/128G内存,8核CPU/64G内存,4核CPU/32G内存);64(4核CPU/16G内存)
  • max_pred_locks_per_transaction 参数说明:控制每个事务允许断定锁的最大数量,是一个平均值。 共享的断定锁表的大小是以假设任意时刻最多只有max_pred_locks_per_transaction*(max_connections+max_prepared_transactions) 个独立的对象需要被锁住为基础进行计算的。不超过设定数量的多个对象可以在任一时刻同时被锁定。当在一个事务里面修改很多不同的表时,可能需要提高这个默认数值。只能在服务器启动的时候设置。 增大这个参数可能导致GaussDB请求更多的System V共享内存,有可能超过操作系统的缺省配置。 该参数属于POSTMASTER类型参数,请参考表1中对应设置方法进行设置。 取值范围:整型,10 ~ INT_MAX 默认值:64
  • partition_lock_upgrade_timeout 参数说明:在执行某些查询语句的过程中,会需要将分区表上的锁级别由允许读的ExclusiveLock级别升级到读写阻塞的AccessExclusiveLock级别。如果此时已经存在并发的读事务,那么该锁升级操作将阻塞等待。partition_lock_upgrade_timeout为尝试锁升级的等待超时时间。 在分区表上进行MERGE PARTITION和CLUSTER PARTITION操作时,都利用了临时表进行数据重排和文件交换,为了最大程度提高分区上的操作并发度,在数据重排阶段给相关分区加锁ExclusiveLock,在文件交换阶段加锁AccessExclusiveLock。 常规加锁方式是等待加锁,直到加锁成功,或者等待时间超过lockwait_timeout发生超时失败。 在分区表上进行MERGE PARTITION或CLUSTER PARTITION操作时,进入文件交换阶段需要申请加锁AccessExclusiveLock,加锁方式是尝试性加锁,加锁成功了则立即返回,不成功则等待50ms后继续下次尝试,加锁超时时间使用会话级设置参数partition_lock_upgrade_timeout。 特殊值:若partition_lock_upgrade_timeout取值-1,表示无限等待,即不停的尝试锁升级,直到加锁成功。 该参数属于USERSET类型参数,请参考表1中对应设置方法进行设置。 取值范围:整型,最小值-1,最大值3000,单位为秒(s)。 默认值:1800
  • num_internal_lock_partitions 参数说明:控制内部轻量级锁分区的个数。主要用于各类场景的性能调优。内容以关键字和数字的KV方式组织,各个不同类型锁之间以逗号隔开。先后顺序对设置结果不影响,例如“C LOG _PART=256, CS NLOG_PART=512”等同于“CSNLOG_PART=512,CLOG_PART=256”。重复设置同一关键字时,以最后一次设置为准,例如“CLOG_PART=256,CLOG_PART=2”,设置的结果为CLOG_PART=2。当没有设置关键字时,则为默认值,各类锁的使用描述和最大、最小、默认值如下。 CLOG_PART:CLOG文件控制器的个数,增大该值可以提高CLOG日志写入效率,提升事务提交性能,但是会增大内存使用;减小该值会减少相应内存使用,但可能使得CLOG日志写入冲突变大,影响性能。最小值为1,最大值为256。 CSNLOG_PART:CSNLOG文件控制器的个数,增大该值可以提高CSNLOG日志写入效率,提升事务提交性能,但是会增大内存使用;减小该值会减少相应内存使用,但可能使得CSNLOG日志写入冲突变大,影响性能。最小值为1,最大值为512。 LOG2_LOCKTABLE_PART:常规锁表锁分区个数的2对数,增大该值可以提升正常流程常规锁获取锁的并行度,但是可能增加锁转移和锁消除时的耗时,对于等待事件在LockMgrLock时,可以调大该锁增加性能。最小值4,即锁分区数为16;最大值为16,即锁分区数为65536。 TWOPHASE_PART:两阶段事务锁的分区数,调大该值可以提高两阶段事务提交的并发数。最小值为1,最大值为64。 FASTPATH_PART:每个线程可以不通过主锁表拿锁的最大锁个数,对于分区表读取、更新、插入、删除操作且等待事件在LockMgrLock时,可以通过调大该值避免获取LockMgrLock提升性能,建议调整数量大于等于分区数*(1+本地索引数量)+全局索引数量+10,调大该值会额外增加内存。最小值为20,最大值为10000。 该参数属于POSTMASTER类型参数,参考表1中对应设置方法进行设置。 取值范围:字符串 默认值: 'CLOG_PART=256,CSNLOG_PART=512,LOG2_LOCKTABLE_PART=4,TWOPHASE_PART=1,FASTPATH_PART=20'(196核CPU/1536G内存,128核CPU/1024G内存,104核CPU/1024G内存,96核CPU/1024G内存,96核CPU/768G内存,80核CPU/640G内存,64核CPU/512G内存,60核CPU/480G内存,32核CPU/256G内存,16核CPU/128G内存,8核CPU/64G内存,4核CPU/32G内存);'CLOG_PART=8,CSNLOG_PART=16,LOG2_LOCKTABLE_PART=4,TWOPHASE_PART=1,FASTPATH_PART=20'(4核CPU/16G内存)
  • MY_SYNONYMS MY_SYNONYMS视图显示当前模式下同义词的信息。该视图所有用户可访问,仅可查看当前用户所属信息。该视图同时存在于PG_CATALOG和SYS schema下。 表1 MY_SYNONYMS字段 名称 类型 描述 schema_name text 同义词所属模式名。 synonym_name text 同义词的名称。 table_owner text 关联对象的所有者。尽管该列称为table_owner,但它拥有的该关联对象不一定是表,可以是任何数据库通用对象,例如视图、存储过程、同义词等。 table_name text 关联对象名。尽管该列称为table_name,但此关联对象不一定是表,可以是任何数据库通用对象,例如视图、存储过程、同义词等。 table_schema_name text 关联对象所属模式名。尽管该列称为table_schema_name,但此schema下的该关联对象不一定是表,可以是任何数据库通用对象,例如视图、存储过程、同义词等。 db_link character varying(128) 保留字段,值为NULL。 origin_con_id character varying(256) 暂不支持,值为0。 父主题: 系统视图
  • 注意事项 TIMECAPSULE TABLE语句的用法主要分为两大类:闪回旧版本数据和从回收站中闪回。 TO TIMECAPSULE和TO CSN能够将表闪回到过去的某个版本。 回收站记录了DROP和TRUNCATE的对象数据。TO BEFORE DROP和TO BEFORE TRUNCATE就是从回收站中闪回。 不支持闪回表的对象类型:系统表、DFS表、全局临时表、本地临时表、UNLOGGED表、序列表、hashbucket表、密态表。 不支持含有自定义类型表的闪回。 开启闪回后,回收站里的表可以进行表级备份,无法进行表级恢复。 闪回点和当前点之间,执行过修改表结构或影响物理存储的语句(DDL、DCL、VACUUM FULL),闪回失败。 执行闪回删除需要用户具有如下权限:用户必须具有垃圾对象所在SCHEMA的CREATE和USAGE权限,并且用户必须是SCHEMA的所有者或者是垃圾对象的所有者。 执行闪回TRUNCATE需要用户具有如下权限:用户必须具有垃圾对象所在SCHEMA的CREATE和USAGE权限,并且用户必须是SCHEMA的所有者或者是垃圾对象的所有者,另外用户必须具有垃圾对象的TRUNCATE权限。 不适用闪回DROP/TRUNCATE功能的场景或表: 回收站关闭场景:enable_recyclebin = off; 系统处于维护态(xc_maintenance_mode = on)或升级场景; 多对象删除场景:DROP/TRUNCATE TABLE命令同时指定多个对象; 系统表、DFS表、全局临时表、本地临时表、UNLOGGED表、序列表、hashbucket表。 如果表依赖的对象为外部对象(如表列为复合类型、自定义类型等),则采用物理删除,不将表放入回收站。 DROP闪回约束: 可以指定原始用户指定的表的名称,或对象删除时数据库分配的系统生成名称。 回收站中系统生成的对象名称是唯一的。因此,如果指定系统生成名称,那么数据库检索指定的对象。使用“select * from gs_recyclebin;”语句查看回收站中的内容。 如果指定了用户指定的名称,且回收站中包含多个该名称的对象,那么数据库检索回收站中最近移动的对象。如果需要检索更早版本的表,请按以下步骤执行: 指定需要检索的表的系统生成名称。 执行TIMECAPSULE TABLE ... TO BEFORE DROP语句,直到找到要检索的表。 恢复DROP表时,只恢复基表名,其他子对象名均保持回收站对象名。用户可根据需要,执行DDL命令手工调整子对象名。 如果表存在缺省值引用序列和自定义函数,那么闪回DROP表成功但不会恢复缺省值。 如果表存在视图引用,DROP表时需要级联删除视图,那么闪回DROP表成功但不会恢复视图。 回收站对象不支持DML、DCL、DDL等写操作,不支持DQL查询操作(后续支持)。 recyclebin_retention_time配置参数用于设置回收站对象保留时间,超过该时间的回收站对象将被自动清理。 不支持DROP多表的恢复。 不支持级联删除账号/schema场景的恢复。 删除账号/Schema时,若回收站中存在该Schema/账号的对象,普通删除会失败,需要级联删除。 TRUNCATE闪回约束: TRUNCATE闪回后,统计信息无变化,仍显示为0,可以在业务低峰期(以降低性能影响)的时候手动analyze来修正统计信息。 RENAME TO仅支持DROP闪回操作为检索表指定新名称,不支持TRUNCATE闪回。 TRUNCATE闪回不能跨越影响表结构或物理存储的语句,否则会报错。即闪回点和当前点之间,如果执行过修改表结构或影响物理存储的语句(DDL、DCL、VACUUM FULL、增加/删除/切割/合成等分区操作),则闪回失败。执行过DDL的表进行闪回操作报错:“ERROR:The table definition of %s has been changed. ”。涉及namespace、表名改变等操作的DDL执行闪回操作报错: “ERROR: recycle object %s desired does not exist. ”。
  • 参数说明 schema 指定模式包含的表。如果缺省,则为当前模式。 table_name 指定表名。 TO CSN 指定要返回表的时间点对应的事务提交序列号(CSN)。expr必须计算一个数字,代表有效的CSN。 TO TIMESTAMP 指定要返回表的时间点对应的时间戳。expr必须计算一个过去有效的时间戳(使用TO_TIMESTAMP函数将字符串转换为时间类型)。表将被闪回到指定时间戳大约3秒内的时间点。 说明:闪回点过旧时,因旧版本被回收导致无法获取旧版本,会导致闪回失败并报错:Restore point too old。 TO BEFORE DROP 使用这个子句检索回收站中已删除的表及其子对象。 RENAME TO 为从回收站中检索的表指定一个新名称。 TO BEFORE TRUNCATE 闪回到TRUNCATE之前。
  • 示例 -- 创建SCHEMA gaussdb=# CREATE SCHEMA tpcds; -- 删除表tpcds.reason_t2 DROP TABLE IF EXISTS tpcds.reason_t2; -- 创建表tpcds.reason_t2 gaussdb=# CREATE TABLE tpcds.reason_t2 ( r_reason_sk integer, r_reason_id character(16), r_reason_desc character(100) )with(storage_type = ustore); --向表tpcds.reason_t2中插入记录 gaussdb=# INSERT INTO tpcds.reason_t2 VALUES (1, 'AA', 'reason1'),(2, 'AB', 'reason2'),(3, 'AC', 'reason3'); INSERT 0 3 --清空tpcds.reason_t2表中的数据 gaussdb=# TRUNCATE TABLE tpcds.reason_t2; --查询tpcds.reason_t2表中的数据 gaussdb=# select * from tpcds.reason_t2; r_reason_sk | r_reason_id | r_reason_desc -------------+-------------+--------------- (0 rows) --执行闪回TRUNCATE gaussdb=# TIMECAPSULE TABLE tpcds.reason_t2 to BEFORE TRUNCATE; gaussdb=# select * from tpcds.reason_t2; r_reason_sk | r_reason_id | r_reason_desc -------------+------------------+------------------------------------------------------------------------------------------------------ 1 | AA | reason1 2 | AB | reason2 3 | AC | reason3 (3 rows) --删除表tpcds.reason_t2 gaussdb=# DROP TABLE tpcds.reason_t2; --执行闪回DROP gaussdb=# TIMECAPSULE TABLE tpcds.reason_t2 to BEFORE DROP; TimeCapsule Table --执行闪回DROP,为检索表指定新名称 gaussdb=# TIMECAPSULE TABLE tpcds.reason_t2 TO BEFORE DROP rename to reason_t3; TimeCapsule Table -- 清空回收站,删除SCHEMA gaussdb=# PURGE RECYCLEBIN; gaussdb=# DROP SCHEMA tpcds CASCADE;
  • MY_CONSTRAINTS MY_CONSTRAINTS视图显示当前用户下表中约束的信息。该视图同时存在于PG_CATALOG和SYS Schema下。 表1 MY_CONSTRAINTS字段 名称 类型 描述 owner character varyiny(64) 约束创建者。 constraint_name vcharacter varying(64) 约束名。 constraint_type text 约束类型: c表示检查约束。 f表示外键约束。 p表示主键约束。 u表示唯一约束。 table_name character varying(64) 约束相关的表名。 index_owner character varying(64) 约束相关的索引的所有者(只针对唯一约束和主键约束)。 index_name character varying(64) 约束相关的索引的名称(只针对唯一约束和主键约束)。 父主题: 系统视图
  • PG_REPLICATION_ORIGIN_STATUS PG_REPLICATION_ORIGIN_STATUS视图可用来查看复制源的复制状态。 表1 PG_REPLICATION_ORIGIN_STATUS字段 名称 类型 描述 local_id oid 复制源ID。 external_id text 复制源名称。 remote_lsn text 复制源的lsn位置。 local_lsn text 本地的lsn位置。 父主题: 系统视图
  • PG_RUNNING_XA CTS PG_RUNNING_XACTS视图显示当前节点运行事务的信息。 表1 PG_RUNNING_XACTS字段 名称 类型 描述 handle integer 事务对应的事务管理器中的槽位句柄,该值恒为-1。 gxid xid 事务id号。 state tinyint 事务状态。 3:prepared。 0:starting。 node text 节点名称。 xmin xid 节点上当前数据涉及的最小事务号。 vacuum boolean 表示当前事务是否是lazy vacuum事务。 t(true):表示是。 f(false):表示不是。 timeline bigint 数据库重启次数。 prepare_xid xid 处于prepared状态的事务的id,若事务不在prepared状态,值为0。 pid bigint 事务对应的线程id。 next_xid xid 本地活跃事务最小CSN值。 父主题: 系统视图
  • 服务器信号函数 服务器信号函数向其他服务器进程发送控制信号。只有系统管理员有权执行以下函数。 pg_cancel_backend(pid int) 描述:取消一个后端线程正在执行的语句。 返回值类型:Boolean 备注:pg_cancel_backend向由pid标识的后端进程发送一个查询取消(SIGINT)信号。一个活动的后端进程的PID可以从pg_stat_activity视图的pid字段找到,或者在服务器上用ps列出数据库进程。具有SYSADMIN权限的用户,后端进程所连接的数据库的属主,后端进程的属主或者继承了内置角色gs_role_signal_backend权限的用户有权使用该函数。 pg_cancel_session(pid bigint, sessionid bigint) 描述:线程池模式下,取消一个活跃状态会话正在执行的语句。 返回值类型:Boolean 备注:pg_cancel_session的入参可以通过pg_stat_activity中的pid字段和sessionid的字段查询,可以用于清理线程池模式下,活跃状态会话正在执行的语句。当入参pid和sessionid相同,且均为线程id时,功能和pg_cancel_backend相同。 pg_reload_conf() 描述:导致所有服务器进程重新装载它们的配置文件。 返回值类型:Boolean 备注:pg_reload_conf给服务器发送一个SIGHUP信号,导致所有服务器进程重新装载配置文件。 pg_rotate_logfile() 描述:滚动服务器的日志文件。 返回值类型:Boolean 备注:pg_rotate_logfile给日志文件管理器发送信号,使之立即切换到一个新的输出文件。这个函数只有在redirect_stderr用于日志输出的时候才有用,否则不会产生日志文件管理器子进程。 pg_terminate_backend(pid int) 描述:终止一个后台线程。 返回值类型:Boolean 备注:如果成功,函数返回true,否则返回false。具有SYSADMIN权限的用户,后端线程所连接的数据库的属主,后端线程的属主或者继承了内置角色gs_role_signal_backend权限的用户有权使用该函数。若执行该函数后未成功终止目标会话,则会强制关闭该会话和客户端的socket连接。 该函数可终止非线程池的线程、活跃状态的线程池线程,但无法终止非活跃状态的线程池线程。 示例: 1 2 3 4 5 6 7 8 9 10 11 gaussdb=# SELECT pid from pg_stat_activity; pid ----------------- 140657876268816 (1 rows) gaussdb=# SELECT pg_terminate_backend(140657876268816); pg_terminate_backend ---------------------- t (1 row) pg_terminate_session(pid int64, sessionid int64) 描述:线程池模式下,终止一个后台session。 返回值类型:Boolean 备注:如果成功,函数返回true,否则返回false。具有SYSADMIN权限的用户、会话所连接的数据库的属主、会话的属主、或者继承了内置角色gs_role_signal_backend权限的用户有权使用该函数。若执行该函数后未成功终止目标会话,则会强制关闭该会话和客户端的socket连接。 当入参pid和sessionid相同,且均为线程id时,该函数可终止非线程池的线程、活跃状态的线程池线程。 当入参pid和sessionid不同时,该函数可终止活跃状态的会话,或关闭非活跃状态会话和客户端的socket连接。 pg_terminate_active_session_socket(pid int64, sessionid int64) 描述:关闭一个活跃session和客户端的socket连接。 返回值类型:Boolean 备注:如果成功,函数返回true,否则返回false。具有SYSADMIN权限的用户、后端线程所连接的数据库的属主、后端线程的属主或者继承了内置角色gs_role_signal_backend权限的用户有权使用该函数。 父主题: 系统管理函数
  • 模式匹配操作符 数据库提供了三种独立的实现模式匹配的方法:SQL LIKE操作符、SIMILAR TO操作符和POSIX-风格的正则表达式。除了这些基本的操作符外,还有一些函数可用于提取或替换匹配子串并在匹配位置分离一个串。 LIKE 描述:判断字符串是否能匹配上LIKE后的模式字符串。如果字符串与提供的模式匹配,则LIKE表达式返回为真(NOT LIKE表达式返回假),否则返回为假(NOT LIKE表达式返回真)。 匹配规则: 此操作符只有在它的模式匹配整个串的时候才能成功。如果要匹配在串内任何位置的序列,该模式必须以百分号开头和结尾。 下划线 (_)代表(匹配)任何单个字符; 百分号(%)代表任意串的通配符。 要匹配文本里的下划线或者百分号,在提供的模式里相应字符必须前导逃逸字符。逃逸字符的作用是禁用元字符的特殊含义,缺省的逃逸字符是反斜线,也可以用ESCAPE子句指定一个不同的逃逸字符。 要匹配逃逸字符本身,写两个逃逸字符。例如要写一个包含反斜线的模式常量,需要在SQL语句里写两个反斜线。 参数standard_conforming_strings设置为off时,在文串常量中写的任何反斜线都需要被双写。因此,写一个匹配单个反斜线的模式实际上要在语句里写四个反斜线(可以通过用ESCAPE选择一个不同的逃逸字符来避免这种情况,这样反斜线就不再是LIKE的特殊字符了。但仍然是字符文本分析器的特殊字符,所以需要两个反斜线)。 在兼容MYSQL数据模式时,可以通过写ESCAPE ''的方式不选择逃逸字符,这样可以有效地禁用逃逸机制,但是没有办法关闭下划线和百分号在模式中的特殊含义。 关键字ILIKE可以用于替换LIKE,区别是LIKE大小写敏感,ILIKE大小写不敏感。 操作符~~等效于LIKE,操作符~~*等效于ILIKE。 示例: 1 2 3 4 5 gaussdb=# SELECT 'abc' LIKE 'abc' AS RESULT; result ----------- t (1 row) 1 2 3 4 5 gaussdb=# SELECT 'abc' LIKE 'a%' AS RESULT; result ----------- t (1 row) 1 2 3 4 5 gaussdb=# SELECT 'abc' LIKE '_b_' AS RESULT; result ----------- t (1 row) 1 2 3 4 5 gaussdb=# SELECT 'abc' LIKE 'c' AS RESULT; result ----------- f (1 row) SIMILAR TO 描述:SIMILAR TO操作符根据自己的模式是否匹配给定串而返回真或者假。他和LIKE非常类似,只不过他使用SQL标准定义的正则表达式理解模式。 匹配规则: 和LIKE一样,此操作符只有在它的模式匹配整个串的时候才能成功。如果要匹配在串内任何位置的序列,该模式必须以百分号开头和结尾。 下划线 (_)代表(匹配)任何单个字符; 百分号(%)代表任意串的通配符。 SIMILAR TO也支持下面这些从POSIX正则表达式借用的模式匹配元字符。 元字符 含义 | 表示选择(两个候选之一) * 表示重复前面的项零次或更多次 + 表示重复前面的项一次或更多次 ? 表示重复前面的项零次或一次 {m} 表示重复前面的项刚好m次 {m,} 表示重复前面的项m次或更多次 {m,n} 表示重复前面的项至少m次并且不超过n次 () 把多个项组合成一个逻辑项 [...] 声明一个字符类,就像POSIX正则表达式一样 前导逃逸字符可以禁止所有这些元字符的特殊含义。逃逸字符的使用规则和LIKE一样。 正则表达式函数: 支持使用函数substring(string from pattern for escape)截取匹配SQL正则表达式的子字符串。 示例: 1 2 3 4 5 gaussdb=# SELECT 'abc' SIMILAR TO 'abc' AS RESULT; result ----------- t (1 row) 1 2 3 4 5 gaussdb=# SELECT 'abc' SIMILAR TO 'a' AS RESULT; result ----------- f (1 row) 1 2 3 4 5 gaussdb=# SELECT 'abc' SIMILAR TO '%(b|d)%' AS RESULT; result ----------- t (1 row) 1 2 3 4 5 gaussdb=# SELECT 'abc' SIMILAR TO '(b|c)%' AS RESULT; result ----------- f (1 row) POSIX正则表达式 描述:正则表达式是一个字符序列,定义一个串集合(一个正则集)的缩写。 如果一个串是正则表达式描述的正则集中的一员时, 则说明这个串匹配该正则表达式。 POSIX正则表达式提供了比LIKE和SIMILAR TO操作符更强大的含义。表1列出了所有可用于POSIX正则表达式模式匹配的操作符。 表1 正则表达式匹配操作符 操作符 描述 例子 ~ 匹配正则表达式,大小写敏感 'thomas' ~ '.*thomas.*' ~* 匹配正则表达式,大小写不敏感 'thomas' ~* '.*Thomas.*' !~ 不匹配正则表达式,大小写敏感 'thomas' !~ '.*Thomas.*' !~* 不匹配正则表达式,大小写不敏感 'thomas' !~* '.*vadim.*' 匹配规则: 与LIKE不同,正则表达式允许匹配串里的任何位置,除非该正则表达式显式地挂接在串的开头或者结尾。 除了上文提到的元字符外, POSIX正则表达式还支持下列模式匹配元字符。 元字符 含义 ^ 表示串开头的匹配 $ 表示串末尾的匹配 . 匹配任意单个字符 正则表达式函数: POSIX正则表达式支持下面函数。 substring(string from pattern)函数提供了抽取一个匹配POSIX正则表达式模式的子串的方法。 regexp_count(string text, pattern text [, position int [, flags text]])函数提供了获取匹配POSIX正则表达式模式的子串数量的功能。 regexp_instr(string text, pattern text [, position int [, occurrence int [, return_opt int [, flags text]]]])函数提供了获取匹配POSIX正则表达式模式子串位置的功能。 regexp_substr(string text, pattern text [, position int [, occurrence int [, flags text]]])函数提供了抽取一个匹配POSIX正则表达式模式的子串的方法。 regexp_replace(string, pattern, replacement [,flags ])函数提供了将匹配POSIX正则表达式模式的子串替换为新文本的功能。 regexp_matches(string text, pattern text [, flags text])函数返回一个文本数组,该数组由匹配一个POSIX正则表达式模式得到的所有被捕获子串构成。 regexp_split_to_table(string text, pattern text [, flags text])函数把一个POSIX正则表达式模式当作一个定界符来分离一个串。 regexp_split_to_array(string text, pattern text [, flags text ])和regexp_split_to_table类似,是一个正则表达式分离函数,不过它的结果以一个text数组的形式返回。 正则表达式分离函数会忽略零长度的匹配,这种匹配发生在串的开头或结尾或者正好发生在前一个匹配之后。这和正则表达式匹配的严格定义是相悖的,后者由regexp_matches实现,但是通常前者是实际中最常用的行为。 示例: 1 2 3 4 5 gaussdb=# SELECT 'abc' ~ 'Abc' AS RESULT; result -------- f (1 row) 1 2 3 4 5 gaussdb=# SELECT 'abc' ~* 'Abc' AS RESULT; result -------- t (1 row) 1 2 3 4 5 gaussdb=# SELECT 'abc' !~ 'Abc' AS RESULT; result -------- t (1 row) 1 2 3 4 5 gaussdb=# SELECT 'abc'!~* 'Abc' AS RESULT; result -------- f (1 row) 1 2 3 4 5 gaussdb=# SELECT 'abc' ~ '^a' AS RESULT; result -------- t (1 row) 1 2 3 4 5 gaussdb=# SELECT 'abc' ~ '(b|d)'AS RESULT; result -------- t (1 row) 1 2 3 4 5 gaussdb=# SELECT 'abc' ~ '^(b|c)'AS RESULT; result -------- f (1 row) 虽然大部分的正则表达式搜索都能很快地执行,但是仍可能被人为地处理成需要任意长的时间和任意量的内存。不建议从非安全模式来源接受正则表达式搜索模式,如果必须这样做,建议加上语句超时限制。使用SIMILAR TO模式的搜索具有同样的安全性危险, 因为SIMILAR TO提供了很多和POSIX-风格正则表达式相同的能力。LIKE搜索比其他两种选项简单得多,因此在接受非安全模式来源搜索时要更安全些。 父主题: 函数和操作符
  • PG_STAT_USER_TABLES PG_STAT_USER_TABLES视图显示所有命名空间中用户自定义普通表和toast表的状态信息。 表1 PG_STAT_USER_TABLES字段 名称 类型 描述 relid oid 表的OID。 schemaname name 该表的模式名。 relname name 表名。 seq_scan bigint 该表发起的顺序扫描数。 seq_tup_read bigint 顺序扫描抓取的活跃行数。 idx_scan bigint 该表发起的索引扫描数。 idx_tup_fetch bigint 索引扫描抓取的活跃行数。 n_tup_ins bigint 插入行数。 n_tup_upd bigint 更新行数。 n_tup_del bigint 删除行数。 n_tup_hot_upd bigint HOT更新行数(即没有更新所需的单独索引)。 n_live_tup bigint 估计活跃行数。 n_dead_tup bigint 估计不活跃行数。 last_vacuum timestamp with time zone 上次手动清理该表的时间(不计算VACUUM FULL)。 last_autovacuum timestamp with time zone 上次被autovacuum守护线程清理的时间。 last_analyze timestamp with time zone 上次手动分析这个表的时间。 last_autoanalyze timestamp with time zone 上次被autovacuum守护线程分析的时间。 vacuum_count bigint 这个表被手动清理的次数(不计算VACUUM FULL)。 autovacuum_count bigint 这个表被autovacuum清理的次数。 analyze_count bigint 这个表被手动分析的次数。 autoanalyze_count bigint 这个表被autovacuum守护进程分析的次。 last_data_changed timestamp with time zone 这个表数据最近修改时间。 父主题: 系统视图
  • TRANSACTIONS_PREPARED_XACTS 显示当前准备好进行两阶段提交的事务的信息。 表1 TRANSACTIONS_PREPARED_XACTS字段 名称 类型 描述 transaction xid 预备事务的数字事务标识。 gid text 赋予该事务的全局事务标识。 prepared timestamp with time zone 事务准备好提交的时间。 owner name 执行该事务的用户的名称。 database name 执行该事务所在的数据库名。 父主题: Transaction
  • MY_TABLESPA CES MY_TABLESPACES视图显示用户拥有存储对象的表空间的描述信息。默认所有用户都可以访问。该视图同时存在于PG_CATALOG和SYS Schema下。A数据库与GaussDB逻辑结构特性不一致。 表1 MY_TABLESPACES字段 名称 类型 描述 tablespace_name character varying(64) 表空间名称。 block_size numeric 暂不支持,值为NULL。 initial_extent numeric 暂不支持,值为NULL。 next_extent numeric 暂不支持,值为NULL。 min_extents numeric 暂不支持,值为NULL。 max_extents numeric 暂不支持,值为NULL。 max_size numeric 暂不支持,值为NULL。 pct_increase numeric 暂不支持,值为NULL。 min_extlen numeric 暂不支持,值为NULL。 contents character varying(9) 暂不支持,值为NULL。 status character varying(9) 表空间状态,默认为ONLINE(在线)。 logging character varying(9) 暂不支持,值为NULL。 force_logging character varying(3) 暂不支持,值为NULL。 extent_management character varying(10) 暂不支持,值为NULL。 allocation_type character varying(9) 暂不支持,值为NULL。 segment_space_management character varying(6) 暂不支持,值为NULL。 def_tab_compression character varying(8) 暂不支持,值为NULL。 retention character varying(11) 暂不支持,值为NULL。 bigfile character varying(3) 暂不支持,值为NULL。 predicate_evaluation character varying(7) 暂不支持,值为NULL。 encrypted character varying(3) 暂不支持,值为NULL。 compress_for character varying(30) 暂不支持,值为NULL。 def_inmemory character varying(8) 暂不支持,值为NULL。 def_inmemory_priority character varying(8) 暂不支持,值为NULL。 def_inmemory_distribute character varying(15) 暂不支持,值为NULL。 def_inmemory_compression character varying(17) 暂不支持,值为NULL。 def_inmemory_duplicate character varying(13) 暂不支持,值为NULL。 shared character varying(12) 暂不支持,值为NULL。 def_index_compression character varying(8) 暂不支持,值为NULL。 index_compress_for character varying(13) 暂不支持,值为NULL。 def_cellmemory character varying(14) 暂不支持,值为NULL。 def_inmemory_service character varying(12) 暂不支持,值为NULL。 def_inmemory_service_name character varying(1000) 暂不支持,值为NULL。 lost_write_protect character varying(7) 暂不支持,值为NULL。 chunk_tablespace character varying(1) 暂不支持,值为NULL。 父主题: 系统视图
  • MEMORY_NODE_DETAIL 显示当前数据库节点内存使用情况。 表1 MEMORY_NODE_DETAIL字段 名称 类型 描述 nodename text 节点名称。 memorytype text 内存的名称。 max_process_memory:数据库节点可用内存的最大值。 process_used_memory:进程所使用的内存大小。 max_dynamic_memory:最大动态内存。 dynamic_used_memory:已使用的动态内存。 dynamic_peak_memory:内存的动态峰值。 dynamic_used_shrctx:已使用的动态共享内存上下文。 dynamic_peak_shrctx:共享内存上下文的动态峰值。 max_shared_memory:最大共享内存。 shared_used_memory:已使用的共享内存。 max_sctpcomm_memory:TCP代理通信所允许使用的最大内存。 sctpcomm_used_memory:TCP代理通信已使用的内存大小。 sctpcomm_peak_memory:TCP代理通信的内存峰值。 other_used_memory:其他已使用的内存大小。 gpu_max_dynamic_memory:GPU最大动态内存。 gpu_dynamic_used_memory:GPU已使用的动态内存。 gpu_dynamic_peak_memory:GPU内存的动态峰值。 pooler_conn_memory:连接池申请内存计数。 pooler_freeconn_memory:连接池空闲连接的内存计数。 storage_compress_memory:存储模块压缩使用的内存大小。 udf_reserved_memory:UDF预留的内存大小。 memorymbytes integer 内存使用的大小,单位为MB。 父主题: Memory
  • DB_IND_SUBPARTITIONS DB_IND_SUBPARTITIONS视图显示当前用户所能访问的二级分区表Local索引的索引分区信息(不包含分区表全局索引)。所有用户都可以访问。该视图同时存在于PG_CATALOG和SYS Schema下。 表1 DB_IND_SUBPARTITIONS字段 名称 类型 描述 index_owner character varying(64) 索引分区所属分区表索引的所有者的名称。 index_name character varying(64) 索引分区所属分区表索引的名称。 partition_name character varying(64) 索引所在一级分区的名称。 subpartition_name character varying(64) 索引所在二级分区的名称。 def_tablespace_name name 索引分区的表空间名称。 high_value text 索引分区所对应分区的边界值。 index_partition_usable boolean 索引分区是否可用。 t(true):可用。 f(false):不可用。 schema character varying(64) 索引分区所属分区表索引的模式。 high_value_length integer 索引分区所对应分区的边界的字符长度。 partition_position numeric 索引分区在索引中的位置。 subpartition_position numeric 二级分区在分区中的位置。 status character varying(8) 指示索引分区是否可用。 tablespace_name name 索引分区的表空间名称。 pct_free numeric 块中最小可用空间百分比。 ini_trans numeric 初始事务数,默认值为4,非USTORE分区表时为NULL。 max_trans numeric 最大事务数,默认值为128,非USTORE分区表时为NULL。 initial_extent numeric 暂不支持,值为NULL。 next_extent numeric 暂不支持,值为NULL。 min_extent numeric 暂不支持,值为NULL。 max_extent numeric 暂不支持,值为NULL。 max_size numeric 暂不支持,值为NULL。 pct_increase numeric 暂不支持,值为NULL。 freelists numeric 暂不支持,值为NULL。 freelist_groups numeric 暂不支持,值为NULL。 logging character varying(7) 是否记录对索引的更改。 compression character varying(13) 用于二级分区的压缩类型。 blevel numeric 暂不支持,值为NULL。 leaf_blocks numeric 暂不支持,值为NULL。 distinct_keys numeric 暂不支持,值为NULL。 avg_leaf_blocks_per_key numeric 暂不支持,值为NULL。 avg_data_blocks_per_key numeric 暂不支持,值为NULL。 clustering_factor numeric 根据索引的值表示表中行的顺序。需要通过执行analyze进行统计。 num_rows numeric 二级分区中的行数。需要通过执行vacuum进行统计。 sample_size numeric 暂不支持,值为NULL。 last_analyzed timestamp with time zone 最近分析此分区的日期。 buffer_pool character varying(7) 二级分区的缓冲池。 flash_cache character varying(7) 暂不支持,值为NULL。 cell_flash_cache character varying(7) 暂不支持,值为NULL。 user_stats character varying(3) 暂不支持,值为NULL。 global_stats character varying(3) 暂不支持,值为NULL。 interval character varying(3) 分区是否在间隔分区表的间隔节中。 segment_created character varying(3) 索引分区段是否已创建。 domidx_opstatus character varying(6) 暂不支持,值为NULL。 parameters character varying(1000) 暂不支持,值为NULL。 父主题: 系统视图
  • GLOBAL_RECORD_RESET_TIME GLOBAL_RECORD_RESET_TIME用于获取数据库的“重置(重启,主备倒换,数据库删除)时间”的统计信息。 表1 GLOBAL_RECORD_RESET_TIME字段 名称 类型 描述 node_name text 节点名称。 reset_time timestamp with time zone 重置时间点。 父主题: Utility
  • 示例 CREATE PACKAGE SPECIFICATION示例: gaussdb=# CREATE OR REPLACE PACKAGE emp_bonus IS var1 int:=1;--公有变量。 var2 int:=2; PROCEDURE testpro1(var3 int);--公有存储过程,可以被外部调用。 END emp_bonus; / CREATE PACKAGE BODY示例: gaussdb=# drop table if exists test1; gaussdb=# create or replace package body emp_bonus is var3 int:=3; var4 int:=4; procedure testpro1(var3 int) is begin create table if not exists test1(col1 int); insert into test1 values(var1); insert into test1 values(var4); end; begin --实例化开始。 var4:=9; testpro1(var4); end emp_bonus; / ALTER PACKAGE OWNER示例: --将PACKAGE emp_bonus的所属者改为omm。 gaussdb=# ALTER PACKAGE emp_bonus OWNER TO omm; 调用PACKAGE示例: --使用call调用package存储过程。 gaussdb=# call emp_bonus.testpro1(1); --使用select调用package存储过程。 gaussdb=# select emp_bonus.testpro1(1); --匿名块里调用package存储过程。 gaussdb=# begin emp_bonus.testpro1(1); end; /
  • 注意事项 在package specification中声明过的函数或者存储过程,必须在package body中找到定义。 在实例化中,无法调用带有commit/rollback的存储过程。 创建存储过程时,仅对CREATE的存储过程或PACKAGE本身加写锁,仅对执行过程中编译、执行会对函数和函数依赖的PACKAGE均加读锁。 不能在Trigger中调用package函数。 不能在外部SQL中直接使用package当中的变量。 不允许在package外部调用package的私有变量和存储过程。 不支持其它存储过程不支持的用法,例如,在function中不允许调用commit/rollback,则package的function中同样无法调用commit/rollback。 不支持schema与package同名。 只支持A风格的存储过程和函数定义。 不支持package内有同名变量,包括包内同名参数。 package的全局变量为session级,不同session之间package的变量不共享。 package中调用自治事务的函数,不允许使用package中的cursor变量,以及递归的使用package中cursor变量的函数。 package中不支持声明ref cursor变量。 package默认为SECURITY INVOKER权限,如果想将默认行为改为SECURITY DEFINER权限,需要设置guc参数behavior_compat_options='plsql_security_definer'。 被授予CREATE ANY PACKAGE权限的用户,可以在public模式和用户模式下创建PACKAGE。 如果需要创建带有特殊字符的package名,特殊字符中不能含有空格,并且最好设置GUC参数behavior_compat_options="skip_insert_gs_source",否则可能引起报错。 package创建时依赖未定义对象,如参数behavior_compat_options='plpgsql_dependency'打开,创建可执行,通过WARNING提示;如参数未打开,package创建不可执行。 如package中A风格函数已被视图直接依赖,且参数behavior_compat_options='plpgsql_dependency'打开,再次创建包体后视图可正常访问;如参数未打开,视图访问失败。 创建package函数时,其参数默认值不支持含有变量。 包头在PG_OBJECT的类型为'S'(SPECIFICATION简称),包体在PG_OBJECT中的类型为'B'(BODY简称),当创建的PACKAGE对象失效时,可以通过PG_OBJECT中的VALID字段来查找PACKAGE失效对象的OID,并且使用“ALTER PACKAGE PKG_NAME COMPILE”来重新编译PACKAGE,使其有效。 在创建package内的函数时,如果函数名字为schema.func或package.func形式,则只会取func的名字,前面的Schema声明或者Package声明无效,如果需要默认禁用这种行为,可以设置guc参数behavior_compat_options='forbid_package_function_with_prefix'
  • 语法格式 CREATE PACKAGE SPECIFICATION语法格式。 CREATE [ OR REPLACE ] PACKAGE [ schema ] package_name [ invoker_rights_clause ] { IS | AS } item_list_1 END package_name; invoker_rights_clause可以被声明为AUTHID DEFINER或者AUTHID CURRENT_USER,分别为定义者权限和调用者权限。 item_list_1可以为声明的变量或者存储过程以及函数。 PACKAGE SPECIFICATION(包头)声明了包内的公有变量、函数、异常等,可以被外部函数或者存储过程调用。在PACKAGE SPECIFICATION中只能声明存储过程,函数,不能定义存储过程或者函数。 CREATE PACKAGE BODY语法格式。 CREATE [ OR REPLACE ] PACKAGE BODY [ schema ] package_name { IS | AS } declare_section [ initialize_section ] END package_name; PACKAGE BODY(包体内)定义了包的私有变量,函数等。如果变量或者函数没有在PACKAGE SPECIFICATION中声明过,那么这个变量或者函数则为私有变量或者函数。 PACKAGE BODY也可以声明实例化部分,用来初始化package,详见示例。
  • 条件表达式函数 coalesce(expr1, expr2, ..., exprn) 描述: 返回参数列表中第一个非NULL的参数值。 COALESCE(expr1, expr2) 等价于CASE WHEN expr1 IS NOT NULL THEN expr1 ELSE expr2 END。 示例: 1 2 3 4 5 gaussdb=# SELECT coalesce(NULL,'hello'); coalesce ---------- hello (1 row) 备注: 如果表达式列表中的所有表达式都等于NULL,则本函数返回NULL。 它常用于在显示数据时用缺省值替换NULL。 和CASE表达式一样,COALESCE不会计算不需要用来判断结果的参数;即在第一个非空参数右边的参数不会被计算。 decode(base_expr, compare1, value1, Compare2,value2, … default) 描述:把base_expr与后面的每个compare(n) 进行比较,如果匹配返回相应的value(n)。如果没有发生匹配,则返回default。 示例: 1 2 3 4 5 gaussdb=# SELECT decode('A','A',1,'B',2,0); case ------ 1 (1 row) 备注: 不支持对xml数据类型的操作 nullif(expr1, expr2) 描述:当且仅当expr1和expr2相等时,NULLIF才返回NULL,否则它返回expr1。 nullif(expr1, expr2) 逻辑上等价于CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 END。 示例: 1 2 3 4 5 gaussdb=# SELECT nullif('hello','world'); nullif -------- hello (1 row) 备注: 不支持对xml数据类型的操作。 如果两个参数的数据类型不同,则: 若两种数据类型之间存在隐式转换,则以其中优先级较高的数据类型为基准将另一个参数隐式转换成该类型,转换成功则进行计算,转换失败则返回错误。如: 1 2 3 4 5 gaussdb=# SELECT nullif('1234'::VARCHAR,123::INT4); nullif -------- 1234 (1 row) 1 2 gaussdb=# SELECT nullif('1234'::VARCHAR,'2012-12-24'::DATE); ERROR: invalid input syntax for type timestamp: "1234" 若两种数据类型之间不存在隐式转换,则返回错误。如: 1 2 3 4 5 gaussdb=# SELECT nullif(TRUE::BOOLEAN,'2012-12-24'::DATE); ERROR: operator does not exist: boolean = timestamp without time zone LINE 1: SELECT nullif(TRUE::BOOLEAN,'2012-12-24'::DATE) FROM sys_dummy; ^ HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. nvl( expr1 , expr2 ) 描述: 如果expr1为NULL则返回expr2。 如果expr1非NULL,则返回expr1。 示例: 1 2 3 4 5 gaussdb=# SELECT nvl('hello','world'); nvl ------- hello (1 row) 备注:参数expr1和expr2可以为任意类型,当NVL的两个参数不属于同类型时,看第二个参数是否可以向第一个参数进行隐式转换。如果可以则返回第一个参数类型,否则返回错误。 nvl2( expr1 , expr2,expr3 ) 描述: 如果expr1为NULL,则返回expr3。 如果expr1非NULL,则返回expr2。 此函数在参数a_format_version值为10c和a_format_dev_version值为s1的情况下有效。 示例: 1 2 3 4 5 gaussdb=# SELECT nvl2('hello','world','other'); case ------- world (1 row) 备注:参数expr2和expr3可以为任意类型, 当NVL2的后面两个参数不属于同类型时,看expr3参数是否可以向expr2参数进行隐式转换,如果不能隐式转换,会返回错误。如果第一个参数是数值类型,函数在将本参数和其他参数都转换为numeric类型,然后进行比较,对于不能转换的,提示出错信息;第一个参数是其他类型的,函数将其他参数都转换为第一个参数的类型进行比较,对于不能转换的,提示出错信息。 greatest(expr1 [, ...]) 描述:获取并返回参数列表中值最大的表达式的值。 返回值类型: 示例: 1 2 3 4 5 gaussdb=# SELECT greatest(1*2,2-3,4-1); greatest ---------- 3 (1 row) 1 2 3 4 5 gaussdb=# SELECT greatest('HARRY', 'HARRIOT', 'HAROLD'); greatest ---------- HARRY (1 row) 备注: 不支持对xml数据类型的操作。 此函数在参数a_format_version值为10c和a_format_dev_version值为s1的情况下: 如果参数中有任意一个参数的值为null,函数返回null。 如果第一个参数是数值类型,函数将第一个参数和其他参数都转换为numeric类型,然后进行比较,对于不能转换的,提示出错信息;第一个参数是其他类型的,函数将其他参数都转换为第一个参数的类型进行比较,对于不能转换的,提示出错信息。 least(expr1 [, ...]) 描述:获取并返回参数列表中值最小的表达式的值。 示例: 1 2 3 4 5 gaussdb=# SELECT least(1*2,2-3,4-1); least ------- -1 (1 row) 1 2 3 4 5 gaussdb=# SELECT least('HARRY','HARRIOT','HAROLD'); least -------- HAROLD (1 row) 备注: 不支持对xml数据类型的操作。 此函数在参数a_format_version值为10c和a_format_dev_version值为s1的情况下: 如果参数中有任意一个参数的值为null,函数返回null。 如果第一个参数是数值类型,函数将第一个参数和其他参数都转换为numeric类型,然后进行比较,对于不能转换的,提示出错信息;第一个参数是其他类型的,函数将其他参数都转换为第一个参数的类型进行比较,对于不能转换的,提示出错信息。 EMPTY_BLOB() 描述:使用EMPTY_BLOB在INSERT或UPDATE语句中初始化一个BLOB变量,取值为NULL。 返回值类型:BLOB 示例: 1 2 3 4 5 6 --新建表 gaussdb=# CREATE TABLE blob_tb(b blob,id int); --插入数据 gaussdb=# INSERT INTO blob_tb VALUES (empty_blob(),1); --删除表 gaussdb=# DROP TABLE blob_tb; 备注:使用DBE_LOB.GET_LENGTH求得的长度为0。 EMPTY_CLOB() 描述:使用EMPTY_CLOB在INSERT或UPDATE语句中初始化一个CLOB变量,取值为空。 此函数在参数a_format_version值为10c和a_format_dev_version值为s1的情况下有效。 返回值类型:CLOB 示例: 1 2 3 4 5 6 --新建表 gaussdb=# CREATE TABLE clob_tb(c clob,id int); --插入数据 gaussdb=# INSERT INTO clob_tb VALUES (empty_clob(),1); --删除表 gaussdb=# DROP TABLE clob_tb; 备注:使用DBE_LOB.GET_LENGTH求得的长度为0。 lnnvl(condition) 描述:lnnvl用于某个查询语句的where子句中,如果条件为true就返回false,如果条件为unknown或者false,就返回true。 condition:必须为逻辑表达式,但不能用于复合条件如and,or或者between。 返回类型:bool 示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 --新建表 gaussdb=# CREATE TABLE student_demo (name VARCHAR2(20), grade NUMBER(10,2)); CREATE TABLE --插入数据 gaussdb=# INSERT INTO student_demo VALUES ('name0',0); INSERT 0 1 gaussdb=# INSERT INTO student_demo VALUES ('name1',1); INSERT 0 1 gaussdb=# INSERT INTO student_demo VALUES ('name2',2); INSERT 0 1 --调用lnnvl gaussdb=# SELECT * FROM student_demo WHERE LNNVL(name = 'name1'); name | grade -------+------- name0 | 0.00 name2 | 2.00 (2 rows) --删除表 gaussdb=# DROP TABLE student_demo; DROP TABLE 此函数在参数a_format_version值为10c和a_format_dev_version值为s2的情况下生效。
  • javax.naming.Context javax.naming.Context是连接配置的上下文接口。 表1 对javax.naming.Context的支持情况 方法名 返回值类型 支持JDBC 4 bind(Name name, Object obj) void Yes bind(String name, Object obj) void Yes lookup(Name name) Object Yes lookup(String name) Object Yes rebind(Name name, Object obj) void Yes rebind(String name, Object obj) void Yes rename(Name oldName, Name newName) void Yes rename(String oldName, String newName) void Yes unbind(Name name) void Yes unbind(String name) void Yes 父主题: JDBC接口参考
  • 示例 示例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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 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'; gaussdb=# 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操作 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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 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;
  • 参数说明 IF NOT EXISTS 如果已经存在相同名称的表,不会抛出一个错误,而会发出一个通知,告知表关系已存在。 subpartition_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 索引名。 index_name仅在B模式数据库下(即sql_compatibility = 'B')支持,其他模式数据库下不支持。 对于外键约束,constraint_name和index_name同时指定时,索引名为constraint_name。 对于唯一键约束,constraint_name和index_name同时指定时,索引名以index_name。 USING method 指定创建索引的方法。 取值范围参考参数说明中的USING method。 USING method仅在B模式数据库下(即sql_compatibility = 'B')支持,其他模式数据库下不支持。 在B模式下,未指定USING method时,对于ASTORE的存储方式,默认索引方法为btree;对于USTORE的存储方式,默认索引方法为ubtree。 ASC | DESC ASC表示指定按升序排序(默认)。DESC指定按降序排序。 ASC|DESC只在B模式数据库下(即sql_compatibility = 'B')支持,其他模式数据库不支持。 LIKE source_table [ like_option ... ] LIKE子句声明一个表,新表自动从这个表里面继承所有字段名及其数据类型和非空约束。新表与原表之间在创建动作完毕之后是完全无关的。在原表做的任何修改都不会传播到新表中,并且也不可能在扫描原表的时候包含新表的数据。 字段缺省表达式只有在声明了INCLUDING DEFAULTS之后才会包含进来。缺省是不包含缺省表达式的,即新表中所有字段的缺省值都是NULL。 如果指定了INCLUDING GENERATED,则原表列的生成表达式会复制到新表中。默认不复制生成表达式。 非空约束将总是复制到新表中,CHECK约束则仅在指定了INCLUDING CONSTRAINTS的时候才复制,而其他类型的约束则永远也不会被复制。此规则同时适用于表约束和列约束。 被复制的列和约束并不使用相同的名称进行融合。如果明确的指定了相同的名称或者在另外一个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。 该子句仅在参数sql_compatibility='B'时有效。 WITH ( storage_parameter [= value] [, ... ] ) 这个子句为表或索引指定一个可选的存储参数。参数的详细描述如下所示: FILLFACTOR 一个表的填充因子(fillfactor)是一个介于10和100之间的百分数。在Ustore存储引擎下,默认值为92,在Astore存储引擎下默认值为100(完全填充)。如果指定了较小的填充因子,INSERT操作仅按照填充因子指定的百分率填充表页。每个页上的剩余空间将用于在该页上更新行,这就使得UPDATE有机会在同一页上放置同一条记录的新版本,这比把新版本放置在其他页上更有效。对于一个从不更新的表将填充因子设为100是最佳选择,但是对于频繁更新的表,选择较小的填充因子则更加合适。 取值范围:10~100 ORIENTATION 决定了表的数据的存储方式。 取值范围: ROW(缺省值):表的数据将以行式存储。 orientation不支持修改。 STORAGE_TYPE 指定存储引擎类型,该参数设置成功后就不再支持修改。 取值范围: USTORE,表示表支持Inplace-Update存储引擎。特别需要注意,使用USTORE表,必须要开启track_counts和track_activities参数,否则会引起空间膨胀。 ASTORE,表示表支持Append-Only存储引擎。 默认值: 不指定表时,默认是Inplace-Update存储。 COMPRESSION 行存表不支持压缩。 segment 预留参数,暂不支持。 COMPRESS / NOCOMPRESS 创建一个新表时,需要在创建表语句中指定关键字COMPRESS,这样,当对该表进行批量插入时就会触发压缩特性。该特性会在页范围内扫描所有元组数据,生成字典、压缩元组数据并进行存储。指定关键字NOCOMPRESS则不对表进行压缩。行存表不支持压缩。 缺省值为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:行迁移开关关闭。 在打开行迁移开关情况下,并发update、delete操作可能会报错,原因如下: update和delete操作对于旧数据都是标记为已删除。在打开行迁移开关情况下,如果更新分区键时,导致了跨分区更新,内核会把旧分区中旧数据标记为已删除,在新分区中新增加一条数据,无法通过旧数据找到新数据。 在以下三个并发场景下,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表示像普通列一样存储生成列的值。 STORED关键字可省略,与不省略STORED语义相同。 生成表达式不能以任何方式引用当前行以外的其他数据。生成表达式不能引用其他生成列,不能引用系统列。生成表达式不能返回结果集,不能使用子查询,不能使用聚集函数,不能使用窗口函数。生成表达式调用的函数只能是不可变(IMMUTABLE)函数。 不能为生成列指定默认值。 生成列不能作为分区键的一部分。 生成列不能和ON UPDATE约束子句的CASCADE、SET NULL、SET DEFAULT动作同时指定。生成列不能和ON DELETE约束子句的SET NULL、SET DEFAULT动作同时指定。 修改和删除生成列的方法和普通列相同。删除生成列依赖的普通列,生成列被自动删除。不能改变生成列所依赖的列的类型。 生成列不能被直接写入。在INSERT或UPDATE命令中,不能为生成列指定值,但是可以指定关键字DEFAULT。 生成列的权限控制和普通列一样。 AUTO_INCREMENT 指定列为自动增长列。 详见:•AUTO_INCREMENT。 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为空,将使用数据库的缺省表空间。
  • 语法格式 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 ][ 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 ] } [, ...] )][, ...] )[ { 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 ] 表约束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 ] like选项like_option: { INCLUDING | EXCLUDING } { DEFAULTS | GENERATED | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | RELOPTIONS| ALL } 索引存储参数index_parameters: [ WITH ( {storage_parameter = value} [, ... ] ) ] [ USING INDEX TABLESPACE tablespace_name ]
  • 注意事项 二级分区表有两个分区键,每个分区键只能支持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/SUBPARTITION FOR (values)语法,values只能是常量。 对于二级分区表PARTITION/SUBPARTITION FOR (values)语法,values在需要数据类型转换时,建议使用强制类型转换,以防隐式类型转换结果与预期不符。 指定分区语句目前不能走全局索引扫描。
  • 功能描述 创建二级分区表。分区表是把逻辑上的一张表根据某种方案分成几张物理块进行存储,这张逻辑上的表称之为分区表,物理块称之为分区。分区表是一张逻辑表,不存储数据,数据实际是存储在分区上的。对于二级分区表,顶层节点表和一级分区都是逻辑表,不存储数据,只有二级分区(叶子节点)存储数据。 二级分区表的分区方案是由两个一级分区的分区方案组合而来的,一级分区的分区方案详见章节CREATE TABLE PARTITION。 常见的二级分区表组合方案有Range-Range分区、Range-List分区、Range-Hash分区、List-Range分区、List-List分区、List-Hash分区、Hash-Range分区、Hash-List分区、Hash-Hash分区等。目前二级分区仅支持行存表。
  • 语法格式 CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] VIEW view_name [ ( column_name [, ...] ) ] [ WITH ( {view_option_name [= view_option_value]} [, ... ] ) ] AS query; 创建视图时使用WITH(security_barrier)可以创建一个相对安全的视图,避免攻击者利用低成本函数的RAISE语句打印出隐藏的基表数据。 当视图创建后,不允许使用REPLACE修改本视图当中的列名,也不允许删除列。
共100000条
提示

您即将访问非华为云网站,请注意账号财产安全