华为云用户手册

  • 语法格式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 CREATE [ OR REPLACE ] PROCEDURE procedure_name [ ( {[ argmode ] [ argname ] argtype [ { DEFAULT | := | = } expression ]}[,...]) ] [ { IMMUTABLE | STABLE | VOLATILE } | { SHIPPABLE | NOT SHIPPABLE } | {PACKAGE} | [ NOT ] LEAKPROOF | { CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT } | {[ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER | AUTHID DEFINER | AUTHID CURRENT_USER} | COST execution_cost | ROWS result_rows | SET configuration_parameter { [ TO | = ] value | FROM CURRENT } ][ ... ] { IS | AS } plsql_body /
  • 参数说明 OR REPLACE 当存在同名的存储过程时,替换原来的定义。 procedure_name 创建的存储过程名字,可以带有模式名。 取值范围:字符串,要符合标识符的命名规范。 argmode 参数的模式。 VARIADIC用于声明数组类型的参数。 取值范围: IN,OUT,INOUT或VARIADIC。缺省值是IN。只有OUT模式的参数后面能跟VARIADIC。并且OUT和INOUT模式的参数不能用在RETURNS TABLE的过程定义中。 argname 参数的名字。 取值范围:字符串,要符合标识符的命名规范。 argtype 参数的数据类型。 取值范围:可用的数据类型。 IMMUTABLE、STABLE等 行为约束可选项。各参数的功能与CREATE FUNCTION类似,详细说明见5.18.17.13-CREATE FUNCTION plsql_body PL/SQL存储过程体。 当在存储过程体中进行创建用户等涉及用户密码相关操作时,系统表及csv日志中会记录密码的明文。因此不建议用户在存储过程体中进行涉及用户密码的相关操作。 argument_name和argmode的顺序没有严格要求,推荐按照argument_name、argmode、argument_type的顺序使用。
  • 注意事项 函数创建也适用于存储过程,更多内容请参考CREATE FUNCTION。 如果创建存储过程时参数或返回值带有精度,不进行精度检测。 创建存储过程时,存储过程定义中对表对象的操作建议都显示指定模式,否则可能会导致存储过程执行异常。 在创建存储过程时,存储过程内部通过SET语句设置current_schema和search_path无效。执行完函数search_path和current_schema与执行函数前的search_path和current_schema保持一致。 如果存储过程参数中带有出参,SELECT调用存储过程必须缺省出参,CALL调用存储过程适配Oracle,调用非重载函数时必须指定出参,对于重载的package函数,out参数可以缺省,具体信息参见CALL的示例。 存储过程指定package属性时支持重载。 在创建procedure时,不能在avg函数外面嵌套其他agg函数,或者其他系统函数。 在多个CN的集群中,不能将存储过程的入参或出参设置为临时表类型,因为在非当前连接CN上执行创建存储过程时,无法单独根据表名获取到正确的临时schema,进而无法获取到准确的表类型。
  • 示例2:通过行级控制实现分区权限管理 创建用户alice: 1 CREATE ROLE alice PASSWORD '{password1}'; 创建范围分区表web_returns_p1,并插入数据: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 CREATE TABLE web_returns_p1 ( wr_returned_date_sk integer, wr_returned_time_sk integer, wr_item_sk integer NOT NULL, wr_refunded_customer_sk integer ) WITH (orientation = column) DISTRIBUTE BY HASH (wr_item_sk) PARTITION BY RANGE(wr_returned_date_sk) ( PARTITION p2016 START(800) END(830) EVERY(1) ); INSERT INTO web_returns_p1 values (801,17,11,102); INSERT INTO web_returns_p1 values (802,18,12,103); 将表web_returns_p1的读取权限赋予alice用户: 1 GRANT SELECT ON web_returns_p1 TO alice; 打开行访问控制策略开关: 1 ALTER TABLE web_returns_p1 ENABLE ROW LEVEL SECURITY; 创建行级访问控制策略web_returns_rsl。其中wr_returned_date_sk为web_returns_p1分区表的分区名,801为分区值: 1 CREATE ROW LEVEL SECURITY POLICY web_returns_rsl ON web_returns_p1 USING('wr_returned_date_sk' = '801'); 将行级访问控制策略web_returns_rsl的赋予用户alice: 1 ALTER ROW LEVEL SECURITY POLICY web_returns_rsl ON web_returns_p1 TO alice; 切换至alice用户: 1 set role alice password '{password1}'; 查询表web_returns_p1: 1 select * from web_returns_p1;
  • 注意事项 支持对行存表、行存分区表、列存表、列存分区表、复制表、unlogged表、hash表定义行访问控制策略。 不支持HDFS表、外表、临时表定义行访问控制策略。 不支持对视图定义行访问控制策略。 同一张表上可以创建多个行访问控制策略,一张表最多创建100个行访问控制策略。 具有管理员权限的用户、初始运维用户(Ruby)、表的owner和表的owner角色组成员不受行访问控制影响,可以查看表的全量数据。 通过SQL语句、视图、函数、存储过程查询包含行访问控制策略的表,都会受影响。 不支持对行访问控制策略依赖的列进行类型修改。例如,不支持如下修改: 1 ALTER TABLE public.all_data ALTER COLUMN role TYPE text;
  • 语法格式 1 2 3 4 5 CREATE [ ROW LEVEL SECURITY ] POLICY policy_name ON table_name [ AS { PERMISSIVE | RESTRICTIVE } ] [ FOR { ALL | SELECT | UPDATE | DELETE } ] [ TO { role_name | PUBLIC } [, ...] ] USING ( using_expression )
  • 参数说明 policy_name 行访问控制策略名称,同一个数据表上行访问控制策略名称不能相同。 table_name 行访问控制策略的表名。 PERMISSIVE 指定行访问控制策略的类型为宽容性策略。对于一个给定的查询,将使用“OR”操作符将所有的宽容性策略组合。行访问控制策略的类型默认为宽容性策略。 RESTRICTIVE 指定行访问控制策略的类型为限制性策略。对于一个给定的查询,将使用“AND”操作符将所有的限制性策略组合。 至少需要一条宽容性策略允许对记录的访问。如果只有限制性策略存在,则不能访问任何记录。当宽容性和限制性策略共存时,只有当记录能通过至少一条宽容性策略以及所有的限制性策略时,该记录才能访问。 command 当前行访问控制影响的SQL操作,可指定操作包括:ALL、SELECT、UPDATE、DELETE。当未指定时,ALL为默认值,涵盖SELECT、UPDATE、DELETE操作。 当command为SELECT时,SELECT类操作受行访问控制的影响,只能查看到满足条件(using_expression返回值为TRUE)的元组数据,受影响的操作包括SELECT,UPDATE ... RETURNING,DELETE ... RETURNING。 当command为UPDATE时,UPDATE类操作受行访问控制的影响,只能更新满足条件(using_expression返回值为TRUE)的元组数据,受影响的操作包括UPDATE,UPDATE ... RETURNING,SELECT ... FOR UPDATE/SHARE。 当command为DELETE时,DELETE类操作受行访问控制的影响,只能删除满足条件(using_expression返回值为TRUE)的元组数据,受影响的操作包括DELETE,DELETE ... RETURNING。 行访问控制策略与适配的SQL语法关系参见下表: 表1 ROW LEVEL SECURITY策略与适配SQL语法关系 Command SELECT/ALL policy UPDATE/ALL policy DELETE/ALL policy SELECT Existing row No No SELECT FOR UPDATE/SHARE Existing row Existing row No UPDATE No Existing row No UPDATE RETURNING Existing row Existing row No DELETE No No Existing row DELETE RETURNING Existing row No Existing row role_name 行访问控制影响的数据库用户。 当未指定时,PUBLIC为默认值,PUBLIC表示影响所有数据库用户,可以指定多个受影响的数据库用户。 系统管理员不受行访问控制特性影响。
  • 功能描述 对表创建行访问控制策略。 对表创建行访问控制策略时,需打开该表的行访问控制开关(ALTER TABLE ... ENABLE ROW LEVEL SECURITY)策略才能生效,否则不生效。 当前行访问控制会影响数据表的读取操作(SELECT、UPDATE、DELETE),暂不影响数据表的写入操作(INSERT、MERGE INTO)。表所有者或系统管理员可以在USING子句中创建表达式,并在客户端执行数据表读取操作时,数据库后台在查询重写阶段会将满足条件的表达式拼接并应用到执行计划中。针对数据表的每一条元组,当USING表达式返回TRUE时,元组对当前用户可见,当USING表达式返回FALSE或NULL时,元组对当前用户不可见。 行访问控制策略名称是针对表的,同一个数据表上不能有同名的行访问控制策略;对不同的数据表,可以有同名的行访问控制策略。 行访问控制策略可以应用到指定的操作(SELECT、UPDATE、DELETE、ALL),ALL表示会影响SELECT、UPDATE、DELETE三种操作;定义行访问控制策略时,若未指定受影响的相关操作,默认为ALL。 行访问控制策略可以应用到指定的用户(角色),也可应用到全部用户(PUBLIC);定义行访问控制策略时,若未指定受影响的用户,默认为PUBLIC。
  • 语法格式 1 2 3 4 CREATE REDACTION POLICY policy_name ON table_name [ { AFTER | BEFORE } old_policy_name ] [INHERIT] [ WHEN (when_expression) ] [ ADD COLUMN column_name WITH redaction_function_name ( [ argument [, ...] ] )] [, ... ];
  • 示例 对指定用户创建脱敏策略。 创建用户alice和matu: 1 2 CREATE ROLE alice PASSWORD '{password}'; CREATE ROLE matu PASSWORD '{password}'; 用户alice创建表对象emp并插入数据: 1 2 CREATE TABLE emp(id int, name varchar(20), salary NUMERIC(10,2)); INSERT INTO emp VALUES(1, 'July', 1230.10), (2, 'David', 999.99); 用户alice为表对象emp创建脱敏策略mask_emp,字段salary对用户matu不可见: 1 CREATE REDACTION POLICY mask_emp ON emp WHEN(current_user = 'matu') ADD COLUMN salary WITH mask_full(salary); 用户alice授予用户matu表emp的SELECT权限: 1 GRANT SELECT ON emp TO matu; 切至用户matu: 1 SET ROLE matu PASSWORD '{password}'; 查询表emp,字段salary数据已脱敏: 1 SELECT * FROM emp; 对角色创建脱敏策略。 创建角色redact_role: 1 CREATE ROLE redact_role PASSWORD '{password}'; 将用户matu,alice加入角色redact_role: 1 GRANT redact_role to matu,alice; 管理员用户创建表对象emp1并插入数据: 1 2 CREATE TABLE emp1(id int, name varchar(20), salary NUMERIC(10,2)); INSERT INTO emp1 VALUES(3, 'Rose', 2230.20), (4, 'Jack', 899.88); 管理员用户为表对象emp1创建脱敏策略mask_emp1,使字段salary对角色redact_role不可见。 1 CREATE REDACTION POLICY mask_emp1 ON emp1 WHEN(pg_has_role(current_user, 'redact_role', 'member')) ADD COLUMN salary WITH mask_full(salary); 若不指定用户,默认为当前用户current_user: 1 CREATE REDACTION POLICY mask_emp1 ON emp1 WHEN (pg_has_role('redact_role', 'member')) ADD COLUMN salary WITH mask_full(salary); 管理员用户授予用户matu表emp1的SELECT权限: 1 GRANT SELECT ON emp1 TO matu; 切换至用户matu: 1 SET ROLE matu PASSWORD '{password}'; 查询表emp,字段salary数据已脱敏。 1 SELECT * FROM emp1;
  • 注意事项 只有表对象的属主具有创建脱敏策略的权限。 仅支持在普通表创建数据脱敏策略,不支持为系统表、HDFS表、外表、临时表、UN LOG GED表以及视图和函数对象创建脱敏策略。 不支持通过同义词向普通表对象创建脱敏策略。 表对象与脱敏策略间一一对应。一个脱敏策略是表对象所有脱敏列的集合,可以给脱敏表对象的多个列字段指定脱敏函数,且不同脱敏列对象可以采用不同的脱敏函数。 创建脱敏策略时,默认策略生效,即属性enable值为true。 具有sysadmin权限的用户,可跳过脱敏策略检查,对脱敏列数据一直具有可见性,即脱敏策略不生效。 支持通过指定角色匹配脱敏策略。
  • 语法格式 在表上创建索引。 1 2 3 4 5 6 7 CREATE [ UNIQUE ] INDEX [ [ schema_name. ] index_name ] ON table_name [ USING method ] ({ { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] }[, ...] ) [ NULLS [ NOT ] DISTINCT | NULLS IGNORE ] [ COMMENT 'text' ] [ WITH ( {storage_parameter = value} [, ... ] ) ] [ WHERE predicate ]; 在分区表上创建索引。 1 2 3 4 5 6 7 CREATE [ UNIQUE ] INDEX [ [ schema_name. ] index_name ] ON table_name [ USING method ] ( {{ column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [ ASC | DESC ] [ NULLS LAST ] }[, ...] ) [ NULLS [ NOT ] DISTINCT | NULLS IGNORE ] [ COMMENT 'text' ] LOCAL [ ( { PARTITION index_partition_name [UNUSABLE] } [, ...] ) ] [ WITH ( { storage_parameter = value } [, ...] ) ] ;
  • 参数说明 UNIQUE 创建唯一性索引,每次添加数据时检测表中是否有重复值。如果插入或更新的值会引起重复的记录时,将导致一个错误。 目前只有行存表B-tree索引和列存表的B-tree索引支持唯一索引。 schema_name 要创建的索引所在的模式名。指定的模式名需与表所在的模式相同。 index_name 要创建的索引名,索引的模式与表相同。 取值范围:字符串,要符合标识符的命名规范。 table_name 需要为其创建索引的表的名字,可以用模式修饰。 取值范围:已存在的表名。 USING method 指定创建索引的方法。 取值范围: btree:B-tree索引使用一种类似于B+树的结构来存储数据的键值,通过这种结构能够快速的查找索引。btree适合支持比较查询以及查询范围。 gin:GIN索引是倒排索引,可以处理包含多个键的值(比如数组)。 gist:Gist索引适用于几何和地理等多维数据类型和集合数据类型。 Psort:Psort索引。针对列存表进行局部排序索引。 行存表支持的索引类型:btree(行存表缺省值)、gin、gist。列存表支持的索引类型:Psort(列存表缺省值)、btree、gin。 column_name 表中需要创建索引的列的名字(字段名)。 如果索引方式支持多字段索引,可以声明多个字段。最多可以声明32个字段。 expression 创建一个基于该表的一个或多个字段的表达式索引,通常必须写在圆括弧中。如果表达式有函数调用的形式,圆括弧可以省略。 表达式索引可用于获取对基本数据的某种变形的快速访问。比如,一个在upper(col)上的函数索引将允许WHERE upper(col) = 'JIM'子句使用索引。 在创建表达式索引时,如果表达式中包含IS NULL子句,则这种索引是无效的。此时,建议用户尝试创建一个部分索引。 COLLATE collation COLLATE子句指定列的排序规则(该列必须是可排列的数据类型)。如果没有指定,则使用默认的排序规则。 opclass 操作符类的名字。对于索引的每一列可以指定一个操作符类,操作符类标识了索引那一列的使用的操作符。例如一个B-tree索引在一个四字节整数上可以使用int4_ops;这个操作符类包括四字节整数的比较函数。实际上对于列上的数据类型默认的操作符类是足够用的。操作符类主要用于一些有多种排序的数据。例如,用户想按照绝对值或者实数部分排序一个复数。能通过定义两个操作符类然后在建立索引时选择合适的类。 ASC 指定按升序排序 (默认)。本选项仅行存支持。 DESC 指定按降序排序。本选项仅行存支持。 NULLS FIRST 指定空值在排序中排在非空值之前,当指定DESC排序时,本选项为默认的。 NULLS LAST 指定空值在排序中排在非空值之后,未指定DESC排序时,本选项为默认的。 NULLS [ NOT ] DISTINCT | NULLS IGNORE 指定Unique唯一索引中索引列NULL值的处理方式。 默认取值:该参数默认取值为空,即NULL值可重复插入。 在对插入的新数据和表中原始数据进行列的等值比较时,对于NULL值有以下三种处理方式: NULLS DISTINCT:NULL值互不相等,即NULL值可重复插入。 NULLS NOT DISTINCT:NULL值相等。若索引列全为NULL,则NULL值不可重复插入;部分索引列为NULL,只有非NULL值不相等,才可成功插入数据。 NULLS IGNORE:在等值比较时跳过NULL值。若索引列全为NULL,则NULL值可重复插入;部分索引列为NULL,只有非NULL值不相等,才可成功插入数据。 三种处理方式具体的行为如下表所示: 表1 唯一索引中索引列NULL值的处理方式 字段控制 索引列全为NULL 部分索引列为NULL NULLS DISTINCT 可重复插入 可重复插入 NULLS NOT DISTINCT 不可重复插入 非NULL值相等,不可插入;非NULL值不相等,则插入成功 NULLS IGNORE 可重复插入 非NULL值相等,不可插入;非NULL值不相等,则插入成功 COMMENT 'text' 指定索引的注释信息。 WITH ( {storage_parameter = value} [, ... ] ) 指定索引方法的存储参数。 取值范围: 只有GIN索引支持FASTUPDATE,GIN_PENDING_LIST_LIMIT参数。GIN和Psort之外的索引都支持FILLFACTOR参数。所有索引都支持INVISIBLE参数。 FILLFACTOR 一个索引的填充因子(fillfactor)是一个介于10和100之间的百分数。 取值范围:10~100 FASTUPDATE GIN索引是否使用快速更新。 取值范围:ON,OFF 默认值:ON GIN_PENDING_LIST_LIMIT 当GIN索引启用fastupdate时,设置该索引pending list容量的最大值。 取值范围:64~INT_MAX,单位KB。 默认值:gin_pending_list_limit的默认取决于GUC中gin_pending_list_limit的值(默认为4MB) INVISIBLE 控制优化器是否生成索引扫描相关计划。 取值范围: ON表示不生成索引扫描相关计划。 OFF表示生成索引扫描相关计划。 默认值:OFF WHERE predicate 创建一个部分索引。部分索引是一个只包含表的一部分记录的索引,通常是该表中比其他部分数据更有用的部分。例如,有一个表,表里包含已记账和未记账的订单,未记账的订单只占表的一小部分而且这部分是最常用的部分,此时就可以通过只在未记账部分创建一个索引来改善性能。另外一个可能的用途是使用带有UNIQUE的WHERE强制一个表的某个子集的唯一性。 取值范围:predicate表达式只能引用表的字段,它可以使用所有字段,而不仅是被索引的字段。目前,子查询和聚集表达式不能出现在WHERE子句里。 PARTITION index_partition_name 索引分区的名称。 取值范围:字符串,要符合标识符的命名规范。 UNUSABLE 建表或者索引分区上的索引时支持创建状态为UNUSABLE的索引。该参数仅8.3.0.100及以上集群版本支持。
  • 注意事项 索引自身也占用存储空间、消耗计算资源,创建过多的索引将对数据库性能造成负面影响(尤其影响数据导入的性能,建议在数据导入后再建索引)。因此,仅在必要时创建索引。 索引定义里的所有函数和操作符都必须是immutable类型的,即结果必须依赖于其输入参数,而不受任何外部的影响(如另外一个表的内容或者当前时间),该限制可以确保该索引的行为是定义良好的。在一个索引上或WHERE语句中使用用户定义函数,请将其标记为immutable类型函数。 在分区表上创建唯一索引时,索引项中必须包含分布列和所有分区键。 GaussDB (DWS)在分区表上创建索引时只支持本地(LOCAL)索引,不支持全局(GLOBAL)索引。 列存表和HDFS表支持B-tree索引,不支持创建表达式索引、部分索引。 列存表支持通过B-tree索引建立唯一索引。 列存表和HDFS表支持的PSORT索引不支持创建表达式索引、部分索引和唯一索引。 列存表支持的GIN索引支持创建表达式索引,但表达式不能包含空分词、空列和多列,不支持创建部分索引和唯一索引。 roundrobin表不支持创建主键/唯一索引。 对表执行CREATE INDEX或REINDEX操作时会触发索引重建(索引重建过程中会先把数据转储到一个新的数据文件中,重建完成之后会删除原始文件),当表比较大时,重建会消耗较多的磁盘空间。当磁盘空间不足时,要谨慎对待大表CREATE INDEX或REINDEX操作,防止触发集群只读。 针对有大批量数据增删改的表,索引个数建议控制在3个以内,最多不超过5个。 避免在业务高峰期执行对大表执行CREATE INDEX和REINDEX操作。 更多开发设计规范参见总体开发设计规范。
  • 功能描述 在指定的表上创建索引。 索引可以用来提高数据库查询性能,但是不恰当的使用将导致数据库性能下降。建议仅在匹配如下某条原则时创建索引: 经常执行查询的字段。 在连接条件上创建索引,对于存在多字段连接的查询,建议在这些字段上建立组合索引。例如,select * from t1 join t2 on t1.a=t2.a and t1.b=t2.b,可以在t1表上的a,b字段上建立组合索引。 where子句的过滤条件字段上(尤其是范围条件)。 在经常出现在order by、group by和distinct后的字段。 对于点查询场景,推荐建立btree索引。 在分区表上创建索引与在普通表上创建索引的语法不太一样,使用时请注意,如分区表上不支持并行创建索引、不支持创建部分索引、不支持NULL FIRST特性。
  • 语法格式 1 2 CREATE GROUP group_name [ [ WITH ] option [ ... ] ] [ ENCRYPTED | UNENCRYPTED ] { PASSWORD | IDENTIFIED BY } { 'password' | DISABLE }; 其中可选项action子句语法为: 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 where option can be: {SYSADMIN | NOSYSADMIN} | {AUDITADMIN | NOAUDITADMIN} | {CREATEDB | NOCREATEDB} | {USEFT | NOUSEFT} | {CREATEROLE | NOCREATEROLE} | {INHERIT | NOINHERIT} | {LOGIN | NOLOGIN} | {REPLICATION | NOREPLICATION} | {INDEPENDENT | NOINDEPENDENT} | {VCADMIN | NOVCADMIN} | CONNECTION LIMIT connlimit | VALID BEGIN 'timestamp' | VALID UNTIL 'timestamp' | RESOURCE POOL 'respool' | USER GROUP 'groupuser' | PERM SPACE 'spacelimit' | NODE GROUP logic_group_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
  • 示例 定义函数为SQL查询: 1 2 3 4 5 CREATE FUNCTION func_add_sql(integer, integer) RETURNS integer AS 'select $1 + $2;' LANGUAGE SQL IMMUTABLE RETURNS NULL ON NULL INPUT; 利用参数名用 PL/pgSQL 自增一个整数: 1 2 3 4 5 CREATE OR REPLACE FUNCTION func_increment_plsql(i integer) RETURNS integer AS $$ BEGIN RETURN i + 1; END; $$ LANGUAGE plpgsql; 返回RECORD类型: 1 2 3 4 5 6 7 8 9 CREATE OR REPLACE FUNCTION compute(i int, out result_1 bigint, out result_2 bigint) returns SETOF RECORD as $$ begin result_1 = i + 1; result_2 = i * 10; return next; end; $$language plpgsql; 返回一个包含多个输出参数的记录: 1 2 3 4 CREATE FUNCTION func_dup_sql(in int, out f1 int, out f2 text) AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$ LANGUAGE SQL; SELECT * FROM func_dup_sql(42); 计算两个整数的和,并返回结果。若果输入为null,则返回null: 1 2 3 4 5 6 CREATE FUNCTION func_add_sql2(num1 integer, num2 integer) RETURN integer AS BEGIN RETURN num1 + num2; END; / 创建package属性的重载函数: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 CREATE OR REPLACE FUNCTION package_func_overload(col int, col2 int) return integer package as declare col_type text; begin col := 122; dbms_output.put_line('two int parameters ' || col2); return 0; end; / CREATE OR REPLACE FUNCTION package_func_overload(col int, col2 smallint) return integer package as declare col_type text; begin col := 122; dbms_output.put_line('two smallint parameters ' || col2); return 0; end; /
  • 参数说明 function_name 要创建的函数名字(可以用模式修饰)。 取值范围:字符串,要符合标识符的命名规范。 如果创建的函数名与系统函数同名,建议指定schema。调用自定义函数时需指定schema,否则系统会优先调用系统函数。 argname 函数参数的名字。 取值范围:字符串,要符合标识符的命名规范。 argmode 函数参数的模式。 取值范围:IN,OUT,INOUT或VARIADIC。缺省值是IN。只有OUT模式的参数后面能跟VARIADIC。并且OUT和INOUT模式的参数不能用在RETURNS TABLE的函数定义中。 VARIADIC用于声明数组类型的参数。 argtype 函数参数的类型。 expression 函数参数的默认表达式。 rettype 函数返回值的数据类型。 如果存在OUT或IN OUT参数,可以省略RETURNS子句。如果存在,该子句必须和输出参数所表示的结果类型一致:如果有多个输出参数,则为RECORD,否则与单个输出参数的类型相同。 SETOF修饰词表示该函数将返回一个集合,而不是单独一项。 DETERMINISTIC 为适配Oracle SQL语法,未实现功能,不推荐使用。 column_name 字段名称。 column_type 字段类型。 definition 一个定义函数的字符串常量,含义取决于语言。它可以是一个内部函数名字、一个指向某个目标文件的路径、一个SQL查询、一个过程语言文本。 LANGUAGE lang_name 用以实现函数的语言的名字。可以是SQL,internal,或者是用户定义的过程语言名字。为了保证向下兼容,该名字可以用单引号(包围)。若采用单引号,则引号内必须为大写。 WINDOW 表示该函数是窗口函数,替换函数定义时不能改变WINDOW属性。 自定义窗口函数只支持LANGUAGE是internal,并且引用的内部函数必须是窗口函数。 IMMUTABLE 表示该函数在给出同样的参数值时总是返回同样的结果。 如果函数的入参是常量,会在优化器阶段计算该函数的值。益处是可以尽早获取表达式的值,从而能更准确的进行代价估算,生成的执行计划也更优。 用户自定义的IMMUTABLE的函数是会被自动下推到DN执行的,但是这样可能有潜在的风险,即如果用户错误定义了函数的IMMUTABLE属性,但是函数执行的过程并不是IMMUTABLE的,那么可能会导致结果错误等严重问题。因此,用户在指定函数的属性为IMMUTABLE的时候,要特别慎重。 举例如下: 如果自定义函数中引用了表,视图等对象,那么该函数就不能定义为IMMUTABLE,因为当表的数据发生变化的时候,函数的返回值可能发生变化。 如果自定义函数中引用了STABLE/VOALATILE类型的函数,那么该函数不能定义为IMMUTABLE。 如果自定义函数中有不下推的因素,则该函数不能定义成IMMUTABLE,因为IMMUTABLE意味着要下推到DN执行,与函数内部的不下推因素相互冲突。典型场景例如,包含不下推的函数、语法等。 如果自定义函数中含有聚合运算,但聚合运算的运算需要生成STREAM计划才能完成计算的(部分结果在DN计算,部分结果在CN计算,例如listagg函数等)。 同时,为了防止这种情况下可能出现严重问题,数据库内部可以通过设置behavior_compat_options=‘check_function_conflicts’来开启对函数定义冲突的检查,目前可以识别出上述1和2场景。 STABLE 表示该函数不能修改数据库,对相同参数值,在同一次表扫描里,该函数的返回值不变,但是返回值可能在不同SQL语句之间变化。 VOLATILE 表示该函数值可以在一次表扫描内改变,因此不会做任何优化。 SHIPPABLE NOT SHIPPABLE 表示该函数是否可以下推到DN上执行。 对于IMMUTABLE类型的函数,函数始终可以下推到DN上执行。 对于STABLE/VOLATILE类型的函数,仅当函数的属性是SHIPPABLE的时候,函数可以下推到DN执行。 用户在定义函数的SHIPPABLE属性时也需特别慎重,SHIPPABLE意味着整个函数会下推到DN上执行,如果设置不当,会导致结果错误等严重问题。 与定义IMMUTABLE属性一样,SHIPPABLE属性的定义也有诸多约束,简单来说就是函数内不能有不可下推的因素,函数下推到单DN执行后,函数内部的计算逻辑仅依赖当前DN的数据集合。 举例如下: 如果函数内部引用了表,并且表为HASH分布,那么该函数通常不能定义为SHIPPABLE。 函数内部有不可下推的因素,函数,语法等,那么该函数不能定义为SHIPPABLE,可参考语句下推调优。 函数内部的计算过程可能需要跨DN数据,这种情况该函数通常不能定义为SHIPPABLE,例如一些聚合运算等。 PACKAGE 表示该函数是否支持重载。PostgreSQL风格的函数本身就支持重载,此参数主要是针对Oracle风格的函数。 不允许package函数和非package函数重载或者替换。 package函数不支持VARIADIC类型的参数。 不允许修改函数的package属性。 LEAKPROOF 指出该函数的参数只包括返回值。LEAKPROOF只能由系统管理员设置。 CALLED ON NULL INPUT 表明该函数的某些参数是NULL的时候可以按照正常的方式调用。该参数可以省略。 RETURNS NULL ON NULL INPUT STRICT STRICT用于指定如果函数的某个参数是NULL,此函数总是返回NULL。如果声明了这个参数,当有NULL值参数时该函数不会被执行;而只是自动返回一个NULL结果。 RETURNS NULL ON NULL INPUT和STRICT的功能相同。 EXTERNAL 目的是和SQL兼容,是可选的,这个特性适合于所有函数,而不仅是外部函数。 SECURITY INVOKER AUTHID CURRENT_USER 表明该函数将带着调用它的用户的权限执行。该参数可以省略。 SECURITY INVOKER和AUTHID CURRENT_USER的功能相同。 SECURITY DEFINER AUTHID DEFINER 声明该函数将以创建它的用户的权限执行。 AUTHID DEFINER和SECURITY DEFINER的功能相同。 FENCED NOT FENCED 该函数只对用户定义的C函数生效,声明函数是在保护模式还是非保护模式下执行。如果函数声明为NOT FENCED模式,则函数的执行在CN或者DN进程中进行。如果函数声明为FENCED模式,则函数在新fork的进程执行,这样函数的异常不会影响CN或者DN进程。 FENCED/NOT FENCED模式的选择: 正在开发或者调试的Function使用FENCED模式。开发测试完成,使用NOT FENCED模式执行,减少fork进程以及通信的开销。 复杂的操作系统操作,例:打开文件,信号处理,线程处理等操作,使用FENCED模式。否则可能影响GaussDB(DWS)数据库的执行。 默认值为FENCED。 COST execution_cost 用来估计函数的执行成本。 execution_cost以cpu_operator_cost为单位。 取值范围:正数 ROWS result_rows 估计函数返回的行数。用于函数返回的是一个集合。 取值范围:正数,默认值是1000行。 configuration_parameter value 把指定的数据库会话参数值设置为给定的值。如果value是DEFAULT或者RESET,则在新的会话中使用系统的缺省设置。OFF关闭设置。 取值范围:字符串 DEFAULT OFF RESET 指定默认值。 from current 取当前会话中的值设置为configuration_parameter的值。 plsql_body PL/SQL存储过程体。 当在函数中创建用户时,日志中会记录密码的明文。因此不建议用户在函数中创建用户。
  • 注意事项 如果创建函数时参数或返回值带有精度,不进行精度检测。 创建函数时,函数定义中对表对象的操作建议都显式指定模式,否则可能会导致函数执行异常。 在创建函数时,函数内部通过SET语句设置current_schema和search_path无效。执行完函数search_path和current_schema与执行函数前的search_path和current_schema保持一致。 如果函数参数中带有出参,SELECT调用函数必须缺省出参,CALL调用函数适配Oracle必须指定出参,对于调用重载的带有PACKAGE属性的函数,CALL调用函数可以缺省出参,具体信息参见CALL的示例。 兼容PostgreSQL风格的函数或者带有PACKAGE属性的函数支持重载。在指定REPLACE的时候,如果参数个数、类型、返回值有变化,不会替换原有函数,而是会建立新的函数。 SELECT调用可以指定不同参数来进行同名函数调用。由于语法CALL适配自Oracle,因此不支持调用不带有PACKAGE属性的同名函数。 在创建function时,不能在avg函数外面嵌套其他agg函数,或者其他系统函数。 在非逻辑集群模式下,暂不支持将返回值、参数以及变量设置为建在非系统默认安装Node Group的表,sql function内部语句暂不支持对建在非系统默认安装Node Group的表操作。 在逻辑集群模式下,如果函数返回值和参数是用户表类型,所有涉及表都必须在同一逻辑集群内;如果函数内部涉及对多个逻辑集群表操作,函数定义时不能为IMMUTABLE和SHIPPABLE类型,以避免函数被下推到DN执行。 在逻辑集群模式下,函数参数、返回值不能用%type引用表字段类型,否则会导致函数创建失败。 新创建的函数默认会给PUBLIC授予执行权限(详见GRANT)。用户可以选择收回PUBLIC默认执行权限,然后根据需要将执行权限授予其他用户,为了避免出现新函数能被所有人访问的时间窗口,应在一个事务中创建函数并且设置函数执行权限。 在多个CN的集群中,不能将函数的入参或出参设置为临时表类型,因为在非当前连接CN上执行创建函数过程中,无法单独根据表名获取到正确的临时schema,进而无法获取到准确的表类型。
  • 语法格式 兼容PostgreSQL风格的创建自定义函数语法。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 CREATE [ OR REPLACE ] FUNCTION function_name ( [ { argname [ argmode ] argtype [ { DEFAULT | := | = } expression ]} [, ...] ] ) [ RETURNS rettype [ DETERMINISTIC ] | RETURNS TABLE ( { column_name column_type } [, ...] )] LANGUAGE lang_name [ {IMMUTABLE | STABLE | VOLATILE } | {SHIPPABLE | NOT SHIPPABLE} | WINDOW | [ NOT ] LEAKPROOF | {CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT } | {[ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER | AUTHID DEFINER | AUTHID CURRENT_USER} | {FENCED | NOT FENCED} | {PACKAGE} | COST execution_cost | ROWS result_rows | SET configuration_parameter { {TO | =} value | FROM CURRENT }} ][...] { AS 'definition' | AS 'obj_file', 'link_symbol' } Oracle风格的创建自定义函数的语法。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 CREATE [ OR REPLACE ] FUNCTION function_name ( [ { argname [ argmode ] argtype [ { DEFAULT | := | = } expression ] } [, ...] ] ) RETURN rettype [ DETERMINISTIC ] [ {IMMUTABLE | STABLE | VOLATILE } | {SHIPPABLE | NOT SHIPPABLE} | {PACKAGE} | {FENCED | NOT FENCED} | [ NOT ] LEAKPROOF | {CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT } | {[ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER | AUTHID DEFINER | AUTHID CURRENT_USER } | COST execution_cost | ROWS result_rows | SET configuration_parameter { {TO | =} value | FROM CURRENT ][...] { IS | AS } plsql_body /
  • 语法格式 1 2 3 4 5 6 7 CREATE FOREIGN TABLE [ IF NOT EXISTS ] table_name ( [ { column_name type_name | LIKE source_table } [, ...] ] ) SERVER server_name OPTIONS ( { option_name ' value ' } [, ...] ) [ READ ONLY ] [ DISTRIBUTE BY {ROUNDROBIN} ] [ TO { GROUP groupname | NODE ( nodename [, ... ] ) } ];
  • 示例 创建名称为server_remote的外部服务器,对应的foreign data wrapper为GC_FDW。 1 CREATE SERVER server_remote FOREIGN DATA WRAPPER GC_FDW OPTIONS (address '10.10.0.100:25000,10.10.0.101:25000',dbname 'test', username 'test', password '{password}'); 在可选项options里面写入了关联集群CN对应的IP地址及端口号。这里推荐使用填写一个LVS的地址或者多个CN的地址。 创建名称为region的外表: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 CREATE FOREIGN TABLE region ( R_REGIONKEY INT4, R_NAME TEXT, R_COMMENT TEXT ) SERVER server_remote OPTIONS ( schema_name 'test', table_name 'region', encoding 'gbk' ); 查看创建的外表region: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 \d+ region Foreign table "public.region" Column | Type | Modifiers | FDW Options | Storage | Stats target | Description -------------+---------+-----------+-------------+----------+--------------+------------- r_regionkey | integer | | | plain | | r_name | text | | | extended | | r_comment | text | | | extended | | Server: server_remote FDW Options: (schema_name 'test', table_name 'region', encoding 'gbk') FDW permission: read only Has OIDs: no Distribute By: ROUND ROBIN Location Nodes: ALL DATANODES
  • 参数说明 IF NOT EXISTS 如果已经存在相同名称的表,不会抛出一个错误,而会发出一个通知,告知表关系已存在。 table_name 外表的表名。 取值范围:字符串,要符合标识符的命名规范。 column_name 外表中的字段名。可以选择多个字段名,中间用“,”隔开。 取值范围:字符串,要符合标识符的命名规范。 不允许在列上创建约束,也不允许创建索引。 type_name 字段的数据类型。 不允许使用序列当作类型和使用自定义类型。 SERVER server_name server名称。允许用户自定义名称。 取值范围:字符串,要符合标识符的命名规范,并且该server必须存在。 OPTIONS ( { option_name ' value ' } [, ...] ) 用于指定外表数据的各类参数,参数类型如下所示。 table_name:对应关联集群的表名,如果省略此option则认为该值和外表名字一样。 schema_name:对应关联集群的schema,如果省略此option则认为该值和外表所在的schema一样。 encoding:对应关联集群的编码,如果省略此option则使用关联集群的数据库编码。 dataencoding:用于实现GDS互联互通时两个latin1库中GBK数据和UTF8数据的同步。该参数仅8.2.0及以上集群版本支持。 当设置该参数时,encoding表示远端集群数据的真实编码,dataencoding表示为本地执行端的集群数据的真实编码。 假如本地执行端和远端两个数据库分别为latin1_local_db和latin1_remote_db,latin1_remote_db中存储着GBK的数据,当把latin1_remote_db中GBK的数据以UTF8的编码迁移到latin1_local_db时,需要在本地端的集群设置外表的dataencoding为UTF8,encoding为GBK。 gds_compress GDS互联互通为了降低网络传输带宽,提供了压缩参数,默认不压缩,当前仅支持设置值为snappy。该参数仅8.2.0及以上集群版本支持。 使用该功能时需要保证本地集群,远端集群,GDS的版本至少在同一版本。 gds_compress与file_type配合使用,当file_type的参数为interconn时,gds需要升级到8.2.0及以上版本,否则会出现ERROR: un-support format报错。 READ ONLY 外表只读。 DISTRIBUTE BY ROUNDROBIN 显示指定外表为ROUNDROBIN分布方式。 TO { GROUP groupname | NODE ( nodename [, ... ] ) } TO GROUP目前不支持使用。TO NODE主要供内部扩容工具使用,一般用户不应使用。
  • 示例5 通过外表读取 DLI 多版本外表。DLI多版本外表示例仅8.1.1及以上版本支持。 创建dli_server,对应的foreign data wrapper为DFS_FDW。 1 2 3 4 5 6 7 8 9 CREATE SERVER dli_server FOREIGN DATA WRAPPER DFS_FDW OPTIONS ( ADDRESS 'obs.example.com', AC CES S_KEY 'xxxxxxxxx', SECRET_ACCESS_KEY 'yyyyyyyyyyyyy', TYPE 'DLI', DLI_ADDRESS 'dli.example.com', DLI_ACCESS_KEY 'xxxxxxxxx', DLI_SECRET_ACCESS_KEY 'yyyyyyyyyyyyy' ); ADDRESS是OBS的终端节点(Endpoint)。DLI_ADDRESS是DLI的终端节点(Endpoint),请根据实际替换。 ACCESS_KEY和SECRET_ACCESS_KEY 是云账号体系访问OBS服务的密钥。请根据实际替换。 DLI_ACCESS_KEY和DLI_SECRET_ACCESS_KEY是云账号体系访问DLI服务的密钥。请根据实际替换。 TYPE表示创建的Server为DLI Server。请保持DLI取值不变。 创建访问DLI多版本的OBS外表customer_address,不包含分区列,表关联的DLI服务器为dli_server。其中project_id为xxxxxxxxxxxxxxx,dli上的database_name为database123,需要访问的table_name为table456,根据实际替换。 认证用的AK和SK硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 CREATE FOREIGN TABLE customer_address ( ca_address_sk integer not null, ca_address_id char(16) not null, ca_street_number char(10) , ca_street_name varchar(60) , ca_street_type char(15) , ca_suite_number char(10) , ca_city varchar(60) , ca_county varchar(30) , ca_state char(2) , ca_zip char(10) , ca_country varchar(20) , ca_gmt_offset decimal(36,33) , ca_location_type char(20) ) SERVER dli_server OPTIONS ( FORMAT 'ORC', ENCODING 'utf8', DLI_PROJECT_ID 'xxxxxxxxxxxxxxx', DLI_DATABASE_NAME 'database123', DLI_TABLE_NAME 'table456' ) DISTRIBUTE BY roundrobin; 通过外表查询DLI多版本表的数据。 1 2 3 4 5 SELECT COUNT(*) FROM customer_address; count ------- 20 (1 row)
  • 示例4 通过外表读取OBS上的json数据。 OBS上有如下json文件,json对象中存在嵌套、数组,部分对象的某些字段缺失,部分对象name重复。 {"A" : "simple1", "B" : {"C" : "nesting1"}, "D" : ["array", 2, {"E" : "complicated"}]} {"A" : "simple2", "D" : ["array", 2, {"E" : "complicated"}]} {"A" : "simple3", "B" : {"C" : "nesting3"}, "D" : ["array", 2, {"E" : "complicated3"}]} {"B" : {"C" : "nesting4"},"A" : "simple4", "D" : ["array", 2, {"E" : "complicated4"}]} {"A" : "simple5", "B" : {"C" : "nesting5"}, "D" : ["array", 2, {"E" : "complicated5"}]} 创建obs_server,对应的foreign data wrapper为DFS_FDW。 1 2 3 4 5 6 CREATE SERVER obs_server FOREIGN DATA WRAPPER DFS_FDW OPTIONS ( ADDRESS 'obs.example.com', ACCESS_KEY 'xxxxxxxxx', SECRET_ACCESS_KEY 'yyyyyyyyyyyyy', TYPE 'OBS' ); ADDRESS是OBS的终端节点(Endpoint),请根据实际替换。也是使用region参数,通过指定regionCode在region_map文件中查找对应的 域名 。 ACCESS_KEY和SECRET_ACCESS_KEY 是云账号体系访问密钥。请根据实际替换。 TYPE表示创建的Server为OBS Server。请保持OBS取值不变。 创建OBS外表json_f ,定义字段名,以d#2_e为例,从命名可以看出该字段是数组d的第二个元素里嵌套的e对象。表关联的OBS服务器为obs_server。foldername为外表中数据源文件目录,即表数据目录在OBS上对应的文件目录。 认证用的AK和SK硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全。 1 2 3 4 5 6 7 8 9 10 11 CREATE FOREIGN TABLE json_f ( a VARCHAR(10), b_c TEXT, d#1 INTEGER, d#2_e VARCHAR(30) )SERVER obs_server OPTIONS ( foldername '/xxx/xxx/', format 'json', encoding 'utf8', force_mapping 'true' )distribute by roundrobin; 查询外表json_f。由于容错性参数force_mapping默认打开,json对象缺失的字段会填NULL;json对象name重复的以最后一次出现的name为准。 1 2 3 4 5 6 7 8 9 SELECT * FROM json_f; a | b_c | d#1 | d#2_e ---------+----------+-----+-------------- simple1 | nesting1 | 2 | complicated1 simple2 | | 2 | complicated2 simple3 | nesting3 | 2 | complicated3 simple4 | nesting4 | 2 | complicated4 repeat | nesting5 | 2 | complicated5 (5 rows)
  • 示例2 通过HDFS只写外表,将TPC-H benchmark测试数据表region中的数据导出至HDFS文件系统的/user/hive/warehouse/mppdb.db/regin_orc/目录下。 创建HDFS SERVER,对应的foreign data wrapper为HDFS_FDW或者DFS_FDW,同示例一。 创建HDFS只写外表。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 CREATE FOREIGN TABLE ft_wo_region ( R_REGIONKEY INT4, R_NAME TEXT, R_COMMENT TEXT ) SERVER hdfs_server OPTIONS ( FORMAT 'orc', encoding 'utf8', FOLDERNAME '/user/hive/warehouse/mppdb.db/regin_orc/' ) WRITE ONLY; 通过只写外表向HDFS文件系统写入数据。 1 INSERT INTO ft_wo_region SELECT * FROM region;
  • 示例3 关于包含信息约束(Informational Constraint)HDFS外表的相关操作。 创建含有信息约束(Informational Constraint)的HDFS外表。 1 2 3 4 5 6 7 8 9 10 CREATE FOREIGN TABLE ft_region ( R_REGIONKEY int, R_NAME TEXT, R_COMMENT TEXT , primary key (R_REGIONKEY) not enforced) SERVER hdfs_server OPTIONS(format 'orc', encoding 'utf8', foldername '/user/hive/warehouse/mppdb.db/region_orc11_64stripe') DISTRIBUTE BY roundrobin; 查看region表是否有信息约束索引: 1 2 3 4 5 6 7 8 9 10 11 SELECT relname,relhasindex FROM pg_class WHERE oid='ft_region'::regclass; relname | relhasindex ------------------------+------------- ft_region | f (1 row) SELECT conname, contype, consoft, conopt, conindid, conkey FROM pg_constraint WHERE conname ='ft_region_pkey'; conname | contype | consoft | conopt | conindid | conkey ----------------+---------+---------+--------+----------+-------- ft_region_pkey | p | t | t | 0 | {1} (1 row) 删除信息约束: 1 2 3 4 5 6 ALTER FOREIGN TABLE ft_region DROP CONSTRAINT ft_region_pkey RESTRICT; SELECT conname, contype, consoft, conindid, conkey FROM pg_constraint WHERE conname ='ft_region_pkey'; conname | contype | consoft | conindid | conkey ---------+---------+---------+----------+-------- (0 rows) 添加一个唯一信息约束: 1 ALTER FOREIGN TABLE ft_region ADD CONSTRAINT constr_unique UNIQUE(R_REGIONKEY) NOT ENFORCED; 删除唯一信息约束: 1 2 3 4 5 6 ALTER FOREIGN TABLE ft_region DROP CONSTRAINT constr_unique RESTRICT; SELECT conname, contype, consoft, conindid, conkey FROM pg_constraint WHERE conname ='constr_unique'; conname | contype | consoft | conindid | conkey ---------+---------+---------+----------+-------- (0 rows) 添加一个唯一信息约束: 1 2 3 4 5 6 7 ALTER FOREIGN TABLE ft_region ADD CONSTRAINT constr_unique UNIQUE(R_REGIONKEY) NOT ENFORCED disable query optimization; SELECT relname,relhasindex FROM pg_class WHERE oid='ft_region'::regclass; relname | relhasindex ------------------------+------------- ft_region | f (1 row) 删除唯一信息约束: 1 ALTER FOREIGN TABLE ft_region DROP CONSTRAINT constr_unique CASCADE;
  • 语法格式 创建外表。 1 2 3 4 5 6 7 8 9 10 11 12 CREATE FOREIGN TABLE [ IF NOT EXISTS ] table_name ( [ { column_name type_name [ { [CONSTRAINT constraint_name] NULL | [CONSTRAINT constraint_name] NOT NULL | column_constraint [...]} ] | table_constraint [, ...]} [, ...] ] ) SERVER server_name OPTIONS ( { option_name ' value ' } [, ...] ) [ {WRITE ONLY | READ ONLY}] DISTRIBUTE BY {ROUNDROBIN | REPLICATION} [ PARTITION BY ( column_name ) [ AUTOMAPPED ] ] ; 其中column_constraint为: 1 2 3 [CONSTRAINT constraint_name] {PRIMARY KEY | UNIQUE} [NOT ENFORCED [ENABLE QUERY OPTIMIZATION | DISABLE QUERY OPTIMIZATION] | ENFORCED] 其中table_constraint为: 1 2 3 [CONSTRAINT constraint_name] {PRIMARY KEY | UNIQUE} (column_name) [NOT ENFORCED [ENABLE QUERY OPTIMIZATION | DISABLE QUERY OPTIMIZATION] | ENFORCED]
  • 信息约束(Informational Constraint) 在GaussDB(DWS)中,数据的约束完全由使用者保证,数据源数据能够严格遵守某种信息约束条件,能够加速对已经具有这种约束特征数据的查询。目前外表不支持索引,所以采取使用Informational Constraint信息优化Plan,提高查询性能。 建立外表信息约束的约束条件: 只有用户保证表中的其中一列的非空值具有唯一性时才可以建立Informational Constraint,否则查询结果将与期望值不同。 GaussDB(DWS)的Informational Constraint只支持PRIMARY KEY和UNIQUE两种约束。 GaussDB(DWS)的Informational Constraint支持NOT ENFORCED属性,不支持ENFORCED属性。 一个表上的多列可以分别建立UNIQUE类型的Informational Constraint,但是PRIMARY KEY一个表中只能建立一个。 一个表的一列上可以建立多个Informational Constraint(由于一个列上有多个约束和一个的作用一致,所以不建议一个列上建立多个Informational Constraint),但是Primary Key类型只能建立一个。 不支持COMMENT。 不支持多列组合约束。 ORC格式只写外表不支持同一个集群不同CN向同一外表并发导出。 ORC格式只写外表的目录,只能用于GaussDB(DWS)的单个外表的导出目录,不能用于多个外表,并且其他组件不能向此目录写入其他文件。
  • 示例1 在HDFS通过HIVE导入TPC-H benchmark测试数据表part表及region表。part表的文件路径为/user/hive/warehouse/partition.db/part_4,region表的文件路径为/user/hive/warehouse/mppdb.db/region_orc11_64stripe/。 创建HDFS_Server,对应的foreign data wrapper为HDFS_FDW或者DFS_FDW。 1 CREATE SERVER hdfs_server FOREIGN DATA WRAPPER HDFS_FDW OPTIONS (address '10.10.0.100:25000,10.10.0.101:25000',hdfscfgpath '/opt/hadoop_client/HDFS/hadoop/etc/hadoop',type'HDFS'); 在可选项options里面写入了HDFS集群对应的NameNode的IP地址及端口号。具体端口号请在 MRS -HDFS服务配置中搜索参数“dfs.namenode.rpc.port”查看。本示例假设端口号为25000。 ‘10.10.0.100:25000,10.10.0.101:25000’中列出了两组NameNode的地址及端口号,分别表示HDFS的主NameNode及备NameNode,这里推荐使用该种主备方式填写。两组参量中间使用“,”进行分割。 创建HDFS外表。表关联的HDFS server为hdfs_server,表ft_region对应的HDFS服务器上的文件格式为‘orc’,在HDFS文件系统上对应的文件目录为'/user/hive/warehouse/mppdb.db/region_orc11_64stripe/'。 创建不包含分区列的HDFS外表: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 CREATE FOREIGN TABLE ft_region ( R_REGIONKEY INT4, R_NAME TEXT, R_COMMENT TEXT ) SERVER hdfs_server OPTIONS ( FORMAT 'orc', encoding 'utf8', FOLDERNAME '/user/hive/warehouse/mppdb.db/region_orc11_64stripe/' ) DISTRIBUTE BY roundrobin; 创建包含分区列的HDFS外表: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 CREATE FOREIGN TABLE ft_part ( p_partkey int, p_name text, p_mfgr text, p_brand text, p_type text, p_size int, p_container text, p_retailprice float8, p_comment text ) SERVER hdfs_server OPTIONS ( FORMAT 'orc', encoding 'utf8', FOLDERNAME '/user/hive/warehouse/partition.db/part_4' ) DISTRIBUTE BY roundrobin PARTITION BY (p_mfgr) AUTOMAPPED; GaussDB(DWS)支持2种文件指定方式:通过关键字filenames指定和通过foldername指定。推荐通过使用foldername进行指定。关键字distribute指定了表ft_region的存储分布方式。 查看创建的外表: 1 2 3 4 5 6 7 8 9 10 11 SELECT * FROM pg_foreign_table WHERE ftrelid='ft_region'::regclass; ftrelid | ftserver | ftwriteonly | ftoptions ---------+----------+-------------+------------------------------------------------------------------------------ 16510 | 16509 | f | {format=orc,foldername=/user/hive/warehouse/mppdb.db/region_orc11_64stripe/} (1 row) select * from pg_foreign_table where ftrelid='ft_part'::regclass; ftrelid | ftserver | ftwriteonly | ftoptions ---------+----------+-------------+------------------------------------------------------------------ 16513 | 16509 | f | {format=orc,foldername=/user/hive/warehouse/partition.db/part_4} (1 row)
共100000条