目录
一、表空间
二、数据库
三、模式:Schema
四、database schema table之间的关系
五、表
六、分区表
七、索引
八、视图
九、序列
十、同义词
十一、约束
一、表空间
自带了两个表空间:pg_default和pg_global。查看命令:\db
-
默认表空间pg_default:用来存储非共享系统表、用户表、用户表index、临时表、临时表index、内部临时表的默认表空间。对应存储目录为实例数据目录下的base目录。
-
共享表空间pg_global:用来存放共享系统表的表空间。对应存储目录为实例数据目录下的global目录。
创建表空间
CREATE TABLESPACE tp_joe RELATIVE LOCATION 'tablespace/tp_joe';
创建后位置:/vastbase/a-Oracle/data/pg_location/tablespace/tp_joe
数据库系统管理员执行如下命令将“tp_joe”表空间的访问权限赋予数据用户joe
GRANT all PRIVILEGES ON TABLESPACE tp_joe TO joe;
先使用set default_tablespace
设置默认表空间,再创建表
SET default_tablespace = 'tp_joe';
CREATE TABLE foo(i int);
查询表空间利用率,单位为字节
SELECT PG_TABLESPACE_SIZE('tp_joe');
表空间使用率=PG_TABLESPACE_SIZE/表空间所在目录的磁盘大小。
创建单用户指定该表空间设置最低保留值小于等于表空间最大配额
表空间最低配额由参数user_reserve_space来控制,该参数用于控制是否开启单用户表空间最低配额,默认值off(关闭)。
user_reserve_space
设置为on后,表示启用单用户表空间最低配额。该参数重新读取配置文件生效(可通过vb_ctl reload
或者在vsql中执行select pg_reload_conf()
来重新读取配置文件),不需要重启数据库实例。开启参数使用
alter system set user_reserve_space = on;
命令。enable_perm_space用于对持久化磁盘空间的统计和检查功能相关参数,例如单用户表空间最低配额限制、单条sql使用空间限制
on表示开启,off表示关闭。
开启参数使用
alter system set enable_perm_space = on;
命令。
管理员通过表空间可以设置表空间配额。但使用表空间配额管理会使性能有30%左右的影响,MAXSIZE指定每个数据库节点的配额大小,误差范围在500MB以内。
表空间可以控制数据库数据占用的磁盘空间,当表空间所在磁盘的使用率达到90%时,数据库将被设置为只读模式,当磁盘使用率降到90%以下时,数据库将恢复到读写模式。
二、数据库
-
初始时,Vastbase包含两个模板数据库template0、template1,以及一个默认的用户数据库postgres。postgres默认的兼容数据库类型为O(即DBCOMPATIBILITY = 'A' ),该兼容类型下将空字符串作为NULL处理。
-
CREATE DATABASE
实际上通过拷贝模板数据库来创建新数据库。默认情况下,拷贝template0。请避免使用客户端或其他手段连接及操作两个模板数据库。
数据库系统中会有多个数据库,但是客户端程序一次只能连接一个数据库。也不能在不同的数据库之间相互查询。一个Vastbase中存在多个数据库时,需要通过-d
参数指定相应的数据库进行连接。
创建数据库
CREATE DATABASE db_joe WITH TABLESPACE = tp_joe;
三、模式:Schema
引入schema的原因
允许多个用户使用一个数据库并且不会互相干扰。
将数据库对象组织成逻辑组以便更容易管理。
第三方应用的对象可以放在独立的模式中,这样它们就不会与其他对象的名称发生冲突。
创建Schema
# 切换到db3数据库
postgres=# \c db3
You are now connected to database "db3" as user "postgres".
db3=#
# 创建schema
db3=# create SCHEMA myschema;
CREATE SCHEMA
# 在myschema中创建表cities
CREATE TABLE db3.myschema.cities (
name varchar(80),
location point
);
# 创建一个由其他人所拥有的模式(因为这是将用户动作限制在良定义的名字空间中的方法之一)。其语法是:
db3=# CREATE SCHEMA myschema3 AUTHORIZATION role3;
CREATE SCHEMA
db3=#
db3=#
db3=# \dn
List of schemas
Name | Owner
-----------+----------
myschema | postgres
myschema2 | postgres
myschema3 | role3
public | postgres
(4 rows)
查看Schema
db3=# \dn
List of schemas
Name | Owner
-----------+----------
myschema | postgres
myschema2 | postgres
public | postgres
(3 rows)
删除Schema
# 删除不为空的schema会报错
db3=# drop schema myschema;
ERROR: cannot drop schema myschema because other objects depend on it
DETAIL: table cities depends on schema myschema
HINT: Use DROP ... CASCADE to drop the dependent objects too.
# 要删除一个模式以及其中包含的所有对象,可用
db3=# DROP SCHEMA myschema CASCADE;
NOTICE: drop cascades to table cities
DROP SCHEMA
Public Schema
创建的表如果不指定任何schema名称。默认情况下这些表(以及其他对象)会自动的被放入一个名为“public”的schema中。任何新数据库都包含这样一个模式。因此,下面的命令是等效的:
CREATE TABLE products ( ... );
CREATE TABLE public.products ( ... );
Schema搜索路径
搜索路径中的第一个schema被称为当前schema。除了是第一个被搜索的schema外,如果CREATE TABLE
命令没有指定schema名,它将是新创建表所在的schema。
# 显示当前的搜索路径
db3=# SHOW search_path;
search_path
-----------------
"$user", public
(1 row)
第一个元素说明一个和当前用户同名的schema会被搜索。如果不存在这个schema,该项将被忽略。第二个元素指向我们已经见过的public schema。
修改搜索路径
搜索路径中的第一个模式是创建新对象的默认存储位置。这就是默认情况下对象会被创建在公共模式中的原因。当对象在任何其他没有模式限定的环境中被引用(表修改、数据修改或查询命令)时,搜索路径将被遍历直到一个匹配对象被找到。因此,在默认配置中,任何非限定访问将只能指向公共模式。
但是注意,这种set路径的方式只是会话级别的,重新登陆后设置的内容会消失
四、database schema table之间的关系
1.同一个实例下,不同database是不能相互访问的,即独立的。
2.同一个数据库,不同模式下的表是可以相互访问,即可共享的
3.不同模式下,表名可以是一样。也就是表在模式下是独立。
类比理解:
- postgresql中的database,可以看作mysql的一个实例
- postgresql中的schema,可以看作mysql的database
- postgresql中的table,可以看作mysql的table
database
每个PG服务可以包含多个独立的database
schema
如果把databases比作一个国家,那么schema就是一些独立的省。大多数对象是隶属于某个schema的,然后schema又隶属于某个databases。在创建一个新的database时,PG会自动为其创建一个名为public的schema。如果未设置searc_path变量,那么PG会将你创建的所有对象默认放入public schema中。如果表的数量较少,这是没问题的,但是如果你有几千张表,那么我们还是建议你将他们分门别类放入不同的schema中。
table
任何一个数据库中,表都是最核心的对象类型。在PG中,表首先属于某个schema,而schema有属于某个database,这样就构成一种三级存储结构。PG的表支持两种很强大的功能。第一种是继承,即一张表可以有父表和子表,这种层次化的结构可以极大的简化数据库设计,还可以为你省掉大量的重复查询代码。第二种是创建一张表的同时,系统会自动为此表创建一种对应的自定义数据类型。
五、表
表是建立在数据库中的,在不同的数据库中可以存放相同的表。甚至可以通过使用模式在同一个数据 库中创建相同名称的表
创建表
CREATE TABLE test_pro ( ID INT, name VARCHAR(10), peonum VARCHAR(8));
INSERT INTO test_pro
VALUES
( 1, '王诚', 11111 ),
( 2, '石峰', 22222 ),
( 3, '严军朋', 33333 ),
( 4, '张世龙', 444444 );
复制表结构
create table public.test_pro1(like test_pro including all);
复制表数据
修改表
修改表,包括修改表的定义、重命名表、重命名表中指定的列、重命名表的约束、设置表的所属模式、 添加/更新多个列、打开/关闭行访问控制开关。
增加/删除字段
postgres=# ALTER TABLE contab4 ADD COLUMN col2 VARCHAR(8);
postgres=# ALTER TABLE contab4 DROP COLUMN col2;
修改字段默认值
postgres=# ALTER TABLE contab4 ALTER COLUMN col SET DEFAULT '0' ;
修改字段数据类型,注意数据失真
postgres=# ALTER TABLE contab4 ALTER COLUMN col TYPE varchar(9);
修改表名
postgres=# ALTER TABLE contab4 RENAME TO contab5 ;
修改字段名
postgres=# ALTER TABLE contab5 RENAME COLUMN col TO col1 ;
修改表的模式(schema)
postgres=# ALTER TABLE public.testtab1 SET SCHEMA atlas;
六、分区表
分区应用场景
- 范围分区(Range partitioning):
应用场景:适用于数据具有连续范围特性的情况,例如时间序列数据。可以按照时间范围(如年、月、日)来分区。
例子:一个包含多年销售数据的表,可以按年进行分区,每个分区包含特定年份的所有数据。
- 列表分区(List partitioning):
应用场景:适用于数据可以明确分类的情况,每个分区包含特定的值列表。这通常用于分类数据,如地区、部门或状态。
例子:一个包含不同地区用户信息的表,可以按国家或地区进行分区,每个分区包含特定国家或地区内的用户数据。
- 哈希分区(Hash partitioning):
应用场景:适用于需要均匀分布数据以提高并发访问性能的情况。哈希分区可以将数据均匀地分布到多个分区中,每个分区包含数据的一个子集。
例子:一个大型用户表,可以按照用户ID的哈希值进行分区,以确保数据在多个服务器或存储设备上均匀分布,从而提高查询和更新操作的并发性。
分区执行过程
1.查询规划:
PostgreSQL 的查询规划器会接收 SQL 查询并尝试找出最有效的执行计划。
当查询涉及到分区表时,规划器会考虑哪些分区可能包含查询所需的数据,并尝试仅扫描那些必要的分区。
2.分区剪枝:
查询规划器会执行一个称为“分区剪枝”的过程,以确定哪些分区与查询条件匹配。
如果查询条件中包含了分区键(在这个例子中是 add_time),那么规划器就可以确定哪些分区包含可能满足条件的数据。
只有那些与查询条件匹配的分区才会被扫描,这可以显著提高查询性能。
3.并行查询:
如果查询被确定为可以并行执行(这取决于多个因素,如查询的复杂性、系统的配置以及是否启用了并行查询),PostgreSQL 可以并行扫描多个分区。
这意味着多个工作进程可以同时处理不同的分区,从而进一步加速查询的执行。
4.数据读取:
一旦确定了要扫描的分区,PostgreSQL 就会从这些分区中读取数据。
读取操作会遵循表定义的存储参数和索引(如果有的话),以尽可能高效地获取数据。
5.结果合并:
从各个分区读取的数据会在 PostgreSQL 中进行合并,以产生最终的查询结果。
如果查询涉及多个分区,并且这些分区的数据需要按照某种顺序进行排序或组合,那么合并操作可能会更加复杂。
6.返回结果:
一旦合并了所有必要的数据并生成了最终结果,PostgreSQL 就会将结果返回给客户端。
分区表创建
CREATE TABLE customer_address
(
ca_address_sk integer NOT NULL ,
ca_address_id character(16) NOT NULL ,
ca_street_number character(10) ,
ca_street_name character varying(60) ,
ca_street_type character(15) ,
ca_suite_number character(10) ,
ca_city character varying(60) ,
ca_county character varying(30) ,
ca_state character(2) ,
ca_zip character(10) ,
ca_country character varying(20) ,
ca_gmt_offset numeric(5,2) ,
ca_location_type character(20)
)
PARTITION BY RANGE (ca_address_sk)
(
PARTITION P1 VALUES LESS THAN(5000),
PARTITION P2 VALUES LESS THAN(10000),
PARTITION P3 VALUES LESS THAN(15000),
PARTITION P4 VALUES LESS THAN(20000),
PARTITION P5 VALUES LESS THAN(25000),
PARTITION P6 VALUES LESS THAN(30000),
PARTITION P7 VALUES LESS THAN(40000),
PARTITION P8 VALUES LESS THAN(MAXVALUE)
)
ENABLE ROW MOVEMENT;
分区表管理
增加分区
alter table sales add partition p3 values less than (95);
alter table sales add partition p4 values less than (MAXVALUE);
删除分区P3
alter table pt1 drop partition for(90);
或
alter table pt1 drop partition p3;
修改分区
alter table pt1 rename partition p4 to pmax; -- 重命名分区
alter table pt1 move partition pmax tablespace tbs1; -- 移动分区表空间
alter table pt1 split partition p3 at (90) into (partition p4,partition p5); -- 分离分区
alter table pt1 merge partitions p4,p5 into partition p3; -- 合并分区
alter table pt1 exchange partition (p3) with table t1; -- 分区表数据交换
VastBase数据库分区表注意事项
https://docs.vastdata.com.cn/zh_CN/VastbaseG100/V2.2.15/1/5950072cd2f845368966395edfbb00d5
七、索引
应该考虑在哪些列上创建索引?
- 经常执行查询的字段;
- 在连接条件上创建索引,对于存在多字段连接的查询,建议在这些字段上建立组合索引;
- where子句的过滤条件字段上(尤其是范围条件);
- 为经常出现在关键字ORDER BY、GROUP BY、DISTINCT后面的字段建立索引。
分区表索引分为LOCAL索引与GLOBAL索引,一个LOCAL索引对应一个具体分区,而GLOBAL索引则对应整个分区表。
B-Tree索引
创建索引
CREATE INDEX testtab1_id_idx1 ON testtab1(id) TABLESPACE tbs_index1;
联机创建索引
CREATE INDEX CONCURRENTLY testtab1_id_idx1 ON testtab1(id);
索引的排序顺序,缺省是升序
CREATE INDEX CONCURRENTLY testtab1_id_idx1 ON testtab1(id) DESC;
删除索引
DROP INDEX testtab1_id_idx1;
唯一索引
插入数据时需要检查唯一性
相对非唯一索引查询时更快,但插入数据稍慢
创建索引
CREATE UNIQUE INDEX testtab1_id_idx1 ON testtab1(id) TABLESPACE tbs_index1;
多字段索引
复合索引
CREATE UNIQUE INDEX testtab1_id_idx1 ON testtab1(id,name);
附加字段索引
CREATE UNIQUE INDEX testtab1_id_idx1 ON testtab1(id) INCLUDE (name,acc_balance);
局部索引
可以使用查询的检索条件创建索引,满足查询条件的行才会放入索引节点
Concurrently :不堵塞dml操作
CREATE INDEX CONCURRENTLY testtab1_id_idx1 ON testtab1(status) WHERE status<>'Finished';
表达式索引
可以基于字段的表达式或者使用函数创建索引
CREATE INDEX CONCURRENTLY testtab1_id_idx1 ON testtab1( substr(id,7,8));
八、视图
视图与基本表不同,是一个虚拟的表。数据库中仅存放视图的定义,而不存放视图对应的数据,这些数据仍存放在原来的基本表中。若基本表中的数据发生变化,从视图中查询出的数据也随之改变。从这个意义上讲,视图就像一个窗口,透过它可以看到数据库中用户感兴趣的数据及变化。
-
被授予CREATE ANY TABLE权限的用户,可以在public模式和用户模式下创建视图。
-
不可与同一模式下已存在的synonym产生命名冲突。
创建视图
create view v1 as select * from test_pro where id<4;
查看视图定义
select pg_get_viewdef('v1');
管理物化视图
alter view v1 rename to v2; -- 重命名视图
alter view v2 owner to jack; -- 修改视图属主
alter view v2 set schema jack; -- 修改视图schema
删除视图
drop view jack.v2; -- 删除视图
drop materialized view mv1; -- 删除物化视图
九、序列
序列Sequence是用来产生唯一整数的数据库对象。序列的值是按照一定规则自增的整数。因为自增所以不重复,因此说Sequence具有唯一标识性。这也是Sequence常被用作主键的原因。
通过序列使某字段成为唯一标识符的方法有两种:
-
一种是声明字段的类型为序列整型,由数据库在后台自动创建一个对应的Sequence。
-
另一种是使用CREATE SEQUENCE自定义一个新的Sequence,然后将nextval('sequence_name')函数读取的序列值,指定为某一字段的默认值,这样该字段就可以作为唯一标识符。
创建序列
方法一: 声明字段类型为序列整型来定义标识符字段
方法二: 创建序列,并通过nextval('sequence_name')函数指定为某一字段的默认值
1、 创建序列
2、 指定为某一字段的默认值,使该字段具有唯一标识属性。
CREATE TABLE T2
(
id int not null default nextval('seq1'),
name text
);
3、 指定序列与列的归属关系
将序列和一个表的指定字段进行关联。这样,在删除此指定字段或序列所在表的时候会自动删除已关联的序列。
除了为序列指定了cache,方法二所实现的功能基本与方法一类似。但是一旦定义cache,序列将会产生空洞(序列值为不连贯的数值,如:1.4.5),并且不能保序。另外为某序列指定从属列后,若该列删除,对应的sequence也会被删除。虽然数据库并不限制序列只能为一列产生默认值,但最好不要多列共用同一个序列。
vastbase当前版本仅支持在PostgreSQL兼容模式下对已存在的表进行修改,为表增加自增列,可参考表增加自增列。其余兼容模式下只支持在定义表的时候指定自增列,或者指定某列的默认值为nextval('seqname'),不支持在已有表中增加自增列或者增加默认值为nextval('seqname')的列。
十、同义词
GaussDB数据库中的同义词SYNONYM_gauss200数据库同义词synonm-CSDN博客
十一、约束
以下是在 PostgreSQL 中常用的约束。
-
NOT NULL:指示某列不能存储 NULL 值。
-
UNIQUE:确保某列的值都是唯一的。
-
PRIMARY Key:NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。。
-
FOREIGN Key: 保证一个表中的数据匹配另一个表中的值的参照完整性。
-
CHECK: 保证列中的值符合指定的条件。
-
EXCLUSION :排他约束,保证如果将任何两行的指定列或表达式使用指定操作符进行比较,至少其中一个操作符比较将会返回 false 或空值。
PostgreSQL 建表约束规则_pgsql 建表字段約束-CSDN博客