华为云用户手册

  • 语法格式 1 FETCH [ direction { FROM | IN } ] cursor_name; 其中direction子句为可选参数。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 NEXT | PRIOR | FIRST | LAST | ABSOLUTE count | RELATIVE count | count | ALL | FORWARD | FORWARD count | FORWARD ALL | BACKWARD | BACKWARD count | BACKWARD ALL
  • 功能描述 FETCH通过已创建的游标来检索数据。 每个游标都有一个供FETCH使用的关联位置。游标的关联位置可以在查询结果的第一行之前,或者在结果中的任意行,或者在结果的最后一行之后: 游标刚创建完之后,关联位置在第一行之前的。 在抓取了一些移动行之后,关联位置在检索到的最后一行上。 如果FETCH抓取完了所有可用行,它就停在最后一行后面,或者在反向抓取的情况下是停在第一行前面。 FETCH ALL或FETCH BACKWARD ALL将总是把游标的关联位置放在最后一行或者在第一行前面。
  • 示例 撤销 my_savepoint 建立之后执行的命令的影响: 1 ROLLBACK TO SAVEPOINT my_savepoint; 游标位置不受保存点回滚的影响: 1 2 3 4 BEGIN; DECLARE foo CURSOR FOR SELECT 1 UNION SELECT 2; SAVEPOINT foo; FETCH 1 FROM foo; 1 2 ROLLBACK TO SAVEPOINT foo; FETCH 1 FROM foo;
  • 注意事项 不能回滚到未定义的保存点,语法上会报错。 在保存点方面,游标有一些非事务性的行为。任何在保存点里打开的游标都会在回滚掉这个保存点之后关闭。如果一个前面打开了的游标在保存点里面,并且游标被一个FETCH命令影响,而这个保存点稍后回滚了,那么这个游标的位置仍然在FETCH让它指向的位置(也就是FETCH不会被回滚)。关闭一个游标的行为也不会被回滚给撤销掉。如果一个游标的操作导致事务回滚,那么这个游标就会置于不可执行状态,所以,尽管一个事务可以用ROLLBACK TO SAVEPOINT重新恢复,但是游标不能再使用了。 使用ROLLBACK TO SAVEPOINT回滚到保存点。使用RELEASE SAVEPOINT删除保存点,但是保留该保存点建立后执行的命令的效果。
  • 示例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.xxx.xxx.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)
  • 示例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.xxx.xxx.com', ACCESS_KEY 'xxxxxxxxx', SECRET_ACCESS_KEY 'yyyyyyyyyyyyy', TYPE 'DLI', DLI_ADDRESS 'dli.xxx.xxx.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)
  • 示例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;
  • 示例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;
  • 示例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)
  • 功能描述 在当前数据库创建一个HDFS或OBS外表,用来访问存储在HDFS或者OBS分布式集群文件系统上的结构化数据。也可以导出ORC格式数据到HDFS或者OBS上。 数据存储在OBS:数据存储和计算分离,集群存储成本低,存储量不受限制,并且集群可以随时删除,但计算性能取决于OBS访问性能,相对HDFS有所下降,建议在数据计算不频繁场景下使用。 数据存储在HDFS:数据存储和计算不分离,集群成本较高,计算性能高,但存储量受磁盘空间限制,删除集群前需将数据导出保存,建议在数据计算频繁场景下使用。 实时数仓(单机部署)暂不支持HDFS外表。 实时数仓(单机部署)8.2.0及以上集群版本支持OBS外表,但需要指定Server的foreign data wrapper为DFS_FDW。
  • 语法格式 创建外表。 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]
  • 注意事项 HDFS外表与OBS外表分为只读外表和只写外表,只读外表用于查询操作,只写外表可以将GaussDB(DWS)中的数据导出到分布式文件系统中。 此方式支持ORC、TEXT、CSV、CARBONDATA、PARQUET和JSON格式的导入查询,OBS外表支持ORC、CSV和TEXT格式的导出。HDFS外表仅支持ORC格式的导出。 该方式需要用户手动创建外部服务器,具体请参见CREATE SERVER。 若手动创建Server时指定foreign data wrapper为HDFS_FDW或者DFS_FDW,创建只读外表时需DISTRIBUTE BY子句指定分布方式。
  • 信息约束(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)的单个外表的导出目录,不能用于多个外表,并且其他组件不能向此目录写入其他文件。
  • 注意事项 列存表支持的数据类型请参考列存表支持的数据类型。 创建列存和HDFS分区表的数量建议不超过1000个。 表中的主键约束和唯一约束必须包含分布列。 如果在建表过程中数据库系统发生故障,系统恢复后可能无法自动清除之前已创建的、大小为0的磁盘文件。此种情况出现概率小,不影响数据库系统的正常运行。 列存表支持PARTIAL CLUSTER KEY、主键和唯一表级约束,不支持外键表级约束。 列存表的字段约束只支持NULL、NOT NULL和DEFAULT常量值。 列存表支持delta表,受表级参数enable_delta控制是否开启,受参数deltarow_threshold控制进入delta表的阈值。不推荐使用列存带Delta表,否则会出现由于来不及merge而导致的磁盘膨胀以及性能劣化等问题。 冷热表仅支持列存分区表,依赖于可用的OBS服务。 冷热表仅支持默认表空间为default_obs_tbs,如需新增obs表空间可联系技术支持。
  • 语法格式 1 2 3 4 5 6 7 8 9 10 11 12 CREATE [ [ GLOBAL | LOCAL | VOLATILE ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name { ({ column_name data_type [ compress_mode ] [ COLLATE collation ] [ column_constraint [ ... ] ] | table_constraint | LIKE source_table [ like_option [...] ] } [, ... ])| LIKE source_table [ like_option [...] ] } [ WITH ( {storage_parameter = value} [, ... ] ) ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS } ] [ COMPRESS | NOCOMPRESS ] [ DISTRIBUTE BY { REPLICATION | ROUNDROBIN | { HASH ( column_name [,...] ) } } ] [ TO { GROUP groupname | NODE ( nodename [, ... ] ) } ] [ COMMENT [=] 'text' ]; 其中列约束column_constraint为: 1 2 3 4 5 6 7 8 9 10 [ CONSTRAINT constraint_name ] { NOT NULL | NULL | CHECK ( expression ) | DEFAULT default_expr | ON UPDATE on_update_expr | COMMENT 'text' | UNIQUE [ NULLS [NOT] DISTINCT | NULLS IGNORE ] index_parameters | PRIMARY KEY index_parameters } [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] 其中列的压缩可选项compress_mode为: 1 { DELTA | PREFIX | DICTIONARY | NUMSTR | NOCOMPRESS } 其中表约束table_constraint为: 1 2 3 4 5 6 [ CONSTRAINT constraint_name ] { CHECK ( expression ) | UNIQUE [ NULLS [NOT] DISTINCT | NULLS IGNORE ] ( column_name [, ... ] ) index_parameters | PRIMARY KEY ( column_name [, ... ] ) index_parameters | PARTIAL CLUSTER KEY ( column_name [, ... ] ) } [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] 其中like选项like_option为: 1 { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | PARTITION | RELOPTIONS | DISTRIBUTION | DROPCOLUMNS | ALL } 其中索引参数index_parameters为: 1 [ WITH ( {storage_parameter = value} [, ... ] ) ]
  • 列存表支持的数据类型 列存表支持的数据类型如表1所示。其他未列举的数据类型,暂不支持。 表1 列存表支持的数据类型 类别 数据类型 描述 长度 数值类型 smallint 小范围整数,别名为INT2。 2 integer 常用的整数,别名为INT4。 4 bigint 大范围的整数,别名为INT8。 8 decimal 任意精度型。 可变长度 numeric 任意精度型。 可变长度 real 单精度浮点数。 4 double precision 双精度浮点数。 8 smallserial 二字节序列整型。 2 serial 四字节序列整型。 4 bigserial 八字节序列整型。 8 货币类型 money 货币金额。 8 字符类型 character varying(n), varchar(n) 变长字符串。 可变长度 character(n), char(n) 定长字符串。 n character、char 单字节内部类型。 1 text 变长字符串。 可变长度 nvarchar2 变长字符串。 可变长度 clob 文本大对象。 可变长度 日期/时间类型 timestamp with time zone 日期和时间,带时区。 8 timestamp without time zone 日期和时间。 8 date Oracle兼容模式下记录日期和时间;其他兼容模式下,记录日期。 Oracle兼容模式下,占存储空间8字节;其他兼容模式下,占存储空间4字节。 time without time zone 只用于一日内时间。 8 time with time zone 只用于一日内时间,带时区。 12 interval 时间间隔。 16 父主题: 数据类型
  • 语法格式 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 CREATE TYPE name AS ( [ attribute_name data_type [ COLLATE collation ] [, ... ] ] ) CREATE TYPE name ( INPUT = input_function, OUTPUT = output_function [ , RECEIVE = receive_function ] [ , SEND = send_function ] [ , TYPMOD_IN = type_modifier_input_function ] [ , TYPMOD_OUT = type_modifier_output_function ] [ , ANALYZE = analyze_function ] [ , INTERNALLENGTH = { internallength | VARIABLE } ] [ , PASSEDBYVALUE ] [ , ALIGNMENT = alignment ] [ , STORAGE = storage ] [ , LIKE = like_type ] [ , CATEGORY = category ] [ , PREFERRED = preferred ] [ , DEFAULT = default ] [ , ELEMENT = element ] [ , DELIMITER = delimiter ] [ , COLLATABLE = collatable ] ) CREATE TYPE name CREATE TYPE name AS ENUM ( [ 'label' [, ... ] ] )
  • 参数说明 复合类型 name 要创建的类型的名称(可以被模式限定)。 attribute_name 复合类型的一个属性(列)的名称。 data_type 要成为复合类型的一个列的现有数据类型的名称。 collation 要关联到复合类型的一列的现有排序规则的名称。 基本类型 自定义基本类型时,参数可以以任意顺序出现,input_function和output_function为必选参数,其它为可选参数。 input_function 将数据从类型的外部文本形式转换为内部形式的函数名。 输入函数可以被声明为有一个cstring类型的参数,或者有三个类型分别为cstring、 oid、integer的参数。 cstring参数是以C字符串存在的输入文本。 oid参数是该类型自身的OID(对于数组类型则是其元素类型的OID)。 integer参数是目标列的typmod(如果知道,不知道则将传递 -1)。 输入函数必须返回一个该数据类型本身的值。通常,一个输入函数应该被声明为STRICT。 如果不是这样,在读到一个NULL输入值时,调用输入函数时第一个参数会是NULL。在这种情况下,该函数必须仍然返回NULL,除非调用函数发生了错误(这种情况主要是想支持域输入函数,域输入函数可能需要拒绝NULL输入)。 输入和输出函数能被声明为具有新类型的结果或参数是因为:必须在创建新类型之前创建这两个函数。而新类型应该首先被定义为一种shell type,它是一种占位符类型,除了名称和拥有者之外它没有其他属性。这可以通过不带额外参数的命令CREATE TYPE name做到。然后用C写的I/O函数可以被定义为引用这种shell type。最后,用带有完整定义的CREATE TYPE把该shell type替换为一个完全的、合法的类型定义,之后新类型就可以正常使用了。 output_function 将数据从类型的内部形式转换为外部文本形式的函数名。 输出函数必须被声明为有一个新数据类型的参数。输出函数必须返回类型cstring。对于NULL值不会调用输出函数。 receive_function 可选参数。将数据从类型的外部二进制形式转换成内部形式的函数名。 如果没有该函数,该类型不能参与到二进制输入中。二进制表达转换成内部形式代价更低,然而却更容易移植(例如,标准的整数数据类型使用网络字节序作为外部二进制表达,而内部表达是机器本地的字节序)。receive_function应该执行足够的检查以确保该值是有效的。 接收函数可以被声明为有一个internal类型的参数,或者有三个类型分别为internal、oid、integer的参数。 internal参数是一个指向StringInfo缓冲区的指针,其中保存着接收到的字节串。 oid和integer参数和文本输入函数的相同。 接收函数必须返回一个该数据类型本身的值。通常,一个接收函数应该被声明为STRICT。如果不是这样,在读到一个NULL输入值时调用接收函数时第一个参数会是NULL。在这种情况下,该函数必须仍然返回NULL,除非接收函数发生了错误(这种情况主要是想支持域接收函数,域接收函数可能需要拒绝NULL输入)。 send_function 可选参数。将数据从类型的内部形式转换为外部二进制形式的函数名。 如果没有该函数,该类型将不能参与到二进制输出中。发送函数必须被声明为有一个新数据类型的参数。发送函数必须返回类型bytea。对于NULL值不会调用发送函数。 type_modifier_input_function 可选参数。将类型的修饰符数组转换为内部形式的函数名。 type_modifier_output_function 可选参数。将类型的修饰符的内部形式转换为外部文本形式的函数名。 如果该类型支持修饰符(附加在类型声明上的可选约束,例如,char(5)或numeric(30,2)),则需要可选的type_modifier_input_function以及type_modifier_output_function。GaussDB(DWS)允许用户定义的类型有一个或者多个简单常量或者标识符作为修饰符。不过,为了存储在系统目录中,该信息必须能被打包到一个非负整数值中。所声明的修饰符会被以cstring数组的形式传递给type_modifier_input_function。type_modifier_input_function必须检查该值的合法性(如果值错误就抛出一个错误),如果值正确,要返回一个非负integer值,该值将被存储在“typmod”列中。如果类型没有 type_modifier_input_function则类型修饰符将被拒绝。type_modifier_output_function把内部的整数typmod值转换回正确的形式用于用户显示。type_modifier_output_function必须返回一个cstring值,该值就是追加到类型名称后的字符串。例如,numeric的函数可能会返回(30,2)。如果默认的显示格式就是只把存储的typmod整数值放在圆括号内,则允许省略type_modifier_output_function。 analyze_function 可选参数。为该数据类型执行统计分析的函数名的可选参数。 默认情况下,如果该类型有一个默认的B-tree操作符类,ANALYZE将尝试用类型的“equals”和“less-than”操作符来收集统计信息。这种行为对于非标量类型并不合适,因此可以通过指定一个自定义分析函数来覆盖这种行为。分析函数必须被声明为有一个类型为internal的参数,并且返回一个boolean结果。 internallength 可选参数。一个数字常量,用于指定新类型的内部表达的字节长度。默认为变长。 虽然只有I/O函数和其他为该类型创建的函数才知道新类型的内部表达的细节, 但是内部表达的一些属性必须被向GaussDB(DWS)声明。其中最重要的是internallength。基本数据类型可以是定长的(这种情况下internallength是一个正整数)或者是变长的(把internallength设置为VARIABLE,在内部通过把typlen设置为-1表示)。所有变长类型的内部表达都必须以一个4字节整数开始,internallength定义了总长度。 PASSEDBYVALUE 可选参数。表示这种数据类型的值需要被传值而不是传引用。传值的类型必须是定长的,并且它们的内部表达不能超过Datum类型(某些机器上是4字节,其他机器上是8字节)的尺寸。 alignment 可选参数。该参数指定数据类型的存储对齐需求。如果被指定,必须是char、int2、int4或者double。默认是int4。 允许的值等同于以1、2、4或8字节边界对齐。要注意变长类型的alignment参数必须至少为4,因为它们需要包含一个int4作为它们的第一个组成部分。 storage 可选参数。该数据类型的存储策略。 如果被指定,必须是plain、external、extended或者main。 默认是plain。 plain指定该类型的数据将总是被存储在线内并且不会被压缩。(对定长类型只允许plain) extended指定系统将首先尝试压缩一个长的数据值,并且将在数据仍然太长的情况下把值移出主表行。 external允许值被移出主表, 但是系统将不会尝试对它进行压缩。 main允许压缩,但是不鼓励把值移出主表(如果没有其他办法让行的大小变得合适,具有这种存储策略的数据项仍将被移出主表,但比起extended以及external项来,这种存储策略的数据项会被优先考虑保留在主表中)。 除plain之外所有的storage值都暗示该数据类型的函数能处理被TOAST过的值。指定的值仅仅是决定一种可TOAST数据类型的列的默认TOAST存储策略,用户可以使用ALTER TABLE SET STORAGE为列选取其他策略。 like_type 可选参数。与新类型具有相同表达的现有数据类型的名称。会从这个类型中复制internallength、 passedbyvalue、 alignment以及storage的值( 除非在这个CREATE TYPE命令的其他地方用显式说明覆盖)。 当新类型的低层实现是以一种现有的类型为参考时,用这种方式指定表达特别有用。 category 可选参数。这种类型的分类码(一个ASCII 字符)。 默认是“用户定义类型”的'U'。为了创建自定义分类, 也可以选择其他ASCII字符。 preferred 可选参数。如果这种类型是其类型分类中的优先类型则为TRUE,否则为FALSE。默认为FALSE。在一个现有类型分类中创建一种新的优先类型要非常谨慎, 因为这可能会导致很大的改变。 category和preferred参数可以被用来帮助控制在混淆的情况下应用哪一种隐式造型。每一种数据类型都属于一个用单个ASCII 字符命名的分类,并且每一种类型可以是其所属分类中的“首选”。当有助于解决重载函数或操作符时,解析器将优先造型到首选类型(但是只能从同类的其他类型造型)。对于没有隐式转换到或来自任意其他类型的类型,让这些设置保持默认即可。不过,对于有隐式转换的相关类型的组,把它们都标记为属于同一个类别并且选择一种或两种“最常用”的类型作为该类别的首选通常是很有用的。在把一种用户定义的类型增加到一个现有的内建类别(例如,数字或者字符串类型)中时,category参数特别有用。不过,也可以创建新的全部是用户定义类型的类别。对这样的类别,可选择除大写字母之外的任何ASCII字符。 default 可选参数。数据类型的默认值。如果被省略,默认值是空。 如果用户希望该数据类型的列被默认为某种非空值,可以指定一个默认值。默认值可以用DEFAULT关键词指定(这样一个默认值可以被附加到一个特定列的显式DEFAULT子句覆盖)。 element 可选参数。被创建的类型是一个数组,element指定了数组元素的类型。例如,要定义一个4字节整数的数组(int4), 应指定ELEMENT = int4。 delimiter 可选参数。指定这种类型组成的数组中分隔值的定界符。 可以把delimiter设置为一个特定字符,默认的定界符是逗号(,)。注意定界符是与数组元素类型相关的,而不是数组类型本身相关。 collatable 可选参数。如果这个类型的操作可以使用排序规则信息,则为TRUE。默认为FALSE。 如果collatable为TRUE,这种类型的列定义和表达式可能通过使用COLLATE子句携带有排序规则信息。在该类型上操作的函数的实现负责真正利用这些信息,仅把类型标记为可排序的并不会让它们自动地去使用这类信息。 label 可选参数。与枚举类型的一个值相关的文本标签,其值为长度不超过64个字符的非空字符串。 在创建用户定义类型的时候, GaussDB(DWS)会自动创建一个与之关联的数组类型,其名字由该元素类型的名字前缀一个下划线组成。
  • 功能描述 在当前数据库中定义一种新的数据类型。定义数据类型的用户将成为该数据类型的拥有者。类型只适用于行存表 有四种形式的CREATE TYPE,分别为:复合类型、基本类型、shell类型和枚举类型。 复合类型 复合类型由一个属性名和数据类型的列表指定。如果属性的数据类型是可排序的,也可以指定该属性的排序规则。复合类型本质上和表的行类型相同,但是如果只想定义一种类型,使用CREATE TYPE避免了创建一个实际的表。单独的复合类型也是很有用的,例如可以作为函数的参数或者返回类型。 为了能够创建复合类型,必须拥有在其所有属性类型上的USAGE特权。 基本类型 用户可以自定义一种新的基本类型(标量类型)。通常来说这些函数必须是用C或者另外一种低层语言所编写。 shell类型 shell类型是一种用于后面要定义的类型的占位符,通过发出一个只带类型名参数的CREATE TYPE命令来创建该类型。在创建基本类型时,需要shell类型作为一种向前引用。 枚举类型 由若干个标签构成的列表,每一个标签值都是一个非空字符串,且字符串长度必须不超过64个字节。
  • uuid_generate_v1() 描述:生成一个UUID类型的序列号。 返回类型:UUID 示例: 1 2 3 4 5 SELECT uuid_generate_v1(); uuid_generate_v1 -------------------------------------- c71ceaca-a175-11e9-a920-797ff7000001 (1 row) uuid_generate_v1函数根据时间信息、集群节点编号和生成该序列的线程号生成UUID,该UUID在单个集群内是全局唯一的,但在多个集群间的时间信息、集群节点编号、线程号和时钟序列仍然存在同时相等的可能性,因此多个集群间生成的UUID仍然存在极低概率的重复风险。
  • uuid() 描述:生成一个UUID类型的序列号。此函数为MySQL兼容性函数,仅8.2.0及以上集群版本支持。 返回类型:UUID 示例: 1 2 3 4 5 SELECT uuid(); uuid ---------------------------------- 6327dc96-f0e7-0100-f2f2-6c9ff700fffe (1 row) uuid函数内部生成原理同uuid_generate_v1()函数,即根据时间信息、集群节点编号和生成该序列的线程号生成UUID,该UUID在单个集群内是全局唯一的,但在多个集群间的时间信息、集群节点编号、线程号和时钟序列仍然存在同时相等的可能性,因此多个集群间生成的UUID仍然存在极低概率的重复风险。
  • UUID函数应用示例 UUID全局唯一的特点,可以作为数据表生成主键,也可以作为数据表的分布列,uuid_generate_v1()作为数据表分布列的默认值时,通过Hash分布可以将数据均匀分布到各个DN上,防止数据倾斜。 UUID的显著优点就是全局唯一,不需要中心节点,单个节点独立生成。但是也存在缺点,UUID较INT占用更多的存储空间,索引效率低,生成的ID随机,没有递增的特性,所以辨识困难。因此,在应用中,要根据实际情况选择UUID还是Sequence作为数据表主键。 示例如下: INT类型作为分布列。 创建示例哈希表mytable01,int类型作为分布列,插入数据后,查询数据存在数据倾斜。 1 2 3 4 5 6 7 8 CREATE TABLE mytable01(a INT, b INT) DISTRIBUTE BY hash(a); INSERT INTO mytable01 VALUES(1, 10); INSERT INTO mytable01 VALUES(1, 10); INSERT INTO mytable01 VALUES(1, 10); INSERT INTO mytable01 VALUES(1, 10); INSERT INTO mytable01 VALUES(1, 10); SELECT * FROM mytable01; 1 SELECT table_skewness('mytable01'); UUID类型作为分布列。 创建示例哈希表mytable02,UUID类型作为分布列,插入数据后,查询数据分布正常。 1 2 3 4 5 6 7 8 CREATE TABLE mytable02 (id UUID default uuid_generate_v1(), a INT, b INT) DISTRIBUTE BY hash(id); INSERT INTO mytable02(a, b) VALUES(1, 10); INSERT INTO mytable02(a, b) VALUES(1, 10); INSERT INTO mytable02(a, b) VALUES(1, 10); INSERT INTO mytable02(a, b) VALUES(1, 10); INSERT INTO mytable02(a, b) VALUES(1, 10); SELECT * FROM mytable02; 1 SELECT table_skewness('mytable02');
  • sys_guid() 描述:生成Oracle的GUID序列号,类似UUID。此函数为Oracle兼容性函数。 返回类型:text 示例: 1 2 3 4 5 SELECT sys_guid(); sys_guid ---------------------------------- 4EBD3C74A17A11E9A1BF797FF7000001 (1 row) sys_guid函数内部生成原理同uuid_generate_v1函数。
  • 示例 Synonym词典可用于解决语言学相关问题,例如,为避免使单词"Paris"变成"pari",可在Synonym词典文件中定义一行"Paris paris",并将该词典放置在预定义的english_stem词典之前。 1 SELECT * FROM ts_debug('english', 'Paris'); 1 2 3 4 5 6 7 8 9 10 11 CREATE TEXT SEARCH DICTIONARY my_synonym ( TEMPLATE = synonym, SYNONYMS = my_synonyms, FILEPATH = 'obs://bucket01/obs.xxx.xxx.com accesskey=xxxxx secretkey=xxxxx region=cn-north-1' ); ALTER TEXT SEARCH CONFIGURATION english ALTER MAPPING FOR asciiword WITH my_synonym, english_stem; SELECT * FROM ts_debug('english', 'Paris'); 1 SELECT * FROM ts_debug('english', 'paris'); 1 ALTER TEXT SEARCH DICTIONARY my_synonym ( CASESENSITIVE=true); 1 SELECT * FROM ts_debug('english', 'paris'); 其中,同义词词典文件全名为my_synonyms.syn,所在目录为 'obs://bucket01/obs.xxx.xxx.com accesskey=xxxxx secretkey=xxxxx region=cn-north-1'。关于创建词典的语法和更多参数,请参见CREATE TEXT SEARCH DICTIONARY。 星号(*)可用于词典文件中的同义词结尾,表示该同义词是一个前缀。在to_tsvector()中该星号将被忽略,但在to_tsquery()中会匹配该前缀并对应输出结果(参照处理查询一节)。 假设词典文件synonym_sample.syn内容如下: 1 2 3 4 5 postgres pgsql postgresql pgsql postgre pgsql gogle googl indices index* 创建并使用词典: 1 2 3 4 5 6 CREATE TEXT SEARCH DICTIONARY syn ( TEMPLATE = synonym, SYNONYMS = synonym_sample ); SELECT ts_lexize('syn','indices'); 1 2 3 4 5 CREATE TEXT SEARCH CONFIGURATION tst (copy=simple); ALTER TEXT SEARCH CONFIGURATION tst ALTER MAPPING FOR asciiword WITH syn; SELECT to_tsvector('tst','indices'); 1 SELECT to_tsquery('tst','indices'); 1 SELECT 'indexes are very useful'::tsvector; 1 SELECT 'indexes are very useful'::tsvector @@ to_tsquery('tst','indices');
  • 参数说明 表1 冲突的锁模式 请求的锁模式/当前锁模式 ACCESS SHARE ROW SHARE ROW EXCLUSIVE SHARE UPDATE EXCLUSIVE SHARE SHARE ROW EXCLUSIVE EXCLUSIVE ACCESS EXCLUSIVE UPDATE EXCLUSIVE ACCESS SHARE - - - - - - - X - ROW SHARE - - - - - - X X - ROW EXCLUSIVE - - - - X X X X - SHARE UPDATE EXCLUSIVE - - - X X X X X - SHARE - - X X - X X X X SHARE ROW EXCLUSIVE - - X X X X X X X EXCLUSIVE - X X X X X X X X ACCESS EXCLUSIVE X X X X X X X X X UPDATE EXCLUSIVE - - - - X X X X X LOCK的参数说明如下所示: name 要锁定的表的名字,可以有模式修饰。 LOCK TABLE命令中声明的表的顺序就是上锁的顺序。 取值范围:已存在的表名。 ONLY 如果指定ONLY只有该表被锁定,如果没有声明该表和他的所有子表将都被锁定。 ACCESS SHARE ACCESS锁只允许对表进行读取,而禁止对表进行修改。所有对表进行读取而不修改的SQL语句都会自动请求这种锁。例如,SELECT命令会自动在被引用的表上请求一个这种锁。 ROW SHARE ROW SHARE锁允许对表进行并发读取,禁止对表进行其他操作。 SELECT FOR UPDATE和SELECT FOR SHARE命令会自动在目标表上请求ROW SHARE锁(且所有被引用但不是FOR SHARE/FOR UPDATE的其他表上,还会自动加上ACCESS SHARE锁)。 ROW EXCLUSIVE 与ROW SHARE锁不同,ROW EXCLUSIVE允许并发读取表,也允许修改表中的数据。UPDATE,DELETE,INSERT命令会自动在目标表上请求这个锁(且所有被引用的其他表上还会自动加上的ACCESS SHARE锁)。通常情况下,所有会修改表数据的命令都会请求表的ROW EXCLUSIVE锁。 SHARE UPDATE EXCLUSIVE 这个模式保护一个表的模式不被并发修改,以及禁止在目标表上执行垃圾回收命令(VACUUM )。 VACUUM(不带FULL选项),ANALYZE,CREATE INDEX CONCURRENTLY命令会自动请求这样的锁。 SHARE SHARE锁允许并发的查询,但是禁止对表进行修改。 CREATE INDEX(不带CONCURRENTLY选项)语句会自动请求这种锁。 SHARE ROW EXCLUSIVE SHARE ROW EXCLUSIVE锁禁止对表进行任何的并发修改,而且是独占锁,因此一个会话中只能获取一次。 任何SQL语句都不会自动请求这个锁模式。 EXCLUSIVE EXCLUSIVE锁允许对目标表进行并发查询,但是禁止任何其他操作。 这个模式只允许并发加ACCESS SHARE锁,也就是说,只有对表的读动作可以和持有这个锁模式的事务并发执行。 任何SQL语句都不会在用户表上自动请求这个锁模式。然而在某些操作的时候,会在某些系统表上请求它。 ACCESS EXCLUSIVE 这个模式保证其所有者(事务)是可以访问该表的唯一事务。 ALTER TABLE,DROP TABLE,TRUNCATE,REINDEX,CLUSTER,VACUUM FULL命令会自动请求这种锁。 在LOCK TABLE命令没有明确声明需要的锁模式时,它是缺省锁模式。 UPDATE EXCLUSIVE UPDATE EXCLUSIVE 锁允许并发(AUTO)VACUUM和(AUTO)ANALYZE,但不允许多个(AUTO)VACUUM并发。 该参数仅8.2.1.300及以上集群版本支持。 UPDATE EXCLUSIVE锁模式仅在VACUUM语法中使用。 NOWAIT 声明LOCK TABLE不去等待任何冲突的锁释放,如果无法立即获取该锁,该命令退出并且发出一个错误信息。 在不指定NOWAIT的情况下获取表级锁时,如果有其他互斥锁存在的话,则等待其他锁的释放。 LOCAL COORDINATOR ONLY 声明LOCK TABLE只在接收当前会话请求的CN上执行,而不会下发给其他CN和所有DN。该选项仅针对元数据的操作,以提高效率。 该参数仅8.2.0.100以上集群版本支持。 当前仅支持ACCESS SHARE锁模式,其他锁模式会报错。
  • 注意事项 LOCK TABLE只能在一个事务块的内部有用,因为锁在事务结束时就会被释放。出现在任意事务块外面的LOCK TABLE都会报错。 如果没有声明锁模式,缺省为最严格的模式ACCESS EXCLUSIVE。 LOCK TABLE ... IN ACCESS SHARE MODE需要在目标表上有SELECT权限。所有其他形式的LOCK需要UPDATE和/或DELETE权限。 没有UNLOCK TABLE命令,锁总是在事务结束时释放。 LOCK TABLE只处理表级的锁,因此那些带“ROW”字样的锁模式都是有歧义的。这些模式名字通常可理解为用户试图在一个被锁定的表中获取行级的锁。同样,ROW EXCLUSIVE模式也是一个可共享的表级锁。注意,只要是涉及到LOCK TABLE ,所有锁模式都有相同的语意,区别仅在于规则中锁与锁之间是否冲突,规则请参见表1。
  • 语法格式 1 2 3 LOCK [ TABLE ] {[ ONLY ] name [, ...]| {name [ * ]} [, ...]} [ IN {ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE | UPDATE EXCLUSIVE} MODE ] [ NOWAIT ] [LOCAL COORDINATOR ONLY];
  • 功能描述 LOCK TABLE获取表级锁。 当自动获取引用表的命令的锁时,GaussDB(DWS)会始终使用限制最小的锁模式。如果用户需要一种更为严格的锁模式,可以使用LOCK命令。例如,某个应用是在Read Committed隔离级别上运行事务,并且需要保证表中的数据在事务运行期间保持稳定。为实现这个目的,则可以在查询之前对表使用SHARE锁模式进行锁定。这样将防止并发数据更改,并确保后续的查询可以读到已提交的持久化的数据。因为SHARE锁模式与任何写操作需要的ROW EXCLUSIVE模式冲突,并且LOCK TABLE name IN SHARE MODE语句将等到所有当前持有ROW EXCLUSIVE模式锁的事务提交或回滚后才能执行。因此,一旦获得该锁,就不会存在未提交的写操作,此外其他操作也只能等到该锁释放之后才能开始。
  • 示例 character存储类型转换。对一个目标列定义为character(20)的语句,下面的语句显示存储值的长度正确: 1 2 3 4 5 6 7 8 9 10 11 12 CREATE TABLE x1 ( customer_sk integer, customer_id char(20), first_name char(6), last_name char(8) ) with (orientation = column,compression=middle) distribute by hash (last_name); INSERT INTO x1(customer_sk, customer_id, first_name) VALUES (3769, 'abcdef', 'Grace'); SELECT customer_id, octet_length(customer_id) FROM x1; 1 DROP TABLE x1; 这里真正发生的事情是两个unknown文本缺省解析成text,这样就允许||操作符解析成text连接。然后操作符的text结果转换成bpchar("空白填充的字符型", character类型内部名称)以匹配目标字段类型。不过,从text到bpchar的转换是二进制兼容的,这样的转换是隐含的并且实际上不做任何函数调用。最后,在系统表里找到长度转换函数bpchar(bpchar, integer, boolean) 并且应用于该操作符的结果和存储的字段长。这个类型相关的函数执行所需的长度检查和额外的空白填充。
  • 值存储数据类型解析 查找与目标字段准确的匹配。 试着将表达式直接转换成目标类型。如果已知这两种类型之间存在一个已登记的转换函数,那么直接调用该转换函数即可。如果表达式是一个未知类型文本,该文本字符串的内容将交给目标类型的输入转换过程。 检查一下看目标类型是否有长度转换。长度转换是一个从某类型到自身的转换。如果在pg_cast表里面找到一个,那么在存储到目标字段之前先在表达式上应用。这样的转换函数总是接受一个额外的类型为integer的参数,它接收目标字段的atttypmod值(实际上是其声明长度,atttypmod的解释随不同的数据类型而不同),并且它可能接受一个boolean类型的第三个参数,表示转换是显式的还是隐式的。转换函数负责施加那些长度相关的语义,比如长度检查或者截断。
共100000条