云服务器内容精选

  • 优化建议 UN LOG GED UNLOGGED表和表上的索引因为数据写入时不通过WAL日志机制,写入速度远高于普通表。因此,可以用于缓冲存储复杂查询的中间结果集,增强复杂查询的性能。 UNLOGGED表无主备机制,在系统故障或异常断点等情况下,会有数据丢失风险,因此,不可用来存储基础数据。 TEMPORARY | TEMP 临时表只在当前会话可见,会话结束后会自动删除。 除了当前CN外,其他CN对于该临时表不可见。 LIKE 新表自动从这个表中继承所有字段名及其数据类型和非空约束,新表与源表之间在创建动作完毕之后是完全无关的。 LIKE INCLUDING DEFAULTS 源表上的字段缺省表达式只有在指定INCLUDING DEFAULTS时,才会复制到新表中。缺省是不包含缺省表达式的,即新表中的所有字段的缺省值都是NULL。 LIKE INCLUDING CONSTRAINTS 源表上的CHECK约束仅在指定INCLUDING CONSTRAINTS时,会复制到新表中,而其他类型的约束永远不会复制到新表中。非空约束总是复制到新表中。此规则同时适用于表约束和列约束。 LIKE INCLUDING INDEXES 如果指定了INCLUDING INDEXES,则源表上的索引也将在新表上创建,默认不建立索引。 LIKE INCLUDING STORAGE 如果指定了INCLUDING STORAGE,则复制列的STORAGE设置会复制到新表中,默认情况下不包含STORAGE设置。 LIKE INCLUDING COMMENTS 如果指定了INCLUDING COMMENTS,则源表列、约束和索引的注释会复制到新表中。默认情况下,不复制源表的注释。 LIKE INCLUDING PARTITION 如果指定了INCLUDING PARTITION,则源表的分区定义会复制到新表中,同时新表将不能再使用PARTITION BY子句。默认情况下,不复制源表的分区定义。 LIKE INCLUDING RELOPTIONS 如果指定了INCLUDING RELOPTIONS,则源表的存储参数(即源表的WITH子句)会复制到新表中。默认情况下,不复制源表的存储参数。 LIKE INCLUDING DISTRIBUTION 如果指定了INCLUDING DISTRIBUTION,则源表的分布信息会复制到新表中,包括分布类型和分布列,同时新表将不能再使用DISTRIBUTE BY子句。默认情况下,不复制源表的分布信息。 LIKE INCLUDING ALL INCLUDING ALL包含了INCLUDING DEFAULTS、INCLUDING CONSTRAINTS、INCLUDING INDEXES、INCLUDING STORAGE、INCLUDING COMMENTS、INCLUDING PARTITION、INCLUDING RELOPTIONS、INCLUDING DISTRIBUTION和INCLUDING ILM的内容。 ORIENTATION ROW 创建行存表,行存储适合于OLTP业务,此类型的表上交互事务比较多,一次交互会涉及表中的多个列,用行存查询效率较高。 DISTRIBUTE BY 事实表或者数据量较大的维度表建议创建为分布表。对指定的列进行Hash,通过映射,把数据分布到指定DN。语法为:DISTRIBUTE BY HASH(column_name)。 数据量较小的维度表建议创建为复制表。表的每条记录存在所有数据节点(DN)中,即每个数据节点都有完整的表数据。语法为: DISTRIBUTE BY REPLICATION。
  • 表数据分布示例 REPLICATION gaussdb=# CREATE TABLE test_replication( id CHAR(7), name VARCHAR(20), province VARCHAR(60), --省 country VARCHAR(30) DEFAULT 'China' --国籍 )DISTRIBUTE BY REPLICATION; --查询表信息。 gaussdb=# \d+ test_replication Table "public.test_replication" Column | Type | Modifiers | Storage | Stats target | Description ----------+-----------------------+------------------------------------+----------+--------------+------------- id | character(7) | | extended | | name | character varying(20) | | extended | | province | character varying(60) | | extended | | country | character varying(30) | default 'China'::character varying | extended | | Has OIDs: no Distribute By: REPLICATION Location Nodes: ALL DATANODES Options: orientation=row, logical_repl_node=-1, compression=no, storage_type=USTORE, segment=off --删除。 gaussdb=# DROP TABLE test_replication; HASH --定义一个表,使用HASH分布。 gaussdb=# CREATE TABLE test_hash( id CHAR(7), name VARCHAR(20), province VARCHAR(60), --省 country VARCHAR(30) DEFAULT 'China' --国籍 )DISTRIBUTE BY HASH(id); --插入数据。 gaussdb=# INSERT INTO test_hash VALUES ('0000001', 'Bob', 'Shanghai', 'China'), ('0000002', 'Jack', 'Beijing', 'China'), ('0000003', 'Scott', 'Beijing', 'China'); --查看数据分布情况。 gaussdb=# SELECT a.count,b.node_name FROM (SELECT COUNT(*) AS count, xc_node_id FROM test_hash GROUP BY xc_node_id) a, pgxc_node b WHERE a.xc_node_id=b.node_id ORDER BY a.count DESC; count | node_name -------+------------------- 2 | dn_6001_6002_6003 1 | dn_6004_6005_6006 --删除表。 gaussdb=# DROP TABLE test_hash; MURMURHASH --测试环境包含1个CN和6个DN。 --创建NODEGROUP,NODEGROUP中的DN名字可以通过语句SELECT node_name FROM PGXC_NODE WHERE node_type = 'D';查询,查询的结果按需替换CREATE NODE GROUP语句中WITH后的DN名。 gaussdb=# CREATE NODE GROUP NG1 WITH(datanode1, datanode2, datanode3, datanode4, datanode5, datanode6); --定义一个表,使用MURMURHASH分布。 gaussdb=# CREATE TABLE test_murmurhash1 (a int NOT NULL, b int) DISTRIBUTE BY MURMURHASH(a) TO GROUP NG1; gaussdb=# CREATE TABLE test_murmurhash2 (a int NOT NULL, b int) DISTRIBUTE BY MURMURHASH(lpad_s(a,10,'0')) TO GROUP NG1; --插入数据。 gaussdb=# INSERT INTO test_murmurhash1 VALUES(0,1); gaussdb=# INSERT INTO test_murmurhash2 VALUES(1,2); --查询数据。 gaussdb=# SELECT * FROM test_murmurhash1; a | b ---+--- 0 | 1 (1 row) gaussdb=# SELECT * FROM test_murmurhash2; a | b ---+--- 1 | 2 (1 row) --删除表。 gaussdb=# DROP TABLE test_murmurhash1; gaussdb=# DROP TABLE test_murmurhash2; --删除NODE GROUP。 gaussdb=# DROP NODE GROUP NG1; RANGE --定义一个表,使用RANGE分布(需要根据实际情况修改dn名字,查询dn节点名可以通过语句SELECT node_name FROM PGXC_NODE WHERE node_type = 'D';查询)。 gaussdb=# CREATE TABLE test_range( id INT, name VARCHAR(20), province VARCHAR(60), --省 country VARCHAR(30) DEFAULT 'China' --国籍 )DISTRIBUTE BY RANGE(id)( SLICE s1 VALUES LESS THAN (100) DATANODE dn_6001_6002_6003, SLICE s2 VALUES LESS THAN (200) DATANODE dn_6004_6005_6006, SLICE s3 VALUES LESS THAN (MAXVALUE) DATANODE dn_6007_6008_6009 ); --插入数据。 gaussdb=# INSERT INTO test_range VALUES (52, 'Bob', 'Beijing', 'China'); gaussdb=# INSERT INTO test_range VALUES (100, 'Ben', 'Shanghai', 'China'); gaussdb=# INSERT INTO test_range VALUES (150, 'Scott', 'Guangzhou', 'China'); gaussdb=# INSERT INTO test_range VALUES (300, 'Jordan', 'Beijing', 'China'); --查看数据分布情况。 gaussdb=# SELECT a.count,b.node_name FROM (SELECT COUNT(*) AS count, xc_node_id FROM test_range GROUP BY xc_node_id) a, pgxc_node b WHERE a.xc_node_id=b.node_id ORDER BY a.count DESC; count | node_name -------+------------------- 2 | dn_6004_6005_6006 1 | dn_6001_6002_6003 1 | dn_6007_6008_6009 (3 rows) --查询各dn上存储的数据。 gaussdb=# SELECT b.node_name, a.* FROM (SELECT *, xc_node_id FROM test_range) a, pgxc_node b WHERE a.xc_node_id=b.node_id order by node_name; node_name | id | name | province | country | xc_node_id -------------------+-----+--------+-----------+---------+------------- dn_6001_6002_6003 | 52 | Bob | Beijing | China | -1072999043 dn_6004_6005_6006 | 100 | Ben | Shanghai | China | -564789568 dn_6004_6005_6006 | 150 | Scott | Guangzhou | China | -564789568 dn_6007_6008_6009 | 300 | Jordan | Beijing | China | 1532339558 (4 rows) --删除表。 gaussdb=# DROP TABLE test_range; LIST --定义一个表,使用LIST分布(需要根据实际情况修改dn名字,查询dn节点名可以通过语句SELECT node_name FROM PGXC_NODE WHERE node_type = 'D';查询)。 gaussdb=# CREATE TABLE test_list( id INT, name VARCHAR(20), country VARCHAR(30) DEFAULT 'China' --国籍 )DISTRIBUTE BY LIST(country)( SLICE s1 VALUES ('China') DATANODE dn_6001_6002_6003, SLICE s2 VALUES ('USA') DATANODE dn_6004_6005_6006, SLICE s3 VALUES (DEFAULT) DATANODE dn_6007_6008_6009 ); --插入数据。 gaussdb=# INSERT INTO test_list VALUES (1,'Scott','China'); gaussdb=# INSERT INTO test_list VALUES (2,'Henry','USA'); gaussdb=# INSERT INTO test_list VALUES (3,'Michael','France'); gaussdb=# INSERT INTO test_list VALUES (4,'Jack','UK'); --查询各dn上存储的数据。 gaussdb=# SELECT b.node_name, a.* FROM (SELECT *, xc_node_id FROM test_list) a, pgxc_node b WHERE a.xc_node_id=b.node_id order by node_name; node_name | id | name | country | xc_node_id -------------------+----+---------+--------+------------- dn_6001_6002_6003 | 1 | Scott | China | -1072999043 dn_6004_6005_6006 | 2 | Henry | USA | -564789568 dn_6007_6008_6009 | 3 | Michael | France | 1532339558 dn_6007_6008_6009 | 4 | Jack | UK | 1532339558 (4 rows) --删除表。 gaussdb=# DROP TABLE test_list;
  • 建表示例 创建普通表 gaussdb=# CREATE TABLE tbl_test1( id int, name varchar(50), province varchar (60), --省 country varchar (60) DEFAULT 'China' --国籍 ); gaussdb=# DROP TABLE tbl_test1; WITH子句为表或者索引增加存储参数 --建表指定填充因子。 gaussdb=# CREATE TABLE tbl_test2( id int, name varchar(50), province varchar (60), --省 country varchar (60) DEFAULT 'China' --国籍 ) WITH (FILLFACTOR = 70); --建表指定存储引擎。 gaussdb=# CREATE TABLE tbl_test3( id int, name varchar(50), province varchar (60), --省 country varchar (60) DEFAULT 'China' --国籍 ) WITH (STORAGE_TYPE = ASTORE); --删除。 gaussdb=# DROP TABLE tbl_test2; gaussdb=# DROP TABLE tbl_test3; 临时表 --创建临时表,并指定提交事务时删除该临时表数据。 gaussdb=# CREATE TEMPORARY TABLE test_t2( id CHAR(7), name VARCHAR(20), province VARCHAR(60), --省 country VARCHAR(30) DEFAULT 'China' --国籍 ) ON COMMIT DELETE ROWS; gaussdb=# DROP TABLE test_t2; 建表时指定字符集字符序 --创建前置数据库。 gaussdb=# CREATE DATABASE testdb1 ENCODING = 'UTF8'; gaussdb=# \c testdb1 --创建t1表,设置t1的默认字符集为utf8mb4,默认字符序为utf8mb4_bin,设置c1字段为表的默认字符集字符序,设置c2字段的字符集为utf8mb4,字符序为utf8mb4_unicode_ci。 testdb1=# CREATE TABLE t1(c1 text, c2 text charset utf8mb4 collate utf8mb4_unicode_ci) charset utf8mb4 collate utf8mb4_bin; --删除。 testdb1=# DROP TABLE t1; testdb1=# \c postgres gaussdb=# DROP DATABASE testdb1; IF NOT EXISTS关键字 使用该关键字,表不存在时报NOTICE;如不用该关键字,则报ERROR。两种情况下表都不会创建成功。 gaussdb=# CREATE TABLE test_t3(id INT); --创建一个已经存在同名的表test_t3。 gaussdb=# CREATE TABLE test_t3(id INT); ERROR: Relation test_t3 already exists in schema public. DETAIL: Creating new table with existing name in the same schema. --使用IF NOT EXISTS关键字。 gaussdb=# CREATE TABLE IF NOT EXISTS test_t3(id INT); NOTICE: Relation test_t3 already exists, skipping. CREATE TABLE --删除表。 gaussdb=# DROP TABLE test_t3; 建表时指定表空间 --创建表空间。 gaussdb=# CREATE TABLESPACE ds_tbs1 RELATIVE LOCATION 'tablespace/tablespace_1'; --创建表时,指定表空间。 gaussdb=# CREATE TABLE test(id CHAR(7), name VARCHAR(20)) TABLESPACE ds_tbs1; --删除表和表空间。 gaussdb=# DROP TABLE test; gaussdb=# DROP TABLESPACE ds_tbs1;
  • 语法格式 创建表。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name { ( { column_name data_type [ CHARACTER SET | CHARSET charset ] [ compress_mode ] [ COLLATE collation ] [ column_constraint [ ... ] ] | table_constraint | LIKE source_table [ like_option [...] ] } [, ... ] ) | LIKE source_table } [ table_option [ [ , ] ... ] ] [ htap_option ] [ WITH ( {storage_parameter = value} [, ... ] ) ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS } ] [ ILM ADD POLICY ROW STORE COMPRESS ADVANCED ROW AFTER n { day | month | year } OF NO MODIFICATION [ ON ( EXPR )]] [ TABLESPACE tablespace_name ] [ DISTRIBUTE BY { REPLICATION | HASH ( column_name [, ...] ) | MURMURHASH ( expression ) | KMEANS ( column_name ) distance_type | RANGE ( column_name [, ...] ) { SLICE REFEREN CES tablename | ( slice_less_than_item [, ...] ) | ( slice_start_end_item [, ...] ) } | LIST ( column_name [, ...] ) { SLICE REFERENCES tablename | ( slice_values_item [, ...] ) } } ] [ TO { GROUP groupname | NODE ( nodename [, ... ] ) } ]; 其中table_option为: { COMMENT [ = ] 'string' | AUTO_INCREMENT [ = ] value | [ DEFAULT ] CHARACTER SET | CHARSET [ = ] default_charset | [ DEFAULT ] COLLATE [ = ] default_collation | ENGINE [ = ] { InnoDB | 'InnoDB' | "InnoDB" } } 其中htap_option为: { COLVIEW [ PRIORITY { HIGH | LOW | NONE } ] | NOCOLVIEW [ PRIORITY { HIGH | LOW | NONE } ]} 其中列约束column_constraint为: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [ CONSTRAINT constraint_name ] { NOT NULL | NULL | CHECK ( expression ) | DEFAULT default_expr | ON UPDATE update_expr | GENERATED ALWAYS AS ( generation_expr ) [STORED] | AUTO_INCREMENT | COMMENT 'string' | COLVIEW | NOCOLVIEW | UNIQUE [KEY] index_parameters | PRIMARY KEY index_parameters | ENCRYPTED WITH ( COLUMN_ENCRYPTION_KEY = column_encryption_key, ENCRYPTION_TYPE = encryption_type_value ) | REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] } [ 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 [ index_name ] [ USING method ] ( { { column_name [ ( length ) ] | ( expression ) } [ ASC | DESC ] }[, ... ] ) index_parameters | PRIMARY KEY [ USING method ] ( { column_name [ ASC | DESC ] } [, ... ] ) index_parameters [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] { [ COMMENT 'string' ] [ ... ] } 其中like选项like_option为: 1 { INCLUDING | EXCLUDING } { DEFAULTS | GENERATED | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | PARTITION | RELOPTIONS | DISTRIBUTION | UPDATE | ILM | ALL } 其中索引参数index_parameters为: 1 2 [ WITH ( {storage_parameter = value} [, ... ] ) ] [ USING INDEX TABLESPACE tablespace_name ] 其中距离参数distance_type为: 1 { L2 | COSINE | HAMMING } 其中RANGE分布规则 slice_less_than_item为: SLICE name VALUES LESS THAN ({ expression | MAXVALUE } [, ...]) [ DATANODE datanode_name | ( datanode_name_list [, ... ] ) ] slice_start_end_item为: SLICE name { { START ( expression ) END ( expression ) EVERY ( expression ) } | { START ( literal ) END ( { literal | MAXVALUE } ) } | { START ( literal ) } | { END ( { literal | MAXVALUE } ) } } 其中LIST分布规则slice_values_item为: [ ( SLICE name VALUES (expression [, ... ]) [DATANODE datanode_name | ( datanode_name_list )] [, ... ] ) | ( SLICE name VALUES (DEFAULT) [DATANODE datanode_name] | ( datanode_name_list ) ) ] 其中update_expr为: { CURRENT_TIMESTAMP | LOCALTIMESTAMP | NOW() }
  • 范围分区示例 VALUES LESS THAN --创建表空间。 CREATE TABLESPACE tbs_test_range1_p1 RELATIVE LOCATION 'tbs_test_range1/tablespace_1'; CREATE TABLESPACE tbs_test_range1_p2 RELATIVE LOCATION 'tbs_test_range1/tablespace_2'; CREATE TABLESPACE tbs_test_range1_p3 RELATIVE LOCATION 'tbs_test_range1/tablespace_3'; CREATE TABLESPACE tbs_test_range1_p4 RELATIVE LOCATION 'tbs_test_range1/tablespace_4'; --创建分区表test_range1。 CREATE TABLE test_range1( id INT, info VARCHAR(20) ) PARTITION BY RANGE (id) ( PARTITION p1 VALUES LESS THAN (200) TABLESPACE tbs_test_range1_p1, PARTITION p2 VALUES LESS THAN (400) TABLESPACE tbs_test_range1_p2, PARTITION p3 VALUES LESS THAN (600) TABLESPACE tbs_test_range1_p3, PARTITION pmax VALUES LESS THAN (MAXVALUE) TABLESPACE tbs_test_range1_p4 ); --插入1000条数据 INSERT INTO test_range1 VALUES(GENERATE_SERIES(1,1000),'abcd'); --查看p1分区的行数199条,[1,200)。 SELECT COUNT(*) FROM test_range1 PARTITION (p1); count ------- 199 (1 row) --查看p2分区的行数200条,[200,400)。 SELECT COUNT(*) FROM test_range1 PARTITION (p2); count ------- 200 (1 row) --查看分区信息。 SELECT a.relname, a.boundaries, b.spcname FROM pg_partition a, pg_tablespace b WHERE a.reltablespace = b.oid AND a.parentid = 'test_range1'::regclass; relname | boundaries | spcname ---------+------------+-------------------- p1 | {200} | tbs_test_range1_p1 p2 | {400} | tbs_test_range1_p2 p3 | {600} | tbs_test_range1_p3 pmax | {NULL} | tbs_test_range1_p4 (4 rows) --删除 DROP TABLE test_range1; DROP TABLESPACE tbs_test_range1_p1; DROP TABLESPACE tbs_test_range1_p2; DROP TABLESPACE tbs_test_range1_p3; DROP TABLESPACE tbs_test_range1_p4; START END --创建分区表。 CREATE TABLE test_range2( id INT, info VARCHAR(20) ) PARTITION BY RANGE (id) ( PARTITION p1 START(1) END(600) EVERY(200), PARTITION p2 START(600) END(800), PARTITION pmax START(800) END(MAXVALUE) ); --查看分区信息。 SELECT relname, boundaries FROM pg_partition WHERE parentid = 'test_range2'::regclass AND parttype = 'p' ORDER BY 1; relname | boundaries ---------+------------ p1_0 | {1} p1_1 | {201} p1_2 | {401} p1_3 | {600} p2 | {800} pmax | {NULL} (6 rows) --删除。 DROP TABLE test_range2;
  • 哈希分区示例 --创建哈希分区表,指定分区数。 CREATE TABLE test_hash1(c1 int) PARTITION BY HASH(c1) PARTITIONS 3; --创建哈希分区表,并指定分区名。 CREATE TABLE test_hash2(c1 int) PARTITION BY HASH(C1)( PARTITION pa, PARTITION pb, PARTITION pc ); --查看分区信息。 SELECT b.relname AS table_name, a.relname AS partition_name FROM pg_partition a, pg_class b WHERE b.relname LIKE 'test_hash%' AND a.parttype = 'p' AND a.parentid = b.oid; table_name | partition_name ------------+---------------- test_hash1 | p2 test_hash1 | p1 test_hash1 | p0 test_hash2 | pc test_hash2 | pb test_hash2 | pa (6 rows) --删除。 DROP TABLE test_hash1,test_hash2;
  • 列表分区示例 --创建列表分区表。 CREATE TABLE test_list ( NAME VARCHAR ( 50 ), area VARCHAR ( 50 ) ) PARTITION BY LIST (area) ( PARTITION p1 VALUES ('Beijing'), PARTITION p2 VALUES ('Shanghai'), PARTITION p3 VALUES ('Guangzhou'), PARTITION p4 VALUES ('Shenzhen'), PARTITION pdefault VALUES (DEFAULT) ); --插入数据。 INSERT INTO test_list VALUES ('bob', 'Shanghai'),('scott', 'Sichuan'); --查询分区数据。 SELECT * FROM test_list PARTITION (p2); name | area ------+---------- bob | Shanghai (1 row) SELECT * FROM test_list PARTITION (pdefault); name | area -------+--------- scott | Sichuan (1 row) --删除。 DROP TABLE test_list;
  • 参数说明 IF NOT EXISTS 如果已经存在相同名称的表,不抛出错误,而是发出一个notice,告知表已存在。 partition_table_name 分区表的名称。 取值范围:字符串,要符合标识符命名规范。 column_name 新表中要创建的字段名。 取值范围:字符串,要符合标识符命名规范。 data_type 字段的数据类型。 COLLATE collation COLLATE子句指定列的排序规则(该列必须是可排列的数据类型)。如果没有指定,则使用默认的排序规则。排序规则可以使用“SELECT * FROM pg_collation;”命令从pg_collation系统表中查询,默认的排序规则为查询结果中以default开始的行。 CONSTRAINT constraint_name 列约束或表约束的名称。可选的约束子句用于声明约束,新行或者更新的行必须满足这些约束才能成功插入或更新。 定义约束有两种方法: 列约束:作为一个列定义的一部分,仅影响该列。 表约束:不和某个列绑在一起,可以作用于多个列。在B模式数据库下(即sql_compatibility = 'B')constraint_name为可选项,在其他模式数据库下,必须加上constraint_name。 index_name 索引名。 index_name仅在B模式数据库下(即sql_compatibility = 'B')支持,其他模式数据库下不支持。 对于外键约束,constraint_name和index_name同时指定时,索引名为constraint_name。 对于唯一键约束,constraint_name和index_name同时指定时,索引名以index_name。 USING method 指定创建索引的方法。 取值范围参考参数说明中的USING method。 USING method仅在B模式数据库下(即sql_compatibility = 'B')支持,其他模式数据库下不支持。 在B模式下,未指定USING method时,对于ASTORE的存储方式,默认索引方法为btree;对于USTORE的存储方式,默认索引方法为ubtree。 ASC | DESC ASC表示指定按升序排序(默认)。DESC指定按降序排序。 ASC|DESC只在B模式数据库下(即sql_compatibility = 'B')支持,其他模式数据库不支持。 LIKE source_table [ like_option ... ] LIKE子句声明一个表,新表自动从这个表里面继承所有字段名及其数据类型和非空约束。 新表与原表之间在创建动作完毕之后是完全无关的。在原表做的任何修改都不会传播到新表中,并且也不可能在扫描原表的时候包含新表的数据。 字段缺省表达式只有在声明了INCLUDING DEFAULTS之后才会包含进来。缺省是不包含缺省表达式的,即新表中所有字段的缺省值都是NULL。 如果指定了INCLUDING UPDATE,则原表列的ON UPDATE CURRENT_TIMESTAMP属性会复制到新表列中。默认不复制该属性。 如果指定了INCLUDING GENERATED,则原表列的生成表达式会复制到新表中。默认不复制生成表达式。 非空约束将总是复制到新表中,CHECK约束则仅在指定了INCLUDING CONSTRAINTS的时候才复制,而其他类型的约束则永远也不会被复制。此规则同时适用于表约束和列约束。 被复制的列和约束并不使用相同的名称进行融合。如果明确的指定了相同的名称或者在另外一个LIKE子句中,将会报错。 如果指定了INCLUDING INDEXES,则原表上的索引也将在新表上创建,默认不建立索引。 如果指定了INCLUDING STORAGE,则原表列的STORAGE设置也将被复制,默认情况下不包含STORAGE设置。 如果指定了INCLUDING COMMENTS,则原表列、约束和索引的注释也会被复制过来。默认情况下,不复制源表的注释。 如果指定了INCLUDING RELOPTIONS,则原表的存储参数(即源表的WITH子句)也将复制至新表。默认情况下,不复制源原的存储参数。 如果指定了INCLUDING IDENTITY,则原表的identity功能会复制到新表中,并创建一个与原表SEQUENCE参数相同的SEQUENCE。默认情况下,不复制原表的identity功能。 如果指定了INCLUDING ILM,则源表的ILM策略信息会被复制到新表中,如果需要同时复制源表上的分区对象的ILM策略信息,需要同时指定INCLUDING PARTITION。 INCLUDING ALL包含了INCLUDING DEFAULTS、INCLUDING UPDATE、INCLUDING CONSTRAINTS、INCLUDING INDEXES、INCLUDING STORAGE、INCLUDING COMMENTS、INCLUDING PARTITION、INCLUDING RELOPTIONS、INCLUDING IDENTITY和INCLUDING ILM的内容。 “CREATE TABLE table_name LIKE source_table;”语法仅在B模式数据库(即sql_compatibility = 'B')下,且参数b_format_version值为5.7、b_format_dev_version值为s2时支持。 在B模式数据库下,且参数b_format_version值为5.7、b_format_dev_version值为s2时,不支持指定INCLUDING和EXCLUDING选项,缺省等同于指定INCLUDING ALL。 AUTO_INCREMENT [ = ] value 这个子句为自动增长列指定一个初始值,value必须为正整数,不得超过2127-1。 该子句仅在参数sql_compatibility='B'时有效。 COMMENT [ = ] 'string' COMMENT [ = ] 'string'子句表示给表添加注释。 在column_constraint中的COMMENT 'string'表示给列添加注释。 在table_constraint中的COMMENT 'string'表示给主键和唯一键对应的索引添加注释。 具体请参见:•COMMENT [ = ] 'string'。 CHARACTER SET | CHARSET charset 指定表字段的字符集。单独指定时会将字段的字符序设置为指定的字符集的默认字符序。 仅在B模式数据库下(即sql_compatibility = 'B')支持该语法,其他模式数据库不支持。 COLLATE collation COLLATE子句指定列的排序规则(该列必须是可排列的数据类型)。如果没有指定,则使用默认的排序规则。排序规则可以使用“SELECT * FROM pg_collation”命令从pg_collation系统表中查询,默认的排序规则为查询结果中以default开始的行。对于B模式数据库下(即sql_compatibility = 'B')还支持utf8mb4_bin、utf8mb4_general_ci、utf8mb4_unicode_ci、binary、gbk_chinese_ci、gbk_bin、gb18030_chinese_ci、gb18030_bin字符序。 WITH ( storage_parameter [= value] [, ... ] ) 这个子句为表或索引指定一个可选的存储参数。参数的详细描述如下所示: FILLFACTOR 一个表的填充因子(fillfactor)是一个介于10~100的百分数。在Ustore存储引擎下,该值的默认值为92,在Astore存储引擎下默认值为100(完全填充)。如果指定了较小的填充因子,INSERT操作仅按照填充因子指定的百分率填充表页。每个页上的剩余空间将用于在该页上更新行,这就使得UPDATE有机会在同一页上放置同一条记录的新版本,这比把新版本放置在其他页上更有效。对于一个从不更新的表将填充因子设为100是最佳选择,但是对于频繁更新的表,选择较小的填充因子则更加合适。 取值范围:10~100 ORIENTATION 决定了表的数据的存储方式。 取值范围: ROW(缺省值):表的数据将以行式存储。 orientation不支持修改。 STORAGE_TYPE 指定存储引擎类型,该参数设置成功后就不再支持修改。 取值范围: USTORE,表示表支持Inplace-Update存储引擎。特别需要注意,使用USTORE表,必须要开启track_counts和track_activities参数,否则会引起空间膨胀。 ASTORE,表示表支持Append-Only存储引擎。 默认值: 不指定时,由参数enable_default_ustore_table决定存储引擎方式,默认是Inplace-Update存储。 COMPRESSION 该参数仅支持列存压缩。 segment 使用段页式的方式存储。本参数仅支持行存表。不支持临时表、unlog表。 取值范围:on/off 默认值:off statistic_granularity 记录该表在分析统计信息时的默认partition_mode,partition_mode说明详见ANALYZE|ANALYSE参数说明,此参数对非分区表设置无效。 取值范围:见partition_mode取值范围。 默认值:AUTO。 autovacuum_enabled 自动清理功能是否对该表启用。 取值范围:on/off 默认值:on autovacuum_vacuum_threshold 自动清理功能中,指定在该表中触发VACUUM所需的更新或删除的最小元组数(仅对Astore表生效)。 取值范围:0-2147483647 默认值:-1,缺省时与GUC参数autovacuum_vacuum_threshold一致。 autovacuum_analyze_threshold 自动清理功能中,指定在该表中触发ANALYZE所需的插入、更新或删除的最小元组数。 取值范围:0-2147483647 默认值:-1,缺省时与GUC参数autovacuum_analyze_threshold一致。 autovacuum_vacuum_scale_factor 自动清理功能中,指定在该表中触发VACUUM所需的插入、更新或删除元组的比例(仅对Astore表生效)。 取值范围:0.0-100.0 默认值:-1,缺省时与GUC参数autovacuum_vacuum_scale_factor一致。 autovacuum_analyze_scale_factor 自动清理功能中,指定在该表中触发ANALYZE所需的插入、更新或删除元组的比例。 取值范围:0.0-100.0 默认值:-1,缺省时与GUC参数autovacuum_analyze_scale_factor一致。 autovacuum_freeze_min_age 自动清理功能中,指定在该表参数指定了一个行版本的最小年龄,超过这个年龄的行才会被冻结。 取值范围:0-1000000000 默认值:-1,缺省时与GUC参数vacuum_freeze_min_age一致。 autovacuum_freeze_max_age 自动清理功能中,该表pg_class.relfrozenxid字段在超过多少个事务后,就会强制执行VACUUM操作。即使自动清理被禁用,系统也会启动AUTOVACUUM进程。清理操作还允许从pg_clog/子目录中删除旧文件(仅对Astore表生效)。 取值范围:100000-2000000000 默认值:-1,缺省时与GUC参数autovacuum_freeze_max_age一致。 autovacuum_freeze_table_age 自动清理功能中,该表被标记为不需要自动清理时,它将保持不变的时间。(仅对Astore表生效)。 取值范围:0-2000000000 默认值:-1,缺省时与GUC参数vacuum_freeze_table_age一致。 [ ILM ADD POLICY ROW STORE COMPRESS ADVANCED ROW AFTER n { day | month | year } OF NO MODIFICATION [ ON ( EXPR )]] 创建新表时,可以调用ILM ADD POLICY ROW STORE COMPRESS ADVANCED ROW给行存添加高级压缩策略,分区继承表的策略。 AFTER n { day | month | year } OF NO MODIFICATION :表示n天/月/年没有修改的行。 ON ( EXPR ):行级表达式,用于判断行的冷热。 TABLESPACE tablespace_name 指定新表将要在tablespace_name表空间内创建。如果没有声明,将使用默认表空间。 PARTITION BY RANGE [COLUMNS] (partition_key) 创建范围分区。partition_key为分区键的名称。 COLUMNS关键字只能在sql_compatibility='B'时使用,“PARTITION BY RANGE COLUMNS” 语义同 “PARTITION BY RANGE”。 (1)对于从句是VALUES LESS THAN的语法格式: 对于从句是VALUES LESS THAN的语法格式,范围分区策略的分区键最多支持16列。 该情形下,分区键支持的数据类型为:TINYINT、SMALLINT、INTEGER、BIGINT、DECIMAL、NUMERIC、REAL、DOUBLE PRECISION、CHARACTER VARYING(n)、VARCHAR(n)、CHARACTER(n)、CHAR(n)、CHARACTER、CHAR、TEXT、NVARCHAR、NVARCHAR2、NAME、TIMESTAMP[(p)] [WITHOUT TIME ZONE]、TIMESTAMP[(p)] [WITH TIME ZONE]、DATE。 (2)对于从句是START END的语法格式: 对于从句是START END的语法格式,范围分区策略的分区键仅支持1列。 该情形下,分区键支持的数据类型为:TINYINT、SMALLINT、INTEGER、BIGINT、DECIMAL、NUMERIC、REAL、DOUBLE PRECISION、TIMESTAMP[(p)] [WITHOUT TIME ZONE]、TIMESTAMP[(p)] [WITH TIME ZONE]、DATE。 (3)对于指定了INTERVAL子句的语法格式: 对于指定了INTERVAL子句的语法格式,范围分区策略的分区键仅支持1列。 该情形下,分区键支持的数据类型为:TIMESTAMP[(p)] [WITHOUT TIME ZONE]、TIMESTAMP[(p)] [WITH TIME ZONE]、DATE。 PARTITION partition_name VALUES LESS THAN {( { partition_value | MAXVALUE } [,...] ) | MAXVALUE } 指定各分区的信息。partition_name为范围分区的名称。partition_value为范围分区的上边界,取值依赖于partition_key的类型。MAXVALUE表示分区的上边界,它通常用于设置最后一个范围分区的上边界。 每个分区都需要指定一个上边界。 分区上边界的类型应当和分区键的类型一致。 分区列表是按照分区上边界升序排列的,值较小的分区位于值较大的分区之前。 不在括号内的MAVALUE只能在sql_compatibility='B'时使用,并且只能有一个分区键。 PARTITION partition_name {START (partition_value) END (partition_value) EVERY (interval_value)} | {START (partition_value) END (partition_value|MAXVALUE)} | {START(partition_value)} | {END (partition_value | MAXVALUE)} 指定各分区的信息,各参数意义如下: partition_name:范围分区的名称或名称前缀,除以下情形外(假定其中的partition_name是p1),均为分区的名称。 若该定义是START+END+EVERY从句,则语义上定义的分区的名称依次为p1_1, p1_2, ...。例如对于定义“PARTITION p1 START(1) END(4) EVERY(1)”,则生成的分区是:[1, 2), [2, 3) 和 [3, 4),名称依次为p1_1, p1_2和p1_3,即此处的p1是名称前缀。 若该定义是第一个分区定义,且该定义有START值,则范围(MINVALUE, START)将自动作为第一个实际分区,其名称为p1_0,然后该定义语义描述的分区名称依次为p1_1, p1_2, ...。例如对于完整定义“PARTITION p1 START(1), PARTITION p2 START(2)”,则生成的分区是:(MINVALUE, 1), [1, 2) 和 [2, MAXVALUE),其名称依次为p1_0, p1_1和p2,即此处p1是名称前缀,p2是分区名称。这里MINVALUE表示最小值。 partition_value:范围分区的端点值(起始或终点),取值依赖于partition_key的类型,不可是MAXVALUE。 interval_value:对[START,END) 表示的范围进行切分,interval_value是指定切分后每个分区的宽度,不可是MAXVALUE;如果(END-START)值不能整除以EVERY值,则仅最后一个分区的宽度小于EVERY值。 MAXVALUE:表示最大值,它通常用于设置最后一个范围分区的上边界。 在创建分区表若第一个分区定义含START值,则范围(MINVALUE,START)将自动作为实际的第一个分区。 START END语法需要遵循以下限制: 每个partition_start_end_item中的START值(如果有的话,下同)必须小于其END值; 相邻的两个partition_start_end_item,第一个的END值必须等于第二个的START值; 每个partition_start_end_item中的EVERY值必须是正向递增的,且必须小于(END-START)值; 每个分区包含起始值,不包含终点值,即形如:[起始值,终点值),起始值是MINVALUE时则不包含; 一个partition_start_end_item创建的每个分区所属的TABLESPACE一样; partition_name作为分区名称前缀时,其长度不要超过57字节,超过时自动截断; 在创建、修改分区表时请注意分区表的分区总数不可超过最大限制(1048575); 在创建分区表时START END与LESS THAN语法不可混合使用。 即使创建分区表时使用START END语法,备份(gs_dump)出的SQL语句也是VALUES LESS THAN语法格式。 INTERVAL (interval_expr) [ STORE IN (tablespace_name [, ... ] ) ] 间隔分区定义信息。 interval_expr:自动创建分区的间隔,需要符合partition_key的字段类型,目前只支持数值类型和日期/时间类型,例如:1 day、1 month。 STORE IN (tablespace_name [, ... ] ):指定存放自动创建分区的表空间列表,如果有指定,则自动创建的分区从表空间列表中循环选择使用,否则使用分区表默认的表空间。 PARTITION BY LIST [COLUMNS] (partition_key) 创建列表分区。partition_key为分区键的名称。 COLUMNS关键字只能在sql_compatibility='B'时使用,“PARTITION BY LIST COLUMNS” 语义同 “PARTITION BY LIST”。 对于partition_key,列表分区策略的分区键最多支持16列。 对于从句是VALUES [IN] (list_values)的语法格式,list_values中包含了对应分区存在的键值,每个分区的键值数量不超过64个。 从句"VALUES IN"只能在sql_compatibility='B'时使用,语义同"VALUES"。 分区键支持的数据类型为:TINYINT、SMALLINT、INTEGER、BIGINT、NUMERIC、VARCHAR(n)、CHAR、BPCHAR、NVARCHAR、NVARCHAR2、TIMESTAMP[(p)] [WITHOUT TIME ZONE]、TIMESTAMP[(p)] [WITH TIME ZONE]、DATE。分区个数不能超过1048575个。 PARTITION BY HASH(partition_key) 创建哈希分区。partition_key为分区键的名称。 对于partition_key,哈希分区策略的分区键仅支持1列。 分区键支持的数据类型为:TINYINT、SMALLINT、INTEGER、BIGINT、NUMERIC、VARCHAR(n)、CHAR、BPCHAR、TEXT、NVARCHAR、NVARCHAR2、TIMESTAMP[(p)] [WITHOUT TIME ZONE]、TIMESTAMP[(p)] [WITH TIME ZONE]、DATE。分区个数不能超过1048575个。 PARTITION BY KEY(partition_key) 只能在sql_compatibility='B'时使用,语义同“PARTITION BY HASH(partition_key)”。 AUTOMATIC 创建新表时,若指定关键字AUTOMATIC,则开启列表分区的自动扩展功能,缺省时表示不开启自动扩展功能。只有列表分区可以使用自动扩展功能。 开启自动扩展功能后,当插入数据无法匹配到已有分区时,会自动创建一个单独的分区。 PARTITIONS integer 指定分区个数。 integer为分区数,必须为大于0的整数,且不得大于1048575。 当在RANGE和LIST分区后指定此子句时,必须显式定义每个分区,且定义分区的数量必须与integer值相等。只能在sql_compatibility='B'时在RANGE和LIST分区后指定此子句。 当在HASH和KEY分区后指定此子句时,若不列出各个分区定义,将自动生成integer个分区,自动生成的分区名为“p+数字”,数字依次为0到integer-1,分区的表空间默认为此表的表空间;也可以显式列出每个分区定义,此时定义分区的数量必须与integer值相等。若既不列出分区定义,也不指定分区数量,将创建唯一一个分区。 { ENABLE | DISABLE } ROW MOVEMENT 行迁移开关。 如果进行UPDATE操作时,更新了元组在分区键上的值,造成了该元组所在分区发生变化,就会根据该开关给出报错信息,或者进行元组在分区间的转移。 取值范围: ENABLE(缺省值):行迁移开关打开。 DISABLE:行迁移开关关闭。 在打开行迁移开关情况下,并发UPDATE、DELETE操作可能会报错,原因如下: UPDATE和DELETE操作对于旧数据都是标记为已删除。在打开行迁移开关情况下,如果更新分区键时,导致了跨分区更新,内核会把旧分区中旧数据标记为已删除,在新分区中新增加一条数据,无法通过旧数据找到新数据。 在UPDATE和UPDATE并发、DELETE和DELETE并发、UPDATE和DELETE并发三个并发场景下,如果并发操作同一行数据时,数据跨分区和非跨分区结果有不同的行为。 对于数据非跨分区结果,第一个操作执行完后,第二个操作不会报错。 如果第一个操作是UPDATE,第二个操作能成功找到最新的数据,之后对新数据操作。 如果第一个操作是DELETE,第二个操作看到当前数据已经被删除而且找不到最新数据,就终止操作。 对于数据跨分区结果,第一个操作执行完后,第二个操作会报错。 如果第一个操作是UPDATE,由于新数据在新分区中,第二个操作不能成功找到最新的数据,就无法操作,之后会报错。 如果第一个操作是DELETE,第二个操作看到当前数据已经被删除而且找不到最新数据,但无法判断删除旧数据的操作是UPDATE还是DELETE。如果是UPDATE,报错处理。如果是DELETE,终止操作。为了保持数据的正确性,只能报错处理。 如果是UPDATE和UPDATE并发,UPDATE和DELETE并发场景,需要串行执行才能解决问题,如果是DELETE和DELETE并发,关闭行迁移开关可以解决问题。
  • 功能描述 创建分区表。分区表是把逻辑上的一张表根据某种方案分成几张物理块进行存储,这张逻辑上的表称之为分区表,物理块称之为分区。分区表是一张逻辑表,不存储数据,数据实际是存储在分区上的。 常见的分区方案有范围分区(Range Partitioning)、间隔分区(Interval Partitioning)、哈希分区(Hash Partitioning)、列表分区(List Partitioning)、数值分区(Value Partitioning)等。目前行存表支持范围分区、间隔分区、哈希分区、列表分区。 范围分区是根据表的一列或者多列,将要插入表的记录分为若干个范围,这些范围在不同的分区里没有重叠。为每个范围创建一个分区,用来存储相应的数据。 范围分区的分区策略是指记录插入分区的方式。目前范围分区仅支持范围分区策略。 范围分区策略:根据分区键值将记录映射到已创建的某个分区上,如果可以映射到已创建的某一分区上,则把记录插入到对应的分区上,否则给出报错和提示信息。这是最常用的分区策略。 间隔分区是一种特殊的范围分区,相比范围分区,新增间隔值定义,当插入记录找不到匹配的分区时,可以根据间隔值自动创建分区。 间隔分区只支持基于表的一列分区,并且该列只支持TIMESTAMP[(p)] [WITHOUT TIME ZONE]、TIMESTAMP[(p)] [WITH TIME ZONE]、DATE数据类型。 间隔分区策略:根据分区键值将记录映射到已创建的某个分区上,如果可以映射到已创建的某一分区上,则把记录插入到对应的分区上,否则根据分区键值和表定义信息自动创建一个分区,然后将记录插入新分区中,新创建的分区数据范围等于间隔值。 哈希分区是根据表的一列,为每个分区指定模数和余数,将要插入表的记录划分到对应的分区中,每个分区所持有的行都需要满足条件:分区键的值除以为其指定的模数将产生为其指定的余数。 哈希分区策略:根据分区键值将记录映射到已创建的某个分区上,如果可以映射到已创建的某一分区上,则把记录插入到对应的分区上,否则返回报错和提示信息。 列表分区是根据表的一列,将要插入表的记录通过每一个分区中出现的键值划分到对应的分区中,这些键值在不同的分区里没有重叠。为每组键值创建一个分区,用来存储相应的数据。 列表分区策略:根据分区键值将记录映射到已创建的某个分区上,如果可以映射到已创建的某一分区上,则把记录插入到对应的分区上,否则给出报错和提示信息。 分区可以提供若干好处: 某些类型的查询性能可以得到极大提升。特别是表中访问率较高的行位于一个单独分区或少数几个分区上的情况下。分区可以减少数据的搜索空间,提高数据访问效率。 当查询或更新一个分区的大部分记录时,连续扫描该分区而不是访问整个表可以获得巨大的性能提升。 如果需要大量加载或者删除的记录位于单独的分区上,则可以通过直接读取或删除该分区以获得巨大的性能提升,同时还可以避免由于大量DELETE导致的VACUUM超载(哈希分区不支持删除分区)。
  • 语法格式 CREATE TABLE [ IF NOT EXISTS ] partition_table_name { ( [ { column_name data_type [ CHARACTER SET | CHARSET charset ] [ COLLATE collation ] [ column_constraint [ ... ] ] | table_constraint | LIKE source_table [ like_option [...] ] } [, ... ] ] ) | LIKE source_table } [ table_option [ [ , ] ... ] ] [ htap_option ] [ WITH ( {storage_parameter = value} [, ... ] ) ] [ ILM ADD POLICY ROW STORE COMPRESS ADVANCED ROW AFTER n { day | month | year } OF NO MODIFICATION [ ON ( EXPR )]] [ TABLESPACE tablespace_name ] PARTITION BY { {RANGE [COLUMNS] (partition_key) [ INTERVAL (interval_expr) [ STORE IN (tablespace_name [, ... ] ) ] ] [ PARTITIONS integer ] ( partition_less_than_item [, ... ] )} | {RANGE [COLUMNS] (partition_key) [ INTERVAL (interval_expr) [ STORE IN (tablespace_name [, ... ] ) ] ] [ PARTITIONS integer ] ( partition_start_end_item [, ... ] )} | {LIST [COLUMNS] (partition_key) [ AUTOMATIC ] [ PARTITIONS integer ] ( PARTITION partition_name VALUES [IN] (list_values) [ ILM ADD POLICY ROW STORE COMPRESS ADVANCED ROW AFTER n { day | month | year } OF NO MODIFICATION [ ON ( EXPR )]] [ { COLVIEW | NOCOLVIEW } [ PRIORITY { HIGH | LOW | NONE } ] ][TABLESPACE [=] tablespace_name ][, ... ])} | {{ HASH | KEY } (partition_key) [ PARTITIONS integer ] ( PARTITION partition_name [ ILM ADD POLICY ROW STORE COMPRESS ADVANCED ROW AFTER n { day | month | year } OF NO MODIFICATION [ ON ( EXPR )]] [ { COLVIEW | NOCOLVIEW } [ PRIORITY { HIGH | LOW | NONE } ] ][TABLESPACE [=] tablespace_name ][, ... ])} } [ { ENABLE | DISABLE } ROW MOVEMENT ]; 其中table_option为: { COMMENT [ = ] 'string' | AUTO_INCREMENT [ = ] value | [ DEFAULT ] CHARACTER SET | CHARSET [ = ] default_charset | [ DEFAULT ] COLLATE [ = ] default_collation | ENGINE [ = ] { InnoDB | 'InnoDB' | "InnoDB" } } 其中htap_option为: { COLVIEW [ PRIORITY { HIGH | LOW | NONE } ] | NOCOLVIEW [ PRIORITY { HIGH | LOW | NONE } ]} 列约束column_constraint: [ CONSTRAINT constraint_name ] { NOT NULL | NULL | CHECK ( expression ) | DEFAULT default_expr | ON UPDATE update_expr | GENERATED ALWAYS AS ( generation_expr ) [STORED] | GENERATED [ ALWAYS | BY DEFAULT [ ON NULL ] ] AS IDENTITY [ ( identity_options ) ] | AUTO_INCREMENT | COMMENT 'string' | COLVIEW | NOCOLVIEW | UNIQUE [KEY] index_parameters | PRIMARY KEY index_parameters | REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] } [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] 表约束table_constraint: [ CONSTRAINT [ constraint_name ] ] { CHECK ( expression ) | UNIQUE [ index_name ][ USING method ] ( { column_name [ ASC | DESC ] } [, ... ] ) index_parameters | PRIMARY KEY [ USING method ] ( { column_name [ ASC | DESC ] } [, ... ] ) index_parameters | FOREIGN KEY [ index_name ] ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] } [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] { [ COMMENT 'string' ] [ ... ] } like选项like_option: { INCLUDING | EXCLUDING } { DEFAULTS | GENERATED | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | RELOPTIONS| UPDATE | IDENTITY | ILM | ALL } 索引存储参数index_parameters: [ WITH ( {storage_parameter = value} [, ... ] ) ] [ USING INDEX TABLESPACE tablespace_name ]
  • 注意事项 唯一约束和主键约束的约束键包含所有分区键将为约束创建LOCAL索引,否则创建GLOBAL索引。 目前哈希分区仅支持单列构建分区键,暂不支持多列构建分区键。 只需要有间隔分区表的INSERT权限,往该表INSERT数据时就可以自动创建分区。 对于分区表PARTITION FOR (values)语法,values只能是常量。 对于分区表PARTITION FOR (values)语法,values在需要数据类型转换时,建议使用强制类型转换,以防隐式类型转换结果与预期不符。 分区数最大值为1048575个,一般情况下业务不可能创建这么多分区,这样会导致内存不足。应参照参数local_syscache_threshold的值合理创建分区,分区表使用内存大致为(分区数 * 3 / 1024)MB。理论上分区占用内存不允许大于local_syscache_threshold的值,同时还需要预留部分空间以供其他功能使用。 考虑性能影响,一般建议单表最大分区数不超过2000,子分区数 *(LOCAL索引个数 + 1) 不超过10000。 当分区数太多导致内存不足时,会间接导致性能急剧下降。 指定分区语句目前不能走全局索引扫描。 不支持XML类型数据作为分区键、二级分区键。 在为数据对象增加或者变更ILM策略的时候,如果追加了行级表达式,需要注意行表达式目前只支持白名单中列出的函数。具体白名单函数列表参考行表达式函数白名单。
  • 参数说明 OR REPLACE 当存在同名的存储过程时,替换原来的定义。 procedure_name 创建的存储过程名称,可以带有模式名。 取值范围:字符串,要符合标识符命名规范。 建议不要创建和系统函数重名的函数,否则调用时需要指定函数的schema。 argmode 参数的模式。 VARIADIC用于声明数组类型的参数。 取值范围: IN,OUT,INOUT或VARIADIC。缺省值是IN。只有OUT模式的参数后面能跟VARIADIC。并且OUT和INOUT模式的参数不能用在RETURNS TABLE的过程定义中。 argname 参数的名称。 取值范围:字符串,要符合标识符命名规范。 argtype 参数的数据类型。可以使用%ROWTYPE间接引用表的类型,或者使用%TYPE间接引用表或复合类型中某一列的类型。 取值范围:可用的数据类型。 argname和argmode的顺序没有严格要求,推荐按照argname、argmode、argtype的顺序使用。 expression 参数的默认表达式。 在参数a_format_version值为10c和a_format_dev_version值为s2的情况下,参数为INOUT模式时不支持默认表达式。 推荐使用方式:将所有默认值参数定义在所有非默认值参数后。 调用带有默认参数的函数时,入参从左往右排入函数,如果有非默认参数的入参缺失则报错。 打开 proc_uncheck_default_param 参数,调用带有默认参数的函数时,入参从左往右排入函数,允许缺省默认参数个入参,如果有非默认参数的入参缺失,则会用错位的默认值填充该参数。 在参数a_format_version值为10c、a_format_dev_version值为s1和关闭proc_outparam_override,函数参数同时包括out出参和default时,默认值不可缺省。 IMMUTABLE、STABLE等 行为约束可选项。各参数的功能与CREATE FUNCTION类似,详细说明见CREATE FUNCTION plsql_body PL/SQL存储过程体。 创建一个存储过程时,plsql_body支持以“END;”或“END procedure_name;”两种形式结尾。 以“END procedure_name;”结尾时遵循以下约束: 仅ORA兼容模式(数据库级别)下支持使用。 仅支持ORA风格创建语法。 仅支持END后设置存储过程名称的场景。 创建的存储过程在DBE_PLDEVELOPER.gs_source、my_source、db_source、adm_source视图中显示与存储过程创建时定义相同(创建时“END+名称”则显示“END+名称”);在pg_proc视图以及\sf查看时,最外层END后在任何情况下都不跟名称,内部则按照创建时定义(创建时“END+名称”则显示“END+名称”)显示。 gs_dump生成的sql文件,存储过程无法保留最外层END后名称。 以IF/LOOP命名存储过程或嵌套子程序时,不支持以END IF/LOOP结束存储过程。 当在存储过程体中进行创建用户、修改密码或加解密等涉及密码或密钥相关操作时,系统表及日志中会记录密码或密钥的明文信息。为防止敏感信息泄露,不建议用户在存储过程体中进行涉及密码或密钥等敏感信息的相关操作。
  • 注意事项 如果创建存储过程时参数或返回值带有精度,不进行精度检测。 创建存储过程时,存储过程定义中对表对象的操作建议都显示指定模式,否则可能会导致存储过程执行异常。 创建存储过程时,仅对CREATE的存储过程或PACKAGE本身加写锁,仅对执行过程中编译、执行会对函数和函数依赖的PACKAGE均加读锁。 创建存储过程时,存储过程内部通过SET语句设置current_schema和search_path无效。执行完函数search_path和current_schema与执行函数前的search_path和current_schema保持一致。 SELECT、CALL调用函数时,必须要在出参位置提供实参进行调用,实参不会发生作用。 存储过程指定package属性时支持重载。 不能创建仅形参名字不同(存储过程名和参数列表类型都一样)的重载存储过程。 不能创建与函数拥有相同名称和参数列表的存储过程。 不支持仅默认值不同的存储过程重载。 存储过程仅in、out、inout这三种类型不同的参数,打开GUC参数behavior_compat_options(behavior_compat_options='proc_outparam_override')后,不允许重载。关闭该参数后,可以重载。 ORA兼容模式的数据库,建立ORA风格的函数;PG兼容模式的数据库,建立PG风格的函数。不建议混合创建。 函数如果支持重载,需要添加PACKAGE关键字。 重载的存储过程在调用时变量需要明确具体的类型。 在存储过程内部使用未声明的变量,存储过程被调用时会报错。 在创建procedure时,不能在avg函数外面嵌套其他agg函数,或者其他系统函数。 函数定义时如果指定为IMMUTABLE和SHIPPABLE类型,应该尽量避免函数中存在INSERT,UPDATE,DELETE,MERGE和DDL操作,因为上述操作应该由CN判断对应的执行节点,否则执行结果可能产生错误。 存储过程中不支持需要return集合的操作。 在存储过程内部调用其它无参数的存储过程时,可以省略括号,直接使用存储过程名进行调用。 在存储过程内部调用其他有出参的函数,如果在赋值表达式中调用时,需要打开guc参数 set behavior_compat_options = 'proc_outparam_override' ,并提前定义与出参类型相同的变量,然后将变量作为出参调用带有出参的其他函数,出参才能生效。否则,被调函数的出参会被忽略。 存储过程支持参数注释的查看与导出、导入。 存储过程支持介于IS/AS与plsql_body之间的注释的查看与导出、导入。 被授予CREATE ANY FUNCTION权限的用户,可以在用户模式下创建/替换存储过程。 out/inout参数必须传入变量,不能传入常量。 存储过程默认为SECURITY INVOKER权限,如果想将默认行为改为SECURITY DEFINER权限,需要设置guc参数behavior_compat_options='plsql_security_definer'。 如果将定义者权限的存储过程创建到其他用户Schema下,则会以其他用户的权限执行该存储过程,有越权风险,请谨慎使用。 在表达式中使用out参数作为出参时,如下情况不会生效,例如:使用execute immediate sqlv using func语法执行函数、使用select func into语法执行函数、使用insert、update等DML语句执行以及带out出参的函数作为入参时,fun(func(out b),a),out出参b未生效等。 在存储过程内部函数复杂调用,如:func(x).a,函数调用返回复合类型,支持跨schema调用,不支持通过database.schema.package.func(x).b的方式调用。 调用带out出参的存储过程,设置GUC参数set behavior_compat_options = 'proc_outparam_transfer_length'后可以传递参数长度。规格限制如下: 支持的基本类型包括:CHAR(n)、CHARACTER(n)、NCHAR(n)、VARCHAR(n)、VARYING(n)、VARCHAR2(n)、NVARCHAR2(n)。 out出参不生效的情况下(比如perform)不需要传递长度。 不支持精度传递的基本类型包括:NUMERIC、DECIMAL、NUMBER、FLOAT、DEC、INTEGER、TIME、TIMESTAMP、INTERVAL、TIME WITH TIME ZONE、TIMESTAMP WITH TIME ZONE、TIME WITHOUT TIME ZONE、TIMESTAMP WITHOUT TIME ZONE。 无论GUC参数set behavior_compat_options是否设置为proc_outparam_override都支持传递参数长度。 要传递集合类型的元素长度和被集合类型嵌套的数组类型的元素长度需要在GUC参数behavior_compat_options里同时开启tableof_elem_constraints选项。 函数中存在通过GUC参数控制特性的语法、函数等,如果在会话内更改相关GUC参数,修改参数后,调用函数可能会维持修改前的行为,请谨慎变更GUC参数。
  • 语法格式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 CREATE [ OR REPLACE ] PROCEDURE procedure_name [ ( {[ argname ] [ argmode ] 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 | SET configuration_parameter { [ TO | = ] value | FROM CURRENT } ][ ... ] { IS | AS } plsql_body /
  • 功能描述 在当前数据库中定义一种新的数据类型。定义数据类型的用户将成为该数据类型的拥有者。类型只适用于行存表。 有五种形式的CREATE TYPE,分别为:复合类型、基本类型、shell类型、枚举类型和集合类型。 复合类型 复合类型由一个属性名和数据类型的列表指定。如果属性的数据类型是可排序的,也可以指定该属性的排序规则。复合类型本质上和表的行类型相同,但是如果只想定义一种类型,使用CREATE TYPE避免了创建一个实际的表。单独的复合类型也是很有用的,例如可以作为函数的参数或者返回类型。 为了能够创建复合类型,必须拥有在其所有属性类型上的USAGE特权。 基本类型 用户可以自定义一种新的基本类型(标量类型)。通常来说这些函数必须是底层语言所编写。 shell类型 shell类型是一种用于后面要定义的类型的占位符,通过发出一个不带除类型名之外其他参数的CREATE TYPE命令可以创建这种类型。在创建基本类型时,需要shell类型作为一种向前引用。 枚举类型 由若干个标签构成的列表,每一个标签值都是一个非空字符串,且字符串长度必须不超过63个字节。 集合类型 类似数组,但是没有长度限制,主要在存储过程中使用。 被授予CREATE ANY TYPE权限的用户,可以在public模式和用户模式下创建类型。