华为云用户手册

  • 层级权限管理 GaussDB (DWS)通过Database、Schema和数据对象权限实现层级权限管理。 Database之间无法直接互访,通过连接隔离实现彻底的权限隔离。各个Database之间共享资源极少,可实现连接隔离、权限隔离等。数据库集群包含一个或多个已命名数据库。用户和角色在整个集群范围内是共享的,但是其数据并不共享。即用户可以连接任何数据库,但当连接成功后,任何用户都只能访问连接请求里所声明的数据库。 Schema隔离的方式共用资源较多,可以通过GRANT与REVOKE语法便捷地控制不同用户对各Schema及其下属对象的权限,从而赋给业务更多的灵活性。每个数据库包括一个或多个Schema。每个Schema包含表、函数等其他类型的对象。用户要访问包含在指定Schema中的对象,需要被授予Schema的USAGE权限。 对象创建后,默认只有对象所有者或者系统管理员可以查询、修改和删除对象。其他用户要访问包含具体的数据库对象,例如table1,需要首先被授予database的CONNECT权限,再被授予Schema的USAGE权限,最后授予table1的SELECT权限。用户要访问底层的对象,必须先赋予上层对象的权限。比如用户要创建或者删除Schema,需要首先被授予database的CREATE权限; 图1 层级权限管理
  • 角色 GaussDB(DWS)的权限管理模型,是一种典型的RBAC(基于角色的权限控制)的实现。其将用户、角色、权限通过此模型管理起来。 角色是一组权限的集合。 “用户”概念和“角色”概念实际是等同的,唯一的区别在于“用户”拥有login权限,而“角色”拥有nologin权限。 按照数据库系统中承担的责任划分具有不同权限的角色。角色是数据库权限的集合,代表了一个数据库用户、或一组数据用户的行为约束。 角色和用户可以转换,通过ALTER将角色拥有登录权限。 通过GRANT把角色授予用户后,用户即具有了角色的所有权限。推荐使用角色进行高效权限分配。例如,可以为设计、开发和维护人员创建不同的角色,将角色GRANT给用户后,再向每个角色中的用户授予其所需数据的差异权限。在角色级别授予或撤销权限时,这些权限更改会对角色下的所有成员生效。 非三权分立时,只有系统管理员和具有CREATEROLE属性的用户才能创建、修改或删除角色。三权分立下,只有具有CREATEROLE属性的用户才能创建、修改或删除角色。 要查看所有角色,请查询系统表PG_ROLES: 1 SELECT * FROM PG_ROLES; 具体的创建,修改和删除角色操作,可参考《SQL语法参考》中“CREATE ROLE/ALTER ROLE/DROP ROLE”章节。
  • 预置角色 GaussDB(DWS)提供了一组预置角色,以“gs_role_”开头命名,提供对特定的、通常需要高权限的操作的访问,可以将这些角色授权予数据库中的其他用户或角色,使这些用户能够访问或使用特定的信息和功能。请谨慎使用预置角色,以确保预置角色权限的安全使用。 预置角色允许的权限范围可参考下表: 表1 预置角色允许的权限范围 角色 权限描述 gs_role_signal_backend 具有调用函数pg_cancel_backend、pg_terminate_backend、pg_terminate_query、pg_cancel_query、pgxc_terminate_query、pgxc_cancel_query来取消或终止其他会话的权限,但不能操作属于初始用户的会话。 gs_role_read_all_stats 读取系统状态视图并且使用与扩展相关的各种统计信息,包括有些通常只对系统管理员可见的信息。包括: 资源管理类: pgxc_wlm_operator_history pgxc_wlm_operator_info pgxc_wlm_operator_statistics pgxc_wlm_session_info pgxc_wlm_session_statistics pgxc_wlm_workload_records pgxc_workload_sql_count pgxc_workload_sql_elapse_time pgxc_workload_transaction 状态信息类: pgxc_stat_activity pgxc_get_table_skewness table_distribution pgxc_total_memory_detail pgxc_os_run_info pg_nodes_memory pgxc_instance_time pgxc_redo_stat gs_role_analyze_any 具有系统级ANALYZE权限类似系统管理员用户,跳过schema权限检查,对所有的表可以执行ANALYZE。 gs_role_vacuum_any 具有系统级VACUUM权限类似系统管理员用户,跳过schema权限检查,对所有的表可以执行VACUUM。 预置角色的使用约束: 以gs_role_开头的角色名作为数据库的预置角色保留字,禁止新建以“gs_role_”开头的用户/角色,也禁止将已有的用户/角色重命名为以“gs_role_”开头。 禁止对预置角色执行ALTER和DROP操作。 预置角色默认没有 LOG IN权限,不设置预置登录密码。 gsql元命令\du和\dg不显示预置角色的相关信息,但若指定了PATTERN(用来指定要被显示的对象名称)则预置角色信息会显示。 三权分立关闭时,系统管理员和具有预置角色ADMIN OPTION权限的用户有权对预置角色执行GRANT/REVOKE管理;三权分立打开时,安全管理员(具有CREATEROLE属性)和具有预置角色ADMIN OPTION权限的用户有权对预置角色执行GRANT/REVOKE管理。例如: 1 2 GRANT gs_role_signal_backend TO user1; REVOKE gs_role_signal_backend FROM user1;
  • 定时任务管理 创建测试表: 1 CREATE TABLE test(id int, time date); 当结果显示为如下信息,则表示创建成功。 1 CREATE TABLE 创建自定义存储过程: 1 2 3 4 5 6 7 8 9 CREATE OR REPLACE PROCEDURE PRC_JOB_1() AS N_NUM integer :=1; BEGIN FOR I IN 1..1000 LOOP INSERT INTO test VALUES(I,SYSDATE); END LOOP; END; / 当结果显示为如下信息,则表示创建成功。 1 CREATE PROCEDURE 创建任务: 新创建的任务(未指定job_id)表示每隔1分钟执行一次存储过程PRC_JOB_1。 1 2 3 4 5 call dbms_job.submit('call public.prc_job_1(); ', sysdate, 'interval ''1 minute''', :a); job ----- 1 (1 row) 指定job_id创建任务。 1 2 3 4 5 call dbms_job.isubmit(2,'call public.prc_job_1(); ', sysdate, 'interval ''1 minute'''); isubmit --------- (1 row) 通过USER_JOBS视图查看当前用户已创建的任务信息。 需要有系统管理员权限才可以访问此系统视图,字段说明详见表1。 1 2 3 4 5 6 7 8 9 10 select job,dbname,start_date,last_date,this_date,next_date,broken,status,interval,failures,what from user_jobs; job | dbname | start_date | last_date | this_date | next_date | broken | status | interval | failures | what -----+----------+----------------------------+----------------------------+----------------------------+---------------------+--------+--------+---------------------+----------+---------------- ----------- 1 | db_demo | 2022-03-25 07:58:01.829436 | 2022-03-25 07:58:03.174817 | 2022-03-25 07:58:01.829436 | 2022-03-25 07:59:01 | n | s | interval '1 minute' | 0 | call public.prc _job_1(); 2 | db_demo | 2022-03-25 07:58:15.893383 | 2022-03-25 07:58:16.608959 | 2022-03-25 07:58:15.893383 | 2022-03-25 07:59:15 | n | s | interval '1 minute' | 0 | call public.prc _job_1(); (2 rows) 停止任务。 1 2 3 4 5 call dbms_job.broken(1,true); broken -------- (1 row) 启动任务。 1 2 3 4 5 call dbms_job.broken(1,false); broken -------- (1 row) 修改任务属性。 修改JOB的Next_date参数信息。例如,修改Job1的Next_date为1小时以后开始执行。 1 2 3 4 5 call dbms_job.next_date(1, sysdate+1.0/24); next_date ----------- (1 row) 修改JOB的Interval参数信息。例如,修改Job1的Interval为每隔1小时执行一次。 1 2 3 4 5 call dbms_job.interval(1,'sysdate + 1.0/24'); interval ---------- (1 row) 修改JOB的What参数信息。例如,修改Job1的What为执行SQL语句“insert into public.test values(333, sysdate+5);”。 1 2 3 4 5 call dbms_job.what(1,'insert into public.test values(333, sysdate+5);'); what ------ (1 row) 同时修改JOB的Next_date、Interval、What等多个参数信息。 1 2 3 4 5 call dbms_job.change(1, 'call public.prc_job_1();', sysdate, 'interval ''1 minute'''); change -------- (1 row) 删除JOB。 1 2 3 4 5 call dbms_job.remove(1); remove -------- (1 row) JOB的权限控制。 当创建一个JOB时,该JOB会和创建该JOB的数据库和用户绑定(即:pg_job系统视图新增的JOB记录中的dbname和log_user)。 如果当前用户是DBA用户、系统管理员、该JOB的创建用户(即:pg_job中的log_user),那么该用户有权限通过高级包接口remove、change、next_data、what、interval删除或修改JOB的参数信息。否则,会提示当前用户没有权限操作该JOB。 如果当前数据库是该JOB创建所属的数据库(即:为pg_job系统视图中的dbname),那么连接到当前数据库上可以通过高级包接口remove、change、next_data、what、interval删除或修改JOB的参数信息。 当删除JOB所属的数据库(即:为pg_job系统视图中的dbname)时,系统会关联删除该数据库从属的JOB记录。 当删除JOB所属的用户(即:为pg_job系统视图中的log_user)时,系统会关联删除该用户从属的JOB记录。
  • 修改一个序列 ALTER SEQUENCE命令更改现有序列的属性,包括修改拥有者、归属列和最大值。 指定序列与列的归属关系。 将序列和一个表的指定字段进行关联。在删除那个字段或其所在表的时候会自动删除已关联的序列。 1 ALTER SEQUENCE seq1 OWNED BY T2.id; 将序列serial的最大值修改为300: 1 ALTER SEQUENCE seq1 MAXVALUE 300;
  • 创建序列 方法一: 声明字段类型为序列整型来定义标识符字段。例如: 1 2 3 4 5 CREATE TABLE T1 ( id serial, name text ); 方法二: 创建序列,并通过nextval('sequence_name')函数指定为某一字段的默认值。这种方式更灵活,可以为序列定义cache,一次预申请多个序列值,减少与GTM的交互次数,来提高性能。 创建序列 1 CREATE SEQUENCE seq1 cache 100; 指定为某一字段的默认值,使该字段具有唯一标识属性。 1 2 3 4 5 CREATE TABLE T2 ( id int not null default nextval('seq1'), name text ); 除了为序列指定了cache,方法二所实现的功能基本与方法一类似。但是一旦定义cache,序列将会产生空洞(序列值为不连贯的数值,如:1.4.5),并且不能保序。另外为某序列指定从属列后,该列删除,对应的sequence也会被删除。 虽然数据库并不限制序列只能为一列产生默认值,但最好不要多列共用同一个序列。 当前版本只支持在定义表的时候指定自增列,或者指定某列的默认值为nextval('seqname'), 不支持在已有表中增加自增列或者增加默认值为nextval('seqname')的列。
  • 注意事项 新序列值的产生是靠GTM维护的,默认情况下,每申请一个序列值都要向GTM发送一次申请,GTM在当前值的基础上加上步长值作为产生的新值返回给调用者。GTM作为全局唯一的节点,势必成为性能的瓶颈,所以对于需要大量频繁产生序列号的操作,如使用Bulkload(批量快速导入数据)功能进行数据导入场景,是非常不推荐产生默认序列值的。比如,在下面所示的场景中, INSERT FROM SELECT语句的性能会非常慢。 1 2 3 4 5 6 7 CREATE SEQUENCE newSeq1; CREATE TABLE newT1 ( id int not null default nextval('newSeq1'), name text ); INSERT INTO newT1(name) SELECT name from T1; 可以提高性能的写法是(假设T1表导入newT1表中的数据为10000行): 1 2 INSERT INTO newT1(id, name) SELECT id,name from T1; SELECT SETVAL('newSeq1',10000); 序列操作函数nextval(),setval() 等均不支持回滚。另外setval设置的新值,会对当前会话的nextval立即生效,但对其他会话,如果定义了cache,不会立即生效,在用尽所有缓存的值后,其变动才被其他会话感知。所以为了避免产生重复值,要谨慎使用setval,设置的新值不能是已经产生的值或者在缓存中的值。 如果必须要在bulkload场景下产生默认序列值,则一定要为newSeq1定义足够大的cache,并且不要定义Maxvalue或者Minvalue。数据库会试图将nextval('sequence_name')的调用下推到Data Node,以提高性能。 目前GTM对并发的连接请求是有限制的,当Data Node很多时,将产生大量并发连接, 这时一定要控制bulkload的并发数目,避免耗尽GTM的连接资源。如果目标表为复制表(DISTRIBUTE BY REPLICATION)时下推将不能进行。当数据量较大时,这对数据库将是个灾难。除了性能问题之外,空间也可能会剧烈膨胀,在导入结束后,需要用vacuum full来恢复。最好的方式还是如上建议的,不要在bulkload的场景中产生默认序列值。 另外,序列创建后,在每个节点上都维护了一张单行表,存储序列的定义及当前值,但此当前值并非GTM上的当前值,只是保存本节点与GTM交互后的状态。如果其他节点也向GTM申请了新值,或者调用了Setval修改了序列的状态,不会刷新本节点的单行表,但因每次申请序列值是向GTM申请,所以对序列正确性没有影响。
  • 查看视图 查看MyView视图,查询结果为当前实时数据。 1 SELECT * FROM myview; 查看当前用户下的视图。 1 SELECT * FROM user_views; 查看所有视图。 1 SELECT * FROM dba_views; 查看某视图的具体信息。 执行如下命令查询dba_users视图的详细信息。 1 2 3 4 5 6 7 8 \d+ dba_users View "PG_CATALOG.DBA_USERS" Column | Type | Modifiers | Storage | Description ----------+-----------------------+-----------+----------+------------- USERNAME | CHARACTER VARYING(64) | | extended | View definition: SELECT PG_AUTHID.ROLNAME::CHARACTER VARYING(64) AS USERNAME FROM PG_AUTHID;
  • 索引类型 btree:B-tree索引使用一种类似于B+树的结构来存储数据的键值,通过这种结构能够快速的查找索引。btree适合支持比较查询以及查询范围。 gin:GIN索引是倒排索引,可以处理包含多个键的值(比如数组)。 gist:Gist索引适用于几何和地理等多维数据类型和集合数据类型。 Psort:Psort索引。针对列存表进行局部排序索引。 行存表支持的索引类型:btree(行存表缺省值)、gin、gist。列存表支持的索引类型:Psort(列存表缺省值)、btree、gin。 对于点查询场景,推荐建立btree索引。
  • 索引的选择原则 索引建立在数据库表中的某些列上。因此,在创建索引时,应该仔细考虑在哪些列上创建索引。 在经常需要搜索查询的列上创建索引,可以加快搜索的速度。 在作为主键的列上创建索引,强制该列的唯一性和组织表中数据的排列结构。 在经常使用连接的列上创建索引,这些列主要是一些外键,可以加快连接的速度。 在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的。 在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间。 在经常使用WHERE子句的列上创建索引,加快条件的判断速度。 为经常出现在关键字ORDER BY、GROUP BY、DISTINCT后面的字段建立索引。 索引创建成功后,系统会自动判断何时引用索引。当系统认为使用索引比顺序扫描更快时,就会使用索引。 索引创建成功后,必须和表保持同步以保证能够准确地找到新数据,这样就增加了数据操作的负荷。因此请定期删除无用的索引。
  • 分割一个分区 范围分区表和列表分区表分割分语法有所区别: 使用ALTER TABLE语句为范围分区表分割一个分区。例如,将表web_returns_p1分区pxxxx以20201231为分割点分割为p2020和p20xx两个分区。 1 ALTER TABLE web_returns_p1 SPLIT PARTITION pxxxx AT(20201231) INTO (PARTITION p2020,PARTITION p20xx); 使用ALTER TABLE语句为列表分区表分割一个分区。例如,将表sales_info分区province2_202201分割为province3_202201和province4_202201两个分区。 1 ALTER TABLE sales_info SPLIT PARTITION province2_202201 VALUES(('202201', 'city5')) INTO (PARTITION province3_202201,PARTITION province4_202201);
  • 查询分区 查询分区p2019。 1 2 SELECT * FROM web_returns_p1 PARTITION (p2019); SELECT * FROM web_returns_p1 PARTITION FOR (20201231); 查看分区表信息,可使用系统表dba_tab_partitions。 1 SELECT * FROM dba_tab_partitions where table_name='web_returns_p1';
  • 对已有的表进行分区 表只能在创建时被分区。 如果用户有一个表想要分区,用户必须创建一个分过区的表,把原始表的数据载入到新表,再删除原始表并且把分过区的表重命名为原始表的名称。 用户还必须重新授权表上的权限。例如: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 CREATE TABLE web_returns_p2 ( 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(20161231) END(20191231) EVERY(10000), PARTITION p0 END(maxvalue) ); 1 2 3 4 5 INSERT INTO web_returns_p2 SELECT * FROM web_returns_p1; DROP TABLE web_returns_p1; ALTER TABLE web_returns_p2 RENAME TO web_returns_p1; GRANT ALL PRIVILEGES ON web_returns_p1 TO dbadmin; GRANT SELECT ON web_returns_p1 TO jack;
  • 创建列表(list)分区表 LIST分区表可以使用任意允许值比较的列作为分区键列。创建LIST分区表时,必须要为每一个分区声明每一个值分区。 示例:创建LIST分区表sales_info。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 CREATE TABLE sales_info ( sale_time timestamptz, period int, city text, price numeric(10,2), remark varchar2(100) ) DISTRIBUTE BY HASH(sale_time) PARTITION BY LIST (period, city) ( PARTITION province1_202201 VALUES (('202201', 'city1'), ('202201', 'city2')), PARTITION province2_202201 VALUES (('202201', 'city3'), ('202201', 'city4'), ('202201', 'city5')), PARTITION rest VALUES (DEFAULT) );
  • 分区策略选择 当表有以下特征时,可以考虑使用表分区策略: 数据具有明显区间性的字段。 分区表需要根据有明显区间性字段进行表分区。比如按照日期、区域、数值等字段进行分区,时间字段是最常见的分区字段。 业务查询有明显的区间范围特征。 查询数据可落到区间范围指定的分区内,这样才能通过分区剪枝,只扫描查询需要的分区,从而提升数据扫描效率,降低数据扫描的IO开销。 表数据量比较大。 小表扫描本身耗时不大,分区表的性能收益不明显,因此只建议对大表采取分区策略。列存储模式下因为每个列是单独的文件存储,且最小的存储单元CU可存储6w行数据,因此对于列存分区表,建议每个分区的数据不小于DN个数*6w。
  • 创建范围(range)分区表 示例:创建一个按wr_returned_date_sk范围分区的表web_returns_p1。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 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 VALUES LESS THAN(20161231), PARTITION p2017 VALUES LESS THAN(20171231), PARTITION p2018 VALUES LESS THAN(20181231), PARTITION p2019 VALUES LESS THAN(20191231), PARTITION pxxxx VALUES LESS THAN(maxvalue) ); 对于分区间隔固定、批量创建分区的场景。可使用如下示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 CREATE TABLE web_returns_p2 ( 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(20161231) END(20191231) EVERY(10000), PARTITION p0 END(maxvalue) ); 示例:创建一个按时间日期作为分区的表web_returns_p2,其中time作为分区键。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 CREATE TABLE web_returns_p2 ( id integer, idle numeric, IO numeric, scope text, IP text, time timestamp ) WITH (TTL='7 days',PERIOD='1 day') PARTITION BY RANGE(time) ( PARTITION P1 VALUES LESS THAN('2022-01-05 16:32:45'), PARTITION P2 VALUES LESS THAN('2022-01-06 16:56:12') );
  • 使用Schema 在特定Schema下创建对象或者访问特定Schema下的对象,需要使用有Schema修饰的对象名。名称包含Schema名以及对象名,之间用“.”号分开。 在myschema下创建mytable表。以schema_name.table_name格式创建表。 1 CREATE TABLE myschema.mytable(id int, name varchar(20)); 查询myschema下mytable表的所有数据。 1 2 3 4 SELECT * FROM myschema.mytable; id | name ----+------ (0 rows)
  • 系统Schema 每个数据库都包含一个pg_catalog schema,它包含系统表和所有内置数据类型、函数、操作符。pg_catalog是搜索路径中的一部分,始终在临时表所属的模式后面,并在search_path中所有模式的前面,即具有第二搜索优先级。这样确保可以搜索到数据库内置对象。如果用户需要使用和系统内置对象重名的自定义对象时,可以在操作自定义对象时带上自己的模式。 information_schema由一个包含数据库中对象信息的视图集合组成。 这些视图以一种标准化的方式从系统目录表中得到系统信息。
  • 查看Schema 使用current_schema()函数查看当前Schema: 1 2 3 4 5 SELECT current_schema(); current_schema ---------------- myschema (1 row) 要查看Schema所有者,请对系统表PG_NAMESPACE和PG_USER执行如下关联查询。语句中的schema_name请替换为实际要查找的Schema名称。 1 SELECT s.nspname,u.usename AS nspowner FROM PG_NAMESPACE s, PG_USER u WHERE nspname='schema_name' AND s.nspowner = u.usesysid; 要查看所有Schema的列表,请查询PG_NAMESPACE系统表。 1 SELECT * FROM PG_NAMESPACE; 使用PGXC_TOTAL_SCHEMA_INFO视图查询整个集群的Schema空间使用情况。 1 SELECT * FROM PGXC_TOTAL_SCHEMA_INFO; 要查看属于某Schema下表的列表,请查询系统视图PG_TABLES。例如,以下查询会返回Schema PG_CATALOG中的表列表。 1 SELECT distinct(tablename),schemaname FROM PG_TABLES where schemaname = 'pg_catalog';
  • Schema的权限控制 默认情况下,用户只能访问属于自己的Schema中的数据库对象。如需要访问其他Schema的对象,则需赋予对应Schema的usage权限。 通过将模式的CREATE权限授予某用户,被授权用户就可以在此模式中创建对象。 将myschema的usage权限赋给用户jack。 1 GRANT USAGE ON schema myschema TO jack; 将用户jack对于myschema的usage权限收回。 1 REVOKE USAGE ON schema myschema FROM jack;
  • 设置Schema搜索路径 GUC参数search_path设置Schema的搜索顺序,参数取值形式为采用逗号分隔的Schema名称列表。如果创建对象时未指定目标Schema,则该对象会被添加到搜索路径中列出的第一个Schema中。当不同Schema中存在同名的对象时,查询对象未指定Schema的情况下,将从搜索路径中包含该对象的第一个Schema中返回对象。 使用SHOW命令查看当前搜索路径。 1 2 3 4 5 SHOW SEARCH_PATH; search_path ---------------- "$user",public (1 row) search_path参数的默认值为:"$user",public。$user表示与当前会话用户名同名的Schema名,如果这样的模式不存在,$user将被忽略。所以默认情况下,用户连接数据库后,如果数据库下存在同名Schema,则对象会添加到同名Schema下,否则对象被添加到Public Schema下。 使用SET命令修改当前会话的默认Schema。例如,将搜索路径设置为myschema、public,首先搜索myschema。 1 SET SEARCH_PATH TO myschema, public; 也可以使用ALTER ROLE命令为特定的角色(用户)设置search_path。例如: 1 ALTER ROLE jack SET search_path TO myschema, public;
  • 创建Schema 使用CREATE SCHEMA命令来创建一个新的Schema。 1 CREATE SCHEMA myschema; 如果需要在模式中创建或者访问对象,其完整的对象名称由模式名称和具体的对象名称组成。中间由符号“.”隔开。例如:myschema.table。 用户可以创建一个由他人拥有的schema。例如,创建名为myschema的Schema,并指定Schema的所有者为用户jack。 1 CREATE SCHEMA myschema AUTHORIZATION jack; 若不指定authorization username,则其所有者为执行该命令的用户。
  • 查看和停止正在运行的查询语句 通过视图PG_STAT_ACTIVITY可以查看正在运行的查询语句。方法如下: 设置参数track_activities为on。 1 SET track_activities = on; 当此参数为on时,数据库系统才会收集当前活动查询的运行信息。 查看正在运行的查询语句。以查看正在运行的查询语句所连接的数据库名、执行查询的用户、查询状态及查询对应的PID为例: 1 SELECT datname, usename, state,pid FROM pg_stat_activity; 如果state字段显示为idle,则表明此连接处于空闲,等待用户输入命令。 如果仅需要查看非空闲的查询语句,则使用如下命令查看: 1 SELECT datname, usename, state FROM pg_stat_activity WHERE state != 'idle'; 若需要取消运行时间过长的查询,通过PG_TERMINATE_BACKEND函数,根据线程ID结束会话。 1 SELECT PG_TERMINATE_BACKEND(139834759993104); 显示类似如下信息,表示结束会话成功。 1 2 3 4 PG_TERMINATE_BACKEND ---------------------- t (1 row) 显示类似如下信息,表示用户执行了结束当前会话的操作。 1 2 FATAL: terminating connection due to administrator command FATAL: terminating connection due to administrator command gsql客户端使用PG_TERMINATE_BACKEND函数结束当前会话后台线程时,客户端不会退出而是自动重连。即还会返回“The connection to the server was lost. Attempting reset: Succeeded.” 1 2 3 FATAL: terminating connection due to administrator command FATAL: terminating connection due to administrator command The connection to the server was lost. Attempting reset: Succeeded.
  • 查看数据库中包含的表 例如,在PG_TABLES系统表中查看public schema中包含的所有表。 1 SELECT distinct(tablename) FROM pg_tables WHERE SCHEMANAME = 'public'; 结果类似如下这样: 1 2 3 4 5 6 7 8 9 tablename ------------------- err_hr_staffs test err_hr_staffs_ft3 web_returns_p1 mig_seq_table films4 (6 rows)
  • 删除表数据 请谨慎执行DROP TABLE和TRUNCATE TABLE命令,删除表后,数据将无法恢复。 从数据库中删除表customer_t1。 1 DROP TABLE customer_t1; 清空一个表的行但不移除该表的定义,可使用DELETE或者TRUNCATE。 删除表customer_t1中所有的行。 1 TRUNCATE TABLE customer_t1; 删除表customer_t1中所有的行。 1 DELETE FROM customer_t1; 删除表customer_t1中所有c_customer_sk为3869的记录: 1 DELETE FROM customer_t1 WHERE c_customer_sk = 3869;
  • 表分布的定义 GaussDB(DWS)支持的分布方式:复制表(Replication)、哈希表(Hash)和轮询表(Roundrobin)。 轮询表(Roundrobin)分布方式仅8.1.2及以上集群版支持。 策略 描述 适用场景 优势与劣势 复制表(Replication) 集群中每一个DN实例上都有一份全量表数据。 小表、维度表。 Replication优点是每个DN上都有此表的全量数据,在join操作中可以避免数据重分布操作,从而减小网络开销,同时减少了plan segment(每个plan segment都会起对应的线程) Replication缺点是每个DN都保留了表的完整数据,造成数据的冗余。一般情况下只有较小的维度表才会定义为Replication表。 哈希表(Hash) 表数据通过hash方式散列到集群中的所有DN实例上。 数据量较大的事实表。 在读/写数据时可以利用各个节点的IO资源,大幅度提升表的读/写速度。 一般情况下大表(1000000条记录以上)定义为Hash表。 轮询表(Roundrobin) 表的每一行被轮番地发送给各个DN,数据会被均匀地分布在各个DN中。 数据量较大的事实表,且使用Hash分布时找不到合适的分布列。 Roundrobin优点是保证了数据不会发生倾斜,从而提高了集群的空间利用率。 Roundrobin缺点是无法像Hash表一样进行DN本地化优化,查询性能通常不如Hash表。 一般在大表无法找到合适的分布列时,定义为Roundrobin表,若大表能够找到合适的分布列,优先选择性能更好的Hash分布。
  • 创建表 CREATE TABLE命令创建一个表,创建表时可以定义以下内容: 表的列及数据类型。 表约束的定义,即任何用于限制列或者表中数据的表约束或者列约束。参见表约束的定义。 表分布的定义,即表的分布策略,它决定GaussDB(DWS)数据库如何在片(Segment)之间划分数据。 参见表分布的定义。 表存储格式。参见选择GaussDB(DWS)表存储模型。 分区表定义。参见创建和管理GaussDB(DWS)分区表。
  • 查看表数据 使用系统表pg_tables查询数据库所有表的信息。 1 SELECT * FROM pg_tables; 使用gsql的\d+命令查询表的属性。 1 \d+ customer_t1; 执行如下命令查询表customer_t1的数据量。 1 SELECT count(*) FROM customer_t1; 执行如下命令查询表customer_t1的所有数据。 1 SELECT * FROM customer_t1; 执行如下命令只查询字段c_customer_sk的数据。 1 SELECT c_customer_sk FROM customer_t1; 执行如下命令过滤字段c_customer_sk的重复数据。 1 SELECT DISTINCT( c_customer_sk ) FROM customer_t1; 执行如下命令查询字段c_customer_sk为3869的所有数据。 1 SELECT * FROM customer_t1 WHERE c_customer_sk = 3869; 执行如下命令按照字段c_customer_sk进行排序。 1 SELECT * FROM customer_t1 ORDER BY c_customer_sk;
  • 使用压缩 表压缩可以在创建表时开启,压缩表能够使表中的数据以压缩格式存储,意味着占用相对少的内存。 对于I/O读写量大,CPU富足(计算相对小)的场景,选择高压缩比;反之选择低压缩比。建议依据此原则进行不同压缩下的测试和对比,以选择符合自身业务情况的最优压缩比。压缩比通过COMPRESSION参数指定,其支持的取值如下: 列存表为:YES/NO/LOW/MIDDLE/HIGH,默认值为LOW。 行存表为:YES/NO,默认值为NO。(行存表压缩功能暂未商用,如需使用请联系技术支持工程师) 各压缩级别所适用的业务场景说明如下: 压缩级别 所适用的业务场景 低级别压缩 系统CPU使用率高,存储磁盘空间充足。 中度压缩 系统CPU使用率适中,但存储磁盘空间不是特别充足。 高级别压缩 系统CPU使用率低,磁盘空间不充裕。 例如,创建一个名为customer_t3的列存压缩表: 1 2 3 4 5 6 7 CREATE TABLE customer_t3 ( state_ID CHAR(2), state_NAME VARCHAR2(40), area_ID NUMBER ) WITH (ORIENTATION = COLUMN,COMPRESSION=middle);
  • 创建数据库 使用CREATE DATABASE语句创建一个新的数据库。 1 CREATE DATABASE mydatabase; 创建数据库时,若数据库名称长度超过63字节,server端会对数据库名称进行截断,保留前63个字节,因此建议数据库名称长度不要超过63个字节,不要使用多字节字符作为对象名。(如果出现因为误操作导致在多字节字符的中间截断进而无法删除数据库对象的现象,请使用截断前的数据库对象名进行删除操作,或将该对象从各个数据库节点的相应系统表中依次删掉。) 数据库名称遵循SQL标识符的一般规则。当前用户自动成为此新数据库的所有者。 如果一个数据库系统用于承载相互独立的用户和项目,建议把它们放在不同的数据库里。 如果项目或者用户是相互关联的,并且可以相互使用对方的资源,则应该把它们放在同一个数据库里,但可以规划在不同的Schema中。 GaussDB(DWS)允许创建的数据库总数目上限为128个。 用户必须拥有数据库创建的权限或者是数据库的系统管理员权限才能创建数据库。
共100000条