华为云用户手册

  • 功能描述 创建分区表。分区表是把逻辑上的一张表根据某种方案分成几张物理块进行存储,这张逻辑上的表称之为分区表,物理块称之为分区。分区表是一张逻辑表,不存储数据,数据实际是存储在分区上的。 常见的分区方案有范围分区(Range Partitioning)、哈希分区(Hash Partitioning)、列表分区(List Partitioning)、数值分区(Value Partition)等。目前行存表和列存表仅支持范围分区。 范围分区是根据表的一列或者多列,将要插入表的记录分为若干个范围,这些范围在不同的分区里没有重叠。为每个范围创建一个分区,用来存储相应的数据。 范围分区的分区策略是指记录插入分区的方式。目前范围分区仅支持范围分区策略。 范围分区策略:根据分区键值将记录映射到已创建的某个分区上,如果可以映射到已创建的某一分区上,则把记录插入到对应的分区上,否则给出报错和提示信息。这是最常用的分区策略。 分区可以提供若干好处: 某些类型的查询性能可以得到极大提升。特别是表中访问率较高的行位于一个单独分区或少数几个分区上的情况下。分区可以减少数据的搜索空间,提高数据访问效率。 当查询或更新一个分区的大部分记录时,连续扫描那个分区而不是访问整个表可以获得巨大的性能提升。 如果需要大量加载或者删除的记录位于单独的分区上,则可以通过直接读取或删除那个分区以获得巨大的性能提升,同时还可以避免由于大量DELETE导致的VACUUM超载。
  • 语法格式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 CREATE TABLE [ IF NOT EXISTS ] partition_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 ] [ DISTRIBUTE BY { REPLICATION | { [ HASH ] ( column_name ) } } ] [ TO { GROUP groupname | NODE ( nodename [, ... ] ) } ] PARTITION BY { {RANGE (partition_key) ( partition_less_than_item [, ... ] )} | {RANGE (partition_key) ( partition_start_end_item [, ... ] )} } [ { ENABLE | DISABLE } ROW MOVEMENT ]; 列约束column_constraint: 1 2 3 4 5 6 7 8 [ CONSTRAINT constraint_name ] { NOT NULL | NULL | CHECK ( expression ) | DEFAULT default_expr | UNIQUE [ index_parameters ] | PRIMARY KEY [ index_parameters ] } [ 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 ]} [ DEFERRABLE | NOT DEFERRABLE ][ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] like选项like_option: 1 { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | RELOPTIONS | DISTRIBUTION | ALL } 索引存储参数index_parameters: 1 2 [ WITH ( {storage_parameter = value} [, ... ] ) ] [ USING INDEX TABLESPACE tablespace_name ]
  • 调优手段之统计信息 GaussDB优化器是典型的基于代价的优化 (Cost-Based Optimization,简称CBO)。在这种优化器模型下,数据库根据表的元组数、字段宽度、NULL记录比率、distinct值、MCV值、HB值等表的特征值,以及一定的代价计算模型,计算出每一个执行步骤的不同执行方式的输出元组数和执行代价(cost),进而选出整体执行代价最小/首元组返回代价最小的执行方式进行执行。这些特征值就是统计信息。从上面描述可以看出统计信息是查询优化的核心输入,准确的统计信息将帮助规划器选择最合适的查询规划,一般来说我们通过analyze语法收集整个表或者表的若干个字段的统计信息,周期性地运行ANALYZE,或者在对表的大部分内容做了更改之后马上运行它是个好习惯。
  • 调优手段之GUC参数 查询优化的主要目的是为查询语句选择高效的执行方式。 如下SQL语句: 1 2 select count(1) from customer inner join store_sales on (ss_customer_sk = c_customer_sk); 在执行customer inner join store_sales的时候,GaussDB支持Nested Loop、Merge Join和Hash Join三种不同的Join方式。优化器会根据表customer和表store_sales的统计信息估算结果集的大小以及每种join方式的执行代价,然后对比选出执行代价最小的执行计划。 正如前面所说,执行代价计算都是基于一定的模型和统计信息进行估算,当因为某些原因代价估算不能反映真实的cost的时候,我们就需要通过guc参数设置的方式让执行计划倾向更优规划。
  • 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 --创建同义词t1。 postgres=# CREATE OR REPLACE SYNONYM t1 FOR ot.t1; --创建新用户u1。 postgres=# CREATE USER u1 PASSWORD 'user@111'; --修改同义词t1的owner为u1。 postgres=# ALTER SYNONYM t1 OWNER TO u1; --删除同义词t1。 postgres=# DROP SYNONYM t1; --删除用户u1。 postgres=# DROP USER u1;
  • PG_CLASS PG_CLASS系统表存储数据库对象信息及其之间的关系。 表1 PG_CLASS字段 名称 类型 描述 oid oid 行标识符(隐含字段,必须明确选择)。 relname name 表、索引、视图等对象的名称。 relnamespace oid 包含这个关系的名称空间的OID。 reltype oid 对应这个表的行类型的数据类型(索引为零,因为索引没有pg_type记录)。 reloftype oid 复合类型的OID,0表示其他类型。 relowner oid 关系所有者。 relam oid 如果行是索引,则就是所用的访问模式(B-tree,hash等)。 relfilenode oid 这个关系在磁盘上的文件的名称,如果没有则为0。 reltablespace oid 这个关系存储所在的表空间。如果为零,则意味着使用该数据库的缺省表空间。如果关系在磁盘上没有文件,则这个字段没有什么意义。 relpages double precision 以页(大小为BLCKSZ)为单位的该表在磁盘上的大小,它只是优化器用的一个近似值。 reltuples double precision 表中行的数目,只是优化器使用的一个估计值。 relallvisible integer 被标识为全可见的表中的页的数量。此字段是优化器用来做SQL执行优化使用的。VACUUM、ANALYZE和一些DDL语句(例如,CREATE INDEX)会引起此字段更新。 reltoastrelid oid 与该表关联的TOAST表的OID ,如果没有则为0。 TOAST表在一个从属表里“离线”存储大字段。 reltoastidxid oid 对于TOAST表是它的索引的OID,如果不是TOAST表则为0。 reldeltarelid oid Delta表的OID。 Delta表附属于列存表。用于存储数据导入过程中的甩尾数据。 reldeltaidx oid Delta表的索引表OID。 relcudescrelid oid CU描述表的OID。 CU描述表(Desc表)附属于列存表。用于控制表目录中存储数据的可见性。 relcudescidx oid CU描述表的索引表OID。 relhasindex Boolean 如果它是一个表而且至少有(或者最近有过)一个索引,则为真。 它是由CREATE INDEX设置的,但DROP INDEX不会立即将它清除。如果VACUUM进程检测一个表没有索引,将会把它将清理relhasindex字段,将值设置为假。 relisshared Boolean 如果该表在整个集群中由所有数据库共享则为真,否则为假。只有某些系统表(比如pg_database)是共享的。 relpersistence "char" p:表示永久表。 u:表示非日志表。 t:表示临时表。 relkind "char" r:表示普通表。 i:表示索引。 S:表示序列。 v:表示视图。 c:表示复合类型。 t:表示TOAST表。 f:表示外表。 m:表示物化视图。 e:表示STREAM对象。 o:表示CONTVIEW对象。 relnatts smallint 关系中用户字段数目(除了系统字段以外)。在pg_attribute里肯定有相同数目对应行。 relchecks smallint 表里的检查约束的数目;参阅pg_constraint表。 relhasoids Boolean 如果为关系中每行都生成一个OID则为真,否则为假。 relhaspkey Boolean 如果这个表有一个(或者曾经有一个)主键,则为真。否则为假。 relhasrules Boolean 如表有规则就为真。是否有规则可参考系统表PG_REWRITE。 relhastriggers Boolean True表示表中有触发器,或者曾经有过触发器。系统表pg_trigger中记录了表和视图的触发器。 relhassubclass Boolean 如果有(或者曾经有)任何继承的子表,为真。否则为假。 relcmprs tinyint 表示是否启用表的启用压缩特性。需要特别注意,当且仅当批量插入才会触发压缩,普通的CRUD并不能够触发压缩。 0表示其他不支持压缩的表(主要是指系统表,不支持压缩属性的修改操作)。 1表示表数据的压缩特性为NOCOMPRESS或者无指定关键字。 2表示表数据的压缩特性为COMPRESS。 relhasclusterkey Boolean 是否有局部聚簇存储。 true:表示有。 false:表示没有。 relrowmovement Boolean 针对分区表进行update操作时,是否允许行迁移。 true:表示允许行迁移。 false:表示不允许行迁移。 parttype "char" 表或者索引是否具有分区表的性质。 p:表示带有分区表性质。 n:表示没有分区表特性。 relfrozenxid xid32 该表中所有在这个之前的事务ID已经被一个固定的("frozen")事务ID替换。该字段用于跟踪该表是否需要为了防止事务ID重叠(或者允许收缩pg_clog)而进行清理。如果该关系不是表则为零(InvalidTransactionId)。 为保持前向兼容,保留此字段,新增relfrozenxid64用于记录此信息。 relacl aclitem[] 访问权限。 查询的回显结果为以下形式: 1 rolename=xxxx/yyyy --赋予一个角色的权限 1 =xxxx/yyyy --赋予public的权限 xxxx表示赋予的权限,yyyy表示授予这个权限的角色。权限的参数说明请参见表2。 reloptions text[] 索引的访问方法,使用"keyword=value"格式的字符串。 relreplident "char" 逻辑解码中解码列的标识: d = 默认 (主键,如果存在)。 n = 无。 f = 所有列。 i = 索引的indisreplident被设置或者为默认。 relfrozenxid64 xid 该表中所有在这个之前的事务ID已经被一个固定的("frozen")事务ID替换。该字段用于跟踪该表是否需要为了防止事务ID重叠(或者允许收缩pg_clog)而进行清理。如果该关系不是表则为零(InvalidTransactionId)。 relbucket oid 当前表是否包含hash bucket分片。有效的OID指向pg_hashbucket表中记录的具体分片信息。NULL表示不包含hash bucket分片。 relbucketkey int2vector 表示hash分区列信息,NULL表示不包含。 表2 权限的参数说明 参数 参数说明 r SELECT(读) w UPDATE(写) a INSERT(插入) d DELETE D TRUNCATE x REFERENCES t TRIGGER X EXECUTE U USAGE C CREATE c CONNECT T TEMPORARY A ALTER P DROP m COMMENT i INDEX v VACUUM * 给前面权限的授权选项 父主题: 系统表
  • OPEN FOR 动态查询语句还可以使用OPEN FOR打开动态游标来执行。 语法参见图3。 图3 open_for::= 参数说明: cursor_name:要打开的游标名。 dynamic_string:动态查询语句。 USING value:在dynamic_string中存在占位符时使用。 游标的使用请参考游标。 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 postgres=# DECLARE name VARCHAR2(20); phone_number VARCHAR2(20); salary NUMBER(8,2); sqlstr VARCHAR2(1024); TYPE app_ref_cur_type IS REF CURSOR; --定义游标类型 my_cur app_ref_cur_type; --定义游标变量 BEGIN sqlstr := 'select first_name,phone_number,salary from hr.staffs where section_id = :1'; OPEN my_cur FOR sqlstr USING '30'; --打开游标, using是可选的 FETCH my_cur INTO name, phone_number, salary; --获取数据 WHILE my_cur%FOUND LOOP dbe_output.print_line(name||'#'||phone_number||'#'||salary); FETCH my_cur INTO name, phone_number, salary; END LOOP; CLOSE my_cur; --关闭游标 END; /
  • EXECUTE IMMEDIATE 语法图请参见图1。 图1 EXECUTE IMMEDIATE dynamic_select_clause::= using_clause子句的语法图参见图2。 图2 using_clause::= 对以上语法格式的解释如下: define_variable,用于指定存放单行查询结果的变量。 USING IN bind_argument,用于指定存放传递给动态SQL值的变量,即在dynamic_select_string中存在占位符时使用。 USING OUT bind_argument,用于指定存放动态SQL返回值的变量。 查询语句中,into和out不能同时存在; 占位符命名以“:”开始,后面可跟数字、字符或字符串,与USING子句的bind_argument一一对应; bind_argument只能是值、变量或表达式,不能是表名、列名、数据类型等数据库对象,即不支持使用bind_argument为动态SQL语句传递模式对象。如果存储过程需要通过声明参数传递数据库对象来构造动态SQL语句(常见于执行DDL语句时),建议采用连接运算符“||”拼接dynamic_select_clause; 动态PL/SQL块允许出现重复的占位符,即相同占位符只能与USING子句的一个bind_argument按位置对应。 示例 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 --从动态语句检索值(INTO 子句): postgres=# DECLARE staff_count VARCHAR2(20); BEGIN EXECUTE IMMEDIATE 'select count(*) from hr.staffs' INTO staff_count; dbe_output.print_line(staff_count); END; / --传递并检索值(INTO子句用在USING子句前): postgres=# CREATE OR REPLACE PROCEDURE dynamic_proc AS staff_id NUMBER(6) := 200; first_name VARCHAR2(20); salary NUMBER(8,2); BEGIN EXECUTE IMMEDIATE 'select first_name, salary from hr.staffs where staff_id = :1' INTO first_name, salary USING IN staff_id; dbe_output.print_line(first_name || ' ' || salary); END; / --调用存储过程 postgres=# CALL dynamic_proc(); --删除存储过程 postgres=# DROP PROCEDURE dynamic_proc;
  • 伪类型 GaussDB数据类型中包含一系列特殊用途的类型,这些类型按照类别被称为伪类型。伪类型不能作为字段的数据类型,但是可以用于声明函数的参数或者结果类型。 当一个函数不仅是简单地接受并返回某种SQL数据类型的情况下伪类型是很有用的。表1列出了所有的伪类型。 表1 伪类型 名称 描述 any 表示函数接受任何输入数据类型。 anyelement 表示函数接受任何数据类型。 anyarray 表示函数接受任意数组数据类型。 anynonarray 表示函数接受任意非数组数据类型。 anyenum 表示函数接受任意枚举数据类型。 anyrange 表示函数接受任意范围数据类型。 cstring 表示函数接受或者返回一个空结尾的C字符串。 internal 表示函数接受或者返回一种服务器内部的数据类型。 language_handler 声明一个过程语言调用句柄返回language_handler。 fdw_handler 声明一个外部数据封装器返回fdw_handler。 record 标识函数返回一个未声明的行类型。 trigger 声明一个触发器函数返回trigger。 void 表示函数不返回数值。 opaque 一个已经过时的类型,以前用于所有上面这些用途。 声明用C编写的函数(不管是内置的还是动态装载的)都可以接受或者返回任何这样的伪数据类型。当伪类型作为参数类型使用时,用户需要保证函数的正常运行。 用过程语言编写的函数只能使用实现语言允许的伪类型。目前,过程语言都不允许使用作为参数类型的伪类型,并且只允许使用void和record作为结果类型。一些多态的函数还支持使用anyelement,anyarray,anynonarray anyenum和anyrange类型。 伪类型internal用于声明那种只能在数据库系统内部调用的函数,他们不能直接在SQL查询里调用。如果函数至少有一个internal类型的参数,则不能从SQL里调用他。建议不要创建任何声明返回internal的函数,除非他至少有一个internal类型的参数。 示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 --创建表 postgres=# create table t1 (a int); --插入两条数据 postgres=# insert into t1 values(1),(2); --创建函数showall()。 postgres=# CREATE OR REPLACE FUNCTION showall() RETURNS SETOF record AS $$ SELECT count(*) from t1; $$ LANGUAGE SQL; --调用函数showall()。 postgres=# SELECT showall(); showall --------- (2) (1 row) --删除函数。 postgres=# DROP FUNCTION showall(); --删除表 postgres=# drop table t1; 父主题: 数据类型
  • 二进制类型 GaussDB支持的二进制类型请参见表1。 表1 二进制类型 名称 描述 存储空间 BLOB 二进制大对象 目前BLOB支持的外部存取接口仅为: DBE_LOB.GET_LENGTH DBE_LOB.READ DBE_LOB.WRITE DBE_LOB.WRITE_APPEND DBE_LOB.COPY DBE_LOB.ERASE 这些接口详细说明请参见DBE_LOB。 说明: 列存不支持BLOB类型 最大为1GB减去6字节(即1073741818字节)。 RAW 变长的十六进制类型 说明: 列存不支持RAW类型 4字节加上实际的十六进制字符串。最大为1GB减去6字节(即1073741818字节)。 BYTEA 变长的二进制字符串 最大为1GB减去(56+24+5+前n列总字节数)。比如表为(a int, b bytea); 最长存储为1GB – 56 – 24 -5 – 4(int) = 1073741735 BYTEAWITHOUTORDERWITHEQUALCOL 变长的二进制字符串(密态特性新增的类型,如果加密列的加密类型指定为确定性加密,则该列的类型为BYTEAWITHOUTORDERWITHEQUALCO) 4字节加上实际的二进制字符串。最大为1GB减去53字节(即1073741771字节)。 BYTEAWITHOUTORDERCOL 变长的二进制字符串(密态特性新增的类型,如果加密列的加密类型指定为随机加密,则该列的类型为BYTEAWITHOUTORDERCOL) 4字节加上实际的二进制字符串。最大为1GB减去53字节(即1073741771字节)。 _BYTEAWITHOUTORDERWITHEQUALCOL 变长的二进制字符串,密态特性新增的类型 4字节加上实际的二进制字符串。最大为1GB减去53字节(即1073741771字节)。 _BYTEAWITHOUTORDERCOL 变长的二进制字符串,密态特性新增的类型 4字节加上实际的二进制字符串。最大为1GB减去53字节(即1073741771字节)。 除了每列的大小限制以外,每个元组的总大小也不可超过1GB-53字节(即1073741771字节)。 不支持直接使用BYTEAWITHOUTORDERWITHEQUALCOL和BYTEAWITHOUTORDERCOL,_BYTEAWITHOUTORDERWITHEQUALCOL,_BYTEAWITHOUTORDERCOL类型创建表。 示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 --创建表。 postgres=# CREATE TABLE blob_type_t1 ( BT_COL1 INTEGER, BT_COL2 BLOB, BT_COL3 RAW, BT_COL4 BYTEA ) DISTRIBUTE BY REPLICATION; --插入数据。 postgres=# INSERT INTO blob_type_t1 VALUES(10,empty_blob(), HEXTORAW('DEADBEEF'),E'\\xDEADBEEF'); --查询表中的数据。 postgres=# SELECT * FROM blob_type_t1; bt_col1 | bt_col2 | bt_col3 | bt_col4 ---------+---------+----------+------------ 10 | | DEADBEEF | \xdeadbeef (1 row) --删除表。 postgres=# DROP TABLE blob_type_t1; 父主题: 数据类型
  • 参数说明 WITH [ RECURSIVE ] with_query [, ...] 用于声明一个或多个可以在主查询中通过名称引用的子查询,相当于临时表。 如果声明了RECURSIVE,那么允许SELECT子查询通过名称引用它自己。 其中with_query的详细格式为:with_query_name [ ( column_name [, ...] ) ] AS ( {select | values | insert | update | delete} ) with_query_name指定子查询生成的结果集名称,在查询中可使用该名称访问子查询的结果集。 column_name指定子查询结果集中显示的列名。 每个子查询可以是SELECT,VALUES,INSERT,UPDATE或DELETE语句。 plan_hint子句 以/*+ */的形式在SELECT关键字后,用于对SELECT对应的语句块生成的计划进行hint调优,详细用法请参见章节使用Plan Hint进行调优。每条语句中只有第一个/*+ plan_hint */注释块会作为hint生效,里面可以写多条hint。 ALL 声明返回所有符合条件的行,是默认行为,可以省略该关键字。 DISTINCT [ ON ( expression [, ...] ) ] 从SELECT的结果集中删除所有重复的行,使结果集中的每行都是唯一的。 ON ( expression [, ...] ) 只保留那些在给出的表达式上运算出相同结果的行集合中的第一行。 DISTINCT ON表达式是使用与ORDER BY相同的规则进行解释的。除非使用了ORDER BY来保证需要的行首先出现,否则,"第一行" 是不可预测的。 SELECT列表 指定查询表中列名,可以是部分列或者是全部(使用通配符*表示)。 通过使用子句AS output_name可以为输出字段取个别名,这个别名通常用于输出字段的显示。支持关键字name、value和type作为列别名。 列名可以用下面几种形式表达: 手动输入列名,多个列之间用英文逗号(,)分隔。 可以是FROM子句里面计算出来的字段。 FROM子句 为SELECT声明一个或者多个源表。 FROM子句涉及的元素如下所示。 table_name 表名或视图名,名称前可加上模式名,如:schema_name.table_name。 alias 给表或复杂的表引用起一个临时的表别名,以便被其余的查询引用。 别名用于缩写或者在自连接中消除歧义。如果提供了别名,它就会完全代替表的实际名称。 TABLESAMPLE sampling_method ( argument [, ...] ) [ REPEATABLE ( seed ) ] table_name之后的TABLESAMPLE子句表示应该用指定的sampling_method来检索表中行的子集。 可选的REPEATABLE子句指定一个用于产生采样方法中随机数的种子数。种子值可以是任何非空常量值。如果查询时表没有被更改,指定相同种子和argument值的两个查询将会选择该表相同的采样。但是不同的种子值通常将会产生不同的采样。如果没有给出REPEATABLE,则会基于一个系统产生的种子为每一个查询选择一个新的随机采样。 column_alias 列别名 PARTITION 查询分区表的某个分区的数据。 partition_name 分区名。 partition_value 指定的分区键值。在创建分区表时,如果指定了多个分区键,可以通过PARTITION FOR子句指定的这一组分区键的值,唯一确定一个分区。 subquery FROM子句中可以出现子查询,创建一个临时表保存子查询的输出。 with_query_name WITH子句同样可以作为FROM子句的源,可以通过WITH查询的名称对其进行引用。 function_name 函数名称。函数调用也可以出现在FROM子句中。 join_type 有5种类型,如下所示。 [ INNER ] JOIN 一个JOIN子句组合两个FROM项。可使用圆括弧以决定嵌套的顺序。如果没有圆括弧,JOIN从左向右嵌套。 在任何情况下,JOIN都比逗号分隔的FROM项绑定得更紧。 LEFT [ OUTER ] JOIN 返回笛卡尔积中所有符合连接条件的行,再加上左表中通过连接条件没有匹配到右表行的那些行。这样,左边的行将扩展为生成表的全长,方法是在那些右表对应的字段位置填上NULL。请注意,只在计算匹配的时候,才使用JOIN子句的条件,外层的条件是在计算完毕之后施加的。 RIGHT [ OUTER ] JOIN 返回所有内连接的结果行,加上每个不匹配的右边行(左边用NULL扩展)。 这只是一个符号上的方便,因为总是可以把它转换成一个LEFT OUTER JOIN,只要把左边和右边的输入互换位置即可。 FULL [ OUTER ] JOIN 返回所有内连接的结果行,加上每个不匹配的左边行(右边用NULL扩展),再加上每个不匹配的右边行(左边用NULL扩展)。 CROSS JOIN CROSS JOIN等效于INNER JOIN ON(TRUE) ,即没有被条件删除的行。这种连接类型只是符号上的方便,因为它们与简单的FROM和WHERE的效果相同。 必须为INNER和OUTER连接类型声明一个连接条件,即NATURAL ON,join_condition,USING (join_column [, ...]) 之一。但是它们不能出现在CROSS JOIN中。 其中CROSS JOIN和INNER JOIN生成一个简单的笛卡尔积,和在FROM的顶层列出两个项的结果相同。 ON join_condition 连接条件,用于限定连接中的哪些行是匹配的。如:ON left_table.a = right_table.a。 USING(join_column[,...]) ON left_table.a = right_table.a AND left_table.b = right_table.b ... 的简写。要求对应的列必须同名。 NATURAL NATURAL是具有相同名称的两个表的所有列的USING列表的简写。 from item 用于连接的查询源对象的名称。 WHERE子句 WHERE子句构成一个行选择表达式,用来缩小SELECT查询的范围。condition是返回值为布尔型的任意表达式,任何不满足该条件的行都不会被检索。 WHERE子句中可以通过指定"(+)"操作符的方法将表的连接关系转换为外连接。但是不建议用户使用这种用法,因为这并不是SQL的标准语法,在做平台迁移的时候可能面临语法兼容性的问题。同时,使用"(+)"有很多限制: "(+)"只能出现在where子句中。 如果from子句中已经有指定表连接关系,那么不能再在where子句中使用"(+)"。 "(+)"只能作用在表或者视图的列上,不能作用在表达式上。 如果表A和表B有多个连接条件,那么必须在所有的连接条件中指定"(+)",否则"(+)"将不会生效,表连接会转化成内连接,并且不给出任何提示信息。 "(+)"作用的连接条件中的表不能跨查询或者子查询。如果"(+)"作用的表,不在当前查询或者子查询的from子句中,则会报错。如果"(+)"作用的对端的表不存在,则不报错,同时连接关系会转化为内连接。 "(+)"作用的表达式不能直接通过"OR"连接。 如果"(+)"作用的列是和一个常量的比较关系, 那么这个表达式会成为join条件的一部分。 同一个表不能对应多个外表。 "(+)"只能出现"比较表达式","NOT表达式",“ANY表达式”,“ALL表达式”,“IN表达式”,“NULLIF表达式”,“IS DISTINCT FROM表达式”,“IS OF”表达式。"(+)"不能出现在其他类型表达式中,并且这些表达式中不允许出现通过“AND”和“OR”连接的表达式。 "(+)"只能转化为左外连接或者右外连接,不能转化为全连接,即不能在一个表达式的两个表上同时指定"(+)" 对于WHERE子句的LIKE操作符,当LIKE中要查询特殊字符“%”、“_”、“\”的时候需要使用反斜杠“\”来进行转义。 GROUP BY子句 将查询结果按某一列或多列的值分组,值相等的为一组。 CUBE ( { expression | ( expression [, ...] ) } [, ...] ) CUBE是自动对group by子句中列出的字段进行分组汇总,结果集将包含维度列中各值的所有可能组合,以及与这些维度值组合相匹配的基础行中的聚合值。它会为每个分组返回一行汇总信息, 用户可以使用CUBE来产生交叉表值。比如,在CUBE子句中给出三个表达式(n = 3),运算结果为2n = 23 = 8组。 以n个表达式的值分组的行称为常规行,其余的行称为超级聚集行。 GROUPING SETS ( grouping_element [, ...] ) GROUPING SETS子句是GROUP BY子句的进一步扩展,它可以使用户指定多个GROUP BY选项。 这样做可以通过裁剪用户不需要的数据组来提高效率。 当用户指定了所需的数据组时,数据库不需要执行完整CUBE或ROLLUP生成的聚合集合。 如果SELECT列表的表达式中引用了那些没有分组的字段,则会报错,除非使用了聚集函数,因为对于未分组的字段,可能返回多个数值。 HAVING子句 与GROUP BY子句配合用来选择特殊的组。HAVING子句将组的一些属性与一个常数值比较,只有满足HAVING子句中的逻辑表达式的组才会被提取出来。 WINDOW子句 一般形式为WINDOW window_name AS ( window_definition ) [, ...],window_name是可以被随后的窗口定义所引用的名称,window_definition可以是以下的形式: [ existing_window_name ] [ PARTITION BY expression [, ...] ] [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ] [ frame_clause ] frame_clause为窗函数定义一个窗口框架window frame,窗函数(并非所有)依赖于框架,window frame是当前查询行的一组相关行。frame_clause可以是以下的形式: [ RANGE | ROWS ] frame_start [ RANGE | ROWS ] BETWEEN frame_start AND frame_end frame_start和frame_end可以是: UNBOUNDED PRECEDING value PRECEDING CURRENT ROW value FOLLOWING UNBOUNDED FOLLOWING 对列存表的查询目前只支持row_number窗口函数,不支持frame_clause。 UNION子句 UNION计算多个SELECT语句返回行集合的并集。 UNION子句有如下约束条件: 除非声明了ALL子句,否则缺省的UNION结果不包含重复的行。 同一个SELECT语句中的多个UNION操作符是从左向右计算的,除非用圆括弧进行了标识。 FOR UPDATE不能在UNION的结果或输入中声明。 一般表达式: select_statement UNION [ALL] select_statement select_statement可以是任何没有ORDER BY、LIMIT、FOR UPDATE子句的SELECT语句。 如果用圆括弧包围,ORDER BY和LIMIT可以附着在子表达式里。 INTERSECT子句 INTERSECT计算多个SELECT语句返回行集合的交集,不含重复的记录。 INTERSECT子句有如下约束条件: 同一个SELECT语句中的多个INTERSECT操作符是从左向右计算的,除非用圆括弧进行了标识。 当对多个SELECT语句的执行结果进行UNION和INTERSECT操作的时候,会优先处理INTERSECT。 一般形式: select_statement INTERSECT select_statement select_statement可以是任何没有FOR UPDATE子句的SELECT语句。 EXCEPT子句 EXCEPT子句有如下的通用形式: select_statement EXCEPT [ ALL ] select_statement select_statement是任何没有FOR UPDATE子句的SELECT表达式。 EXCEPT操作符计算存在于左边SELECT语句的输出而不存在于右边SELECT语句输出的行。 EXCEPT的结果不包含任何重复的行,除非声明了ALL选项。使用ALL时,一个在左边表中有m个重复而在右边表中有n个重复的行将在结果中出现max(m-n,0) 次。 除非用圆括弧指明顺序,否则同一个SELECT语句中的多个EXCEPT操作符是从左向右计算的。EXCEPT和UNION的绑定级别相同。 目前,不能给EXCEPT的结果或者任何EXCEPT的输入声明FOR UPDATE子句。 MINUS子句 与EXCEPT子句具有相同的功能和用法。 ORDER BY子句 对SELECT语句检索得到的数据进行升序或降序排序。对于ORDER BY表达式中包含多列的情况: 首先根据最左边的列进行排序,如果这一列的值相同,则根据下一个表达式进行比较,依此类推。 如果对于所有声明的表达式都相同,则按随机顺序返回。 ORDER BY中排序的列必须包括在SELECT语句所检索的结果集的列中。 如果要支持中文拼音排序和不区分大小写排序,需要在初始化数据库时指定编码格式为UTF-8或GBK。 命令如下: initdb –E UTF8 –D ../data –locale=zh_CN.UTF-8或initdb –E GBK –D ../data –locale=zh_CN.GBK。 LIMIT子句 LIMIT子句由两个独立的子句组成: LIMIT { count | ALL } OFFSET start count声明返回的最大行数,而start声明开始返回行之前忽略的行数。如果两个都指定了,会在开始计算count个返回行之前先跳过start行。 OFFSET子句 SQL:2008开始提出一种不同的语法: OFFSET start { ROW | ROWS } start声明开始返回行之前忽略的行数。 FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY 如果不指定count,默认值为1,FETCH子句限定返回查询结果从第一行开始的总行数。 FOR UPDATE子句 FOR UPDATE子句将对SELECT检索出来的行进行加锁。这样避免它们在当前事务结束前被其他事务修改或者删除,即其他企图UPDATE、 DELETE、 SELECT FOR UPDATE这些行的事务将被阻塞,直到当前事务结束。 为了避免操作等待其他事务提交,可使用NOWAIT选项,如果被选择的行不能立即被锁住,执行SELECT FOR UPDATE NOWAIT将会立即汇报一个错误,而不是等待。 FOR SHARE的行为类似,只是它在每个检索出来的行上要求一个共享锁,而不是一个排他锁。一个共享锁阻塞其它事务执行UPDATE、DELETE、SELECT,不阻塞SELECT FOR SHARE。 如果在FOR UPDATE或FOR SHARE中明确指定了表名称,则只有这些指定的表被锁定,其他在SELECT中使用的表将不会被锁定。否则,将锁定该命令中所有使用的表。 如果FOR UPDATE或FOR SHARE应用于一个视图或者子查询,它同样将锁定所有该视图或子查询中使用到的表。 多个FOR UPDATE和FOR SHARE子句可以用于为不同的表指定不同的锁定模式。 如果一个表中同时出现(或隐含同时出现)在FOR UPDATE和FOR SHARE子句中,则按照FOR UPDATE处理。类似的,如果影响一个表的任意子句中出现了NOWAIT,该表将按照NOWAIT处理。 对于for update/share,执行计划不能下推的SQL,直接返回报错信息;对于执行计划可以下推的,下推到DN执行。 对列存表的查询不支持for update/share。 NLS_SORT 指定某字段按照特殊方式排序。目前仅支持中文拼音格式排序和不区分大小写排序。 取值范围: SCHINESE_PINYIN_M,按照中文拼音排序。如果要支持此排序方式,在创建数据库时需要指定编码格式为“GBK”,否则排序无效。 generic_m_ci,不区分大小写排序。 PARTITION子句 查询某个分区表中相应分区的数据。
  • 语法格式 查询数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 [ WITH [ RECURSIVE ] with_query [, ...] ] SELECT [/*+ plan_hint */] [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] { * | {expression [ [ AS ] output_name ]} [, ...] } [ FROM from_item [, ...] ] [ WHERE condition ] [ GROUP BY grouping_element [, ...] ] [ HAVING condition [, ...] ] [ WINDOW {window_name AS ( window_definition )} [, ...] ] [ { UNION | INTERSECT | EXCEPT | MINUS } [ ALL | DISTINCT ] select ] [ ORDER BY {expression [ [ ASC | DESC | USING operator ] | nlssort_expression_clause ] [ NULLS { FIRST | LAST } ]} [, ...] ] [ LIMIT { [offset,] count | ALL } ] [ OFFSET start [ ROW | ROWS ] ] [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ] [ {FOR { UPDATE | SHARE } [ OF table_name [, ...] ] [ NOWAIT ]} [...] ]; condition和expression中可以使用targetlist中表达式的别名。 只能同一层引用。 只能引用targetlist中的别名。 只能是后面的表达式引用前面的表达式。 不能包含volatile函数。 不能包含Window function函数。 不支持在join on条件中引用别名。 targetlist中有多个要应用的别名则报错。 其中子查询with_query为: 1 2 with_query_name [ ( column_name [, ...] ) ] AS ( {select | values | insert | update | delete} ) 其中指定查询源from_item为: 1 2 3 4 5 6 7 {[ ONLY ] table_name [ * ] [ partition_clause ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ] [ TABLESAMPLE sampling_method ( argument [, ...] ) [ REPEATABLE ( seed ) ] ] |( select ) [ AS ] alias [ ( column_alias [, ...] ) ] |with_query_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ] |function_name ( [ argument [, ...] ] ) [ AS ] alias [ ( column_alias [, ...] | column_definition [, ...] ) ] |function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] ) |from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ]} 其中group子句为: 1 2 3 4 5 6 ( ) | expression | ( expression [, ...] ) | ROLLUP ( { expression | ( expression [, ...] ) } [, ...] ) | CUBE ( { expression | ( expression [, ...] ) } [, ...] ) | GROUPING SETS ( grouping_element [, ...] ) 其中指定分区partition_clause为: 1 2 PARTITION { ( partition_name ) | FOR ( partition_value [, ...] ) } 指定分区只适合普通表。 其中设置排序方式nlssort_expression_clause为: 1 NLSSORT ( column_name, ' NLS_SORT = { SCHINESE_PINYIN_M | generic_m_ci } ' ) 简化版查询语法,功能相当于select * from table_name。 1 TABLE { ONLY {(table_name)| table_name} | table_name [ * ]};
  • 参数 表1 SQLColAttribute参数 关键字 参数说明 StatementHandle 语句句柄。 ColumnNumber 要检索字段的列号,起始为1,依次递增。 FieldIdentifier IRD中ColumnNumber行的字段。 CharacterAttributePtr 输出参数:一个缓冲区指针,返回FieldIdentifier字段值。 BufferLength 如果FieldIdentifier是一个ODBC定义的字段,而且CharacterAttributePtr指向一个字符串或二进制缓冲区,则此参数为该缓冲区的长度。 如果FieldIdentifier是一个ODBC定义的字段,而且CharacterAttributePtr指向一个整数,则会忽略该字段。 StringLengthPtr 输出参数:缓冲区指针,存放*CharacterAttributePtr中字符类型数据的字节总数,对于非字符类型,忽略BufferLength的值。 NumericAttributePtr 输出参数:指向一个整型缓冲区的指针,返回IRD中ColumnNumber行FieldIdentifier字段的值。
  • 原型 1 2 3 4 5 6 7 SQLRETURN SQLColAttibute(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLUSMALLINT FieldIdentifier, SQLPOINTER CharacterAtrriburePtr, SQLSMALLINT BufferLength, SQLSMALLINT *StringLengthPtr, SQLPOINTE NumericAttributePtr);
  • 语法格式 1 CREATE USER user_name [ [ WITH ] option [ ... ] ] [ ENCRYPTED | UNENCRYPTED ] { PASSWORD | IDENTIFIED BY } { 'password' [EXPIRED] | DISABLE }; 其中option子句用于设置权限及属性等信息。 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 {SYSADMIN | NOSYSADMIN} | {MONADMIN | NOMONADMIN} | {OPRADMIN | NOOPRADMIN} | {POLADMIN | NOPOLADMIN} | {AUDITADMIN | NOAUDITADMIN} | {CREATEDB | NOCREATEDB} | {USEFT | NOUSEFT} | {CREATEROLE | NOCREATEROLE} | {INHERIT | NOINHERIT} | {LOGIN | NOLOGIN} | {REPLICATION | NOREPLICATION} | {INDEPENDENT | NOINDEPENDENT} | {VCADMIN | NOVCADMIN} | {PERSISTENCE | NOPERSISTENCE} | CONNECTION LIMIT connlimit | VALID BEGIN 'timestamp' | VALID UNTIL 'timestamp' | RESOURCE POOL 'respool' | USER GROUP 'groupuser' | PERM SPACE 'spacelimit' | TEMP SPACE 'tmpspacelimit' | SPILL SPACE 'spillspacelimit' | NODE GROUP logic_cluster_name | IN ROLE role_name [, ...] | IN GROUP role_name [, ...] | ROLE role_name [, ...] | ADMIN role_name [, ...] | USER role_name [, ...] | SYSID uid | DEFAULT TABLESPACE tablespace_name | PROFILE DEFAULT | PROFILE profile_name | PGUSER
  • 示例 --创建用户jim,登录密码为xxxxxxxxxx。 postgres=# CREATE USER jim PASSWORD 'xxxxxxxxxx'; --下面语句与上面的等价。 postgres=# CREATE USER kim IDENTIFIED BY 'xxxxxxxxxxx'; --如果创建有“创建数据库”权限的用户,则需要加CREATEDB关键字。 postgres=# CREATE USER dim CREATEDB PASSWORD 'xxxxxxxxxxx'; --将用户jim的登录密码由xxxxxxxxxxx修改为Abcd@123。 postgres=# ALTER USER jim IDENTIFIED BY 'Abcd@123' REPLACE 'xxxxxxxxxx'; --为用户jim追加CREATEROLE权限。 postgres=# ALTER USER jim CREATEROLE; --锁定jim帐户。 postgres=# ALTER USER jim ACCOUNT LOCK; --删除用户。 postgres=# DROP USER kim CASCADE; postgres=# DROP USER jim CASCADE; postgres=# DROP USER dim CASCADE;
  • 示例:逻辑复制代码示例 下面示例演示如何通过JDBC接口使用逻辑复制功能的过程。 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 //以下以gsjdbc4.jar为例 // 认证用的用户名和密码直接写到代码中有很大的安全风险,建议在配置文件或者环境变量中存放(密码应密文存放,使用时解密),确保安全; // 本示例以用户名和密码保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量(环境变量名称请根据自身情况进行设置)EXAMPLE_USERNAME_ENV和EXAMPLE_PASSWORD_ENV。 //逻辑复制功能示例:文件名,LogicalReplicationDemo.java //前提条件:添加JDBC用户机器IP到数据库白名单里,在pg_hba.conf添加以下内容即可: //假设JDBC用户IP为10.10.10.10 //host all all 10.10.10.10/32 sha256 //host replication all 10.10.10.10/32 sha256 import org.postgresql.PGProperty; import org.postgresql.jdbc.PgConnection; import org.postgresql.replication.LogSequenceNumber; import org.postgresql.replication.PGReplicationStream; import java.nio.ByteBuffer; import java.sql.DriverManager; import java.util.Properties; import java.util.concurrent.TimeUnit; public class LogicalReplicationDemo { public static void main(String[] args) { String driver = "org.postgresql.Driver"; //此处配置数据库IP以及端口,这里的端口为haPort,通常默认是所连接DN的port+1端口 String sourceURL = "jdbc:postgresql://$ip:$port/postgres"; PgConnection conn = null; //默认逻辑复制槽的名称是:replication_slot //测试模式:创建逻辑复制槽 int TEST_MODE_CREATE_SLOT = 1; //测试模式:开启逻辑复制(前提条件是逻辑复制槽已经存在) int TEST_MODE_START_REPL = 2; //测试模式:删除逻辑复制槽 int TEST_MODE_DROP_SLOT = 3; //开启不同的测试模式 int testMode = TEST_MODE_START_REPL; try { Class.forName(driver); } catch (Exception e) { e.printStackTrace(); return; } try { Properties properties = new Properties(); PGProperty.USER.set(properties, System.getenv("EXAMPLE_USERNAME_ENV")); PGProperty.PASSWORD.set(properties, System.getenv("EXAMPLE_PASSWORD_ENV")); //对于逻辑复制,以下三个属性是必须配置项 PGProperty.ASSUME_MIN_SERVER_VERSION.set(properties, "9.4"); PGProperty.REPLICATION.set(properties, "database"); PGProperty.PREFER_QUERY_MODE.set(properties, "simple"); conn = (PgConnection) DriverManager.getConnection(sourceURL, properties); System.out.println("connection success!"); if(testMode == TEST_MODE_CREATE_SLOT){ conn.getReplicationAPI() .createReplicationSlot() .logical() .withSlotName("replication_slot") .withOutputPlugin("test_decoding") .make(); }else if(testMode == TEST_MODE_START_REPL) { //开启此模式前需要创建复制槽 LogSequenceNumber waitLSN = LogSequenceNumber.valueOf("6F/E3C53568"); PGReplicationStream stream = conn .getReplicationAPI() .replicationStream() .logical() .withSlotName("replication_slot") .withSlotOption("include-xids", false) .withSlotOption("skip-empty-xacts", true) .withStartPosition(waitLSN) .start(); while (true) { ByteBuffer byteBuffer = stream.readPending(); if (byteBuffer == null) { TimeUnit.MILLISECONDS.sleep(10L); continue; } int offset = byteBuffer.arrayOffset(); byte[] source = byteBuffer.array(); int length = source.length - offset; System.out.println(new String(source, offset, length)); //如果需要flush lsn,根据业务实际情况调用以下接口 // LogSequenceNumber lastRecv = stream.getLastReceiveLSN(); // stream.setFlushedLSN(lastRecv); // stream.forceUpdateStatus(); } }else if(testMode == TEST_MODE_DROP_SLOT){ conn.getReplicationAPI() .dropReplicationSlot("replication_slot"); } } catch (Exception e) { e.printStackTrace(); return; } } } 父主题: 基于JDBC开发
  • 参数说明 src_name 新建Data Source对象的名称,需在数据库内部唯一。 取值范围:字符串,要符标识符的命名规范。 TYPE 新建Data Source对象的类型,可缺省。 取值范围:空串或非空字符串。 VERSION 新建Data Source对象的版本号,可缺省或NULL值。 取值范围:空串或非空字符串或NULL。 OPTIONS Data Source对象的选项字段,创建时可省略,如若指定,其关键字如下: optname 选项名称。 取值范围:dsn, username, password, encoding。不区分大小写。 dsn对应odbc配置文件中的DSN。 username/password对应连接目标库的用户名和密码。 GaussDB在后台会对用户输入的username/password加密以保证安全性。 encoding表示与目标库交互的字符串编码方式(含发送的SQL语句和返回的字符类型数据),此处创建对象时不检查encoding取值的合法性,能否正确编解码取决于用户提供的编码方式是否在数据库本身支持的字符编码范围内。 optvalue 选项值。 取值范围:空或者非空字符串。
  • 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 --创建一个空的Data Source对象,不含任何信息。 postgres=# CREATE DATA SOURCE ds_test1; --创建一个Data Source对象,含TYPE信息,VERSION为NULL。 postgres=# CREATE DATA SOURCE ds_test2 TYPE 'MPPDB' VERSION NULL; --创建一个Data Source对象,仅含OPTIONS。 postgres=# CREATE DATA SOURCE ds_test3 OPTIONS (dsn 'GaussDB', encoding 'utf8'); --创建一个Data Source对象,含TYPE, VERSION, OPTIONS。 postgres=# CREATE DATA SOURCE ds_test4 TYPE 'unknown' VERSION '11.2.3' OPTIONS (dsn 'GaussDB', username 'userid', password 'pwd@123456', encoding ''); --删除Data Source对象。 postgres=# DROP DATA SOURCE ds_test1; postgres=# DROP DATA SOURCE ds_test2; postgres=# DROP DATA SOURCE ds_test3; postgres=# DROP DATA SOURCE ds_test4;
  • 语法 创建函数时需要指定返回值SETOF datatype。 return_next_clause::= return_query_clause::= 对以上语法的解释如下: 当需要函数返回一个集合时,使用RETURN NEXT或者RETURN QUERY向结果集追加结果,然后继续执行函数的下一条语句。随着后续的RETURN NEXT或RETURN QUERY命令的执行,结果集中会有多个结果。函数执行完成后会一起返回所有结果。 RETURN NEXT可用于标量和复合数据类型。 RETURN QUERY有一种变体RETURN QUERY EXECUTE,后面还可以增加动态查询,通过USING向查询插入参数。
  • 示例 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 postgres=# CREATE TABLE t1(a int); postgres=# INSERT INTO t1 VALUES(1),(10); --RETURN NEXT postgres=# CREATE OR REPLACE FUNCTION fun_for_return_next() RETURNS SETOF t1 AS $$ DECLARE r t1%ROWTYPE; BEGIN FOR r IN select * from t1 LOOP RETURN NEXT r; END LOOP; RETURN; END; $$ LANGUAGE PLPGSQL; postgres=# call fun_for_return_next(); a --- 1 10 (2 rows) -- RETURN QUERY postgres=# CREATE OR REPLACE FUNCTION fun_for_return_query() RETURNS SETOF t1 AS $$ DECLARE r t1%ROWTYPE; BEGIN RETURN QUERY select * from t1; END; $$ language plpgsql; postgres=# call fun_for_return_next(); a --- 1 10 (2 rows)
  • 变量声明 变量声明语法请参见图1。 图1 declare_variable::= 对以上语法格式的解释如下: variable_name,为变量名。 type,为变量类型。 value,是该变量的初始值(如果不给定初始值,则初始为NULL)。value也可以是表达式。 示例 1 2 3 4 5 6 postgres=# DECLARE emp_id INTEGER := 7788; --定义变量并赋值 BEGIN emp_id := 5*7784; --变量赋值 END; /
  • 变量作用域 变量的作用域表示变量在代码块中的可访问性和可用性。只有在它的作用域内,变量才有效。 变量必须在declare部分声明,即必须建立BEGIN-END块。块结构也强制变量必须先声明后使用,即变量在过程内有不同作用域、不同的生存期。 同一变量可以在不同的作用域内定义多次,内层的定义会覆盖外层的定义。 在外部块定义的变量,可以在嵌套块中使用。但外部块不能访问嵌套块中的变量。 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 postgres=# DECLARE emp_id INTEGER :=7788; --定义变量并赋值 outer_var INTEGER :=6688; --定义变量并赋值 BEGIN DECLARE emp_id INTEGER :=7799; --定义变量并赋值 inner_var INTEGER :=6688; --定义变量并赋值 BEGIN dbe_output.print_line('inner emp_id ='||emp_id); --显示值为7799 dbe_output.print_line('outer_var ='||outer_var); --引用外部块的变量 END; dbe_output.print_line('outer emp_id ='||emp_id); --显示值为7788 END; /
  • 步骤6:优化导入数据的查询性能 在数据导入完成后,执行ANALYZE语句生成表统计信息。执行计划生成器会使用这些统计数据,以生成最有效的查询执行计划。 如果导入过程中,进行了大量的更新或删除行时,应运行VACUUM FULL命令,然后运行ANALYZE命令。大量的更新和删除操作,会产生大量的磁盘页面碎片,从而逐渐降低查询的效率。VACUUM FULL可以将磁盘页面碎片恢复并交还操作系统。 对表product_info执行VACUUM FULL。 1 postgres=# VACUUM FULL product_info; VACUUM 更新表product_info的统计信息。 1 postgres=# ANALYZE product_info; ANALYZE 父主题: 教程:使用GDS从远端服务器导入数据
  • 创建索引 为了加速文本搜索,可以创建GIN索引。 1 postgres=# CREATE INDEX pgweb_idx_1 ON tsearch.pgweb USING gin(to_tsvector('english', body)); to_tsvector()函数有两个版本。只输一个参数的版本和输两个参数的版本。只输一个参数时,系统默认采用default_text_search_config所指定的分词器。 请注意:创建索引时必须使用to_tsvector的两参数版本。只有指定了分词器名称的全文检索函数才可以在索引表达式中使用。这是因为索引的内容必须不受default_text_search_config的影响,否则索引内容可能不一致。由于default_text_search_config的值可以随时调整,从而导致不同条目生成的tsvector采用了不同的分词器,并且没有办法区分究竟使用了哪个分词器。正确地转储和恢复这样的索引也是不可能的。 因为在上述创建索引中to_tsvector使用了两个参数,只有当查询时也使用了两个参数,且参数值与索引中相同时,才会使用该索引。也就是说,WHERE to_tsvector('english', body) @@ 'a & b' 可以使用索引,但WHERE to_tsvector(body) @@ 'a & b'不能使用索引。这确保只使用这样的索引——索引各条目是使用相同的分词器创建的。 索引中的分词器名称由另一列指定时可以建立更复杂的表达式索引。例如: 1 postgres=# CREATE INDEX pgweb_idx_2 ON tsearch.pgweb USING gin(to_tsvector('ngram', body)); 其中body是pgweb表中的一列。当对索引的各条目使用了哪个分词器进行记录时,允许在同一索引中存在混合分词器。在某些场景下这将是有用的。例如,文档集合中包含不同语言的文档时。再次强调,打算使用索引的查询必须措辞匹配,例如,WHERE to_tsvector(config_name, body) @@ 'a & b'与索引中的to_tsvector措辞匹配。 索引甚至可以连接列: 1 postgres=# CREATE INDEX pgweb_idx_3 ON tsearch.pgweb USING gin(to_tsvector('english', title || ' ' || body)); 另一个方法是创建一个单独的tsvector列控制to_tsvector的输出。下面的例子是title和body的连接, 当其它是NULL的时候,使用coalesce确保一个字段仍然会被索引: 1 2 postgres=# ALTER TABLE tsearch.pgweb ADD COLUMN textsearchable_index_col tsvector; postgres=# UPDATE tsearch.pgweb SET textsearchable_index_col = to_tsvector('english', coalesce(title,'') || ' ' || coalesce(body,'')); 然后为加速搜索创建一个GIN索引: 1 postgres=# CREATE INDEX textsearch_idx_4 ON tsearch.pgweb USING gin(textsearchable_index_col); 现在,就可以执行一个快速全文搜索了: 1 2 3 4 5 6 7 8 9 10 11 postgres=# SELECT title FROM tsearch.pgweb WHERE textsearchable_index_col @@ to_tsquery('north & america') ORDER BY last_mod_date DESC LIMIT 10; title -------- Canada Mexico (2 rows) 相比于一个表达式索引,单独列方法的一个优势是:它没有必要在查询时明确指定分词器以便能使用索引。正如上面例子所示,查询可以依赖于default_text_search_config。另一个优势是搜索比较快速,因为它没有必要重新利用to_tsvector调用来验证索引匹配。表达式索引方法更容易建立,且它需要较少的磁盘空间,因为tsvector形式没有明确存储。 父主题: 表和索引
  • 常量与宏 GaussDB支持的常量和宏请参见表1。 表1 常量和宏 参数 描述 示例 CURRENT_CATALOG 当前数据库 1 2 3 4 5 postgres=# SELECT CURRENT_CATALOG; current_database ------------------ postgres (1 row) CURRENT_ROLE 当前用户 1 2 3 4 5 postgres=# SELECT CURRENT_ROLE; current_user -------------- omm (1 row) CURRENT_SCHEMA 当前数据库模式 1 2 3 4 5 postgres=# SELECT CURRENT_SCHEMA; current_schema ---------------- public (1 row) CURRENT_USER 当前用户 1 2 3 4 5 postgres=# SELECT CURRENT_USER; current_user -------------- omm (1 row) LOCALTIMESTAMP 当前会话时间(无时区) 1 2 3 4 5 postgres=# SELECT LOCALTIMESTAMP; timestamp ---------------------------- 2015-10-10 15:37:30.968538 (1 row) NULL 空值 - SESSION_USER 当前系统用户 1 2 3 4 5 postgres=# SELECT SESSION_USER; session_user -------------- omm (1 row) SYSDATE 当前系统日期 1 2 3 4 5 postgres=# SELECT SYSDATE; sysdate --------------------- 2015-10-10 15:48:53 (1 row) USER 当前用户,此用户为CURRENT_USER的别名。 1 2 3 4 5 postgres=# SELECT USER; current_user -------------- omm (1 row) 父主题: SQL参考
  • 安全策略管理员 安全策略管理员是指具有POLADMIN属性的帐户,具有创建资源标签,脱敏策略和统一审计策略的权限。 要创建新的安全策略管理员,请以系统管理员用户身份连接数据库,并使用带POLADMIN选项的CREATE USER语句或 ALTER USER语句进行设置。 1 postgres=# CREATE USER poladmin WITH POLADMIN password "xxxxxxxxxxx"; 或者 1 postgres=# ALTER USER joe POLADMIN; ALTER USER时,要求用户已存在。
  • 运维管理员 运维管理员是指具有OPRADMIN属性的帐户,具有使用Roach工具执行备份恢复的权限。 要创建新的运维管理员,请以初始用户身份连接数据库,并使用带OPRADMIN选项的CREATE USER语句或 ALTER USER语句进行设置。 1 postgres=# CREATE USER opradmin WITH OPRADMIN password "xxxxxxxxxxx"; 或者 1 postgres=# ALTER USER joe OPRADMIN; ALTER USER时,要求用户已存在。
  • 监控管理员 监控管理员是指具有MONADMIN属性的帐户,具有查看dbe_perf模式下视图和函数的权限,亦可以对dbe_perf模式的对象权限进行授予或收回。 要创建新的监控管理员,请以系统管理员身份连接数据库,并使用带MONADMIN选项的CREATE USER语句或 ALTER USER语句进行设置。 1 postgres=# CREATE USER monadmin WITH MONADMIN password "xxxxxxxxxxx"; 或者 1 postgres=# ALTER USER joe MONADMIN; ALTER USER时,要求用户已存在。
  • 系统管理员 系统管理员是指具有SYSADMIN属性的帐户,默认安装情况下具有与对象所有者相同的权限,但不包括dbe_perf模式的对象权限和使用Roach工具执行备份恢复的权限。 要创建新的系统管理员,请以初始用户或者系统管理员用户身份连接数据库,并使用带SYSADMIN选项的CREATE USER语句或ALTER USER语句进行设置。 1 postgres=# CREATE USER sysadmin WITH SYSADMIN password "xxxxxxxxxxx"; 或者 1 postgres=# ALTER USER joe SYSADMIN; ALTER USER时,要求用户已存在。
共100000条