标签:random 工作 选择性 3.5 access 存储 数据管理 having 标准
《PostgreSQL 教程》:https://www.yiibai.com/postgresql
psql -d test -h 127.0.0.1 -p 5432 -U gpadmin
注意:默认登陆的表名为 gpadmin
create database test; # 需要登陆 psql
createdb test; # 命令行模式
访问模式的对象:schema.table,缺省 Public 模式
1. 创建和删除模式
create schema sc01; # 创建 schema
create schema sc02 authorization dylan; # 将 schema 权限赋予用户 dylan
drop schema sc01; # 删除 schema(空模式)
drop schema sc01 cascade; # 删除模式及相关的所有对象
2. 查看模式
查看所有的模式为 \dn
List of schemas
Name | Owner
--------------------+---------
gp_toolkit | gpadmin
information_schema | gpadmin
pg_aoseg | gpadmin
pg_bitmapindex | gpadmin
pg_catalog | gpadmin
pg_toast | gpadmin
public | gpadmin
3. 设置模式搜索路径
若不想通过指定模式名称的方式来搜索需要的对象,可以通过设置 search_path 的方式来实现,第一个模式为缺省。
# 查看当前的搜索路径
select current_schema();
show search_path;
# 设置搜索路径
# 通过ALTER DATABASE修改DB的模式搜索路径
alter database test set search_path to sc01,public,pg_catalog;
# 通过 alter role 修改 ROLE(User) 的模式搜索路径
alter role dylan set search_path to sc01,public,pg_catalog;
注意: 修改表的搜索路径后需要重新登陆才会生效,即不会在当前会话生效。
4. 系统模式
通过 CREATE TABLE 命令实现,在创建表时,通过需要定义以下几点:
create table tb_products(
-- 1. 主键约束,唯一约束和非空约束的综合体。默认成为 DK(Distributed Key)
id integer integer PRIMARY KEY,
-- 2. 唯一约束,确保字段的数据在表中唯一
product_no integer UNIQUE,
-- 3. 非空约束,不可以存在空值
name text NOT NULL,
-- 4. 检查约束,过制定数据必须满足一个布尔表达式来约束
price numeric CHECK(price>0)
-- 5. 外键约束,GPDB 目前不支持。
);
注意: 主键约束与唯一约束只有出现一个。
在 create table 和 alter table 的时候使用 DISTRIBUTED BY(HASH 分布)或 DISTRIBUTED RANDOMLY(随机分布)来决定数据如何分布。考虑要点:
声明分布键:
create table tb_dk_01(a int, b int) distributed by(b);
create table tb_dk_02(a int, b int);
create table tb_dk_03(a int primary key, b int);
create table tb_dk_04(a int, b int) distributed randomly;
# 查看表分布键
\d tb_dk_01
选择堆存储(Heap)或只追加(Append-Only)存储
# 创建堆表,缺省的存储模式
CREATE TABLE tb_heap_01(id int) DISTRIBUTED BY (id)
# 创建只追加表
CREATE TABLE tb_ao_01(id int) WITH(appendonly=true)
选择行存储(Row-Orientation)或列存储(Column-Orientation),考虑因素:
查询设计的列数量:
如果在 SELECT 或 WHERE 中涉及表的全部或大部分列时,考虑行存储。列存储适用于在 WHERE 或 HAVING 中队单列作聚合操作:
SELECT SUM(salary)
SELECT AVG(salary)…WHERE salary>10000
或在 WHERE 条件中使用单个列条件且返回少量的行使用压缩存储
SELECT salary, dept…WHERE state=‘CA’
压缩:列存储表具有压缩优势。
-- 创建列存储时,只能为追加(Append-Only)存储
create table tb_col_01(a int, b text) with (appendonly=true, orientation=column) distributed by (a);
两种压缩方式:表级压缩和列级压缩。
(1) 选择压缩方式和级别的考虑因素:
应保证不会显著提高压缩时间和查询效率的前提下最有效的压缩减少数据尺寸。ZLIB 压缩率高于 QUICKLZ,但速度较低。
-- 注意:QUICKLZ 只有一种压缩级别,即没有 compresslevel 参数,而 ZLIB 有 1-9 可选。
create table tb_zlib_01(a int, b text) with (appendonly=true, compresstype=zlib, compresslevel=5);
(2) 检查 AO 表的压缩和分布情况:
# 查看表的分布情况,只能用于Append-Only表
select get_ao_distribution(‘表名‘);
# 查看表的压缩率,只能用于Append-Only表
select get_ao_compression_ratio(‘表名‘);
select gp_segment_id, count(1) from 表名 group by 1;
(3) 参数
(4) 压缩设置的优先级
在越低级别的设置具有越高的优先级:
注意: 存储设置不可以被继承
create table tb_t3 (
c1 int encoding(compresstype=zlib),
c2 text,
c3 text encoding(compresstype=rle_type),
c4 smallint encoding(compresstype=none),
defalut column encoding(compresstype=quicklz, blocksize=65536)
)
with(appendonly=true, orientation=column)
partition by range(c3)
(
start(‘2010-01-01‘::date) end(‘2010-12-31‘::date),
column c3 encoding(compresstype=zlib)
);
alter table 命令用于改变现有表的定义。例如:
alter table tb_01 alter column a set not null;
(1) 修改分布策略
-- 数据会重分布,并递归地应用于所有子分区
alter table tb_01 set distributed by(b);
-- 注意:将分布策略改为随机分布时不会重新分布数据
alter table tb_01 set distributed randomly;
(2) 重分布表数据
# 随机分布策略或者不改变分布策略的表,强行重分布
alter table tb_01 set with(reorganize=true);
(3) 修改表的存储模式
存储模式只能在CREATE TABLE时被指定。如果要修改,必须使用正确的存储选项重建该表。
CREATE TABLE tb_zlib_02 (like tb_zlip_01) WITH (appendonly=true, compresstype=quicklz, compresslevel=1, orientation=column);
INSERT INTO tb_zlib_02 SELECT * FROM tb_zlip_01;
DROP TABLE tb_zlip_01;
ALTER TABLE tb_zlib_02 RENAME TO tb_zlib_01;
GRANT ALL PRIVILEGES ON tb_zlib_01 TO admin;
GRANT SELECT ON tb_zlib_01 TO dylan;
(4) 添加压缩列
ALTER TABLE tb_zlib_01 ADD COLUMN c int DEFAULT 0 ENCODING (COMPRESSTYPE=zlib);
(5) 删除表
-- 删除与表相关的视图,必须使用CASCADE
DROP TABLE tb01;
DROP TABLE tb03 CASCADE;
-- 使用 DELETE 或 TRUNCATE 清空表记录
DELETE FROM tb02;
TRUNCATE tb02;
一张大表逻辑性地分成多个部分,如按照分区条件进行查询,将减少数据的扫描范围,提高系统性能。提高对于特定类型数据的查询速度和性能,更方便数据库的维护和更新。
决定表的分区策略:
TABLE 只能在 CREATE TABLE 时被分区。第一步要选择分区类型(范围分区、列表分区)和分区字段
(1) 定义日期范围分区表(range分区)
使用单个 date 或者 timestamp 字段作为分区键。如果需要,还可以使用同样的字段做子分区。通过使用 START、END 和 EVERY 子句定义分区增量让 GP 自动产生分区。
CREATE TABLE tb_cp_01 (id int, date date, amt decimal(10, 2))
DISTRIBUTED BY (id)
PARTITION BY RANGE (date)
(
-- (默认行为)INCLUSIVE:包含 2013-01-01;EXCLUSIVE:不包含 2014-01-01
START (date ‘2013-01-01‘) INCLUSIVE
END (date ‘2014-01-01‘) EXCLUSIVE
EVERY (INTERVAL ‘1 month‘)
);
也可以为每个分区单独制定名称
CREATE TABLE tb_cp_02 (id int, date date, amt decimal(10, 2))
DISTRIBUTED BY (id)
PARTITION BY RANGE (date)
(
PARTITION Jan13 START (date ‘2013-01-01‘) INCLUSIVE,
PARTITION Feb13 START (date ‘2013-02-01‘) INCLUSIVE,
PARTITION Mar13 START (date ‘2013-03-01‘) INCLUSIVE,
PARTITION Apr13 START (date ‘2013-04-01‘) INCLUSIVE,
PARTITION May13 START (date ‘2013-05-01‘) INCLUSIVE,
PARTITION Jun13 START (date ‘2013-06-01‘) INCLUSIVE,
PARTITION Jul13 START (date ‘2013-07-01‘) INCLUSIVE,
PARTITION Aug13 START (date ‘2013-08-01‘) INCLUSIVE,
PARTITION Sep13 START (date ‘2013-09-01‘) INCLUSIVE,
PARTITION Oct13 START (date ‘2013-10-01‘) INCLUSIVE,
PARTITION Nov13 START (date ‘2013-11-01‘) INCLUSIVE,
PARTITION Dec13 START (date ‘2013-12-01‘) INCLUSIVE
END (date ‘2014-01-01‘) EXCLUSIVE
);
(2) 定义数字范围分区表
CREATE TABLE tb_cp_03 (id int, rank int, year int, gender char(1), count int)
DISTRIBUTED BY (id)
PARTITION BY RANGE (year)
(
START (2010) END (2014) EVERY (1),
DEFAULT PARTITION extra
);
(3) 创建列表分区表(list分区)
可以使用任何数据类型的列作为分区键;可以使用多个列组合作为分区键。
CREATE TABLE tb_cp_04 (id int, rank int, year int, gender char(1), count int )
DISTRIBUTED BY (id)
PARTITION BY LIST (gender)
(
PARTITION girls VALUES (‘F‘),
PARTITION boys VALUES (‘M‘),
DEFAULT PARTITION other
);
(4) 定义多级分区表
当需要子分区时,可以使用多级分区的设计。
CREATE TABLE tb_cp_05 (trans_id int, date date, amount decimal(9, 2), region text)
DISTRIBUTED BY (trans_id)
PARTITION BY RANGE (date)
SUBPARTITION BY LIST (region)
SUBPARTITION TEMPLATE
(
-- 子分区
SUBPARTITION usa VALUES (‘usa‘),
SUBPARTITION europe VALUES (‘europe‘),
DEFAULT SUBPARTITION other_regions
)
(
-- 主分区
START (date ‘2013-09-01‘) INCLUSIVE
END (date ‘2014-01-01‘) EXCLUSIVE
EVERY (INTERVAL ‘1 month‘),
DEFAULT PARTITION outlying_dates
);
创建3级子分区表,被分区为年、月、区域三层。
CREATE TABLE tb_cp_06 (id int, year int, month int, day int, region text)
DISTRIBUTED BY (id)
PARTITION BY RANGE (year)
SUBPARTITION BY RANGE (month)
SUBPARTITION TEMPLATE (
-- 定义二级分区(2个 + default)
START (1) END (3) EVERY (1),
DEFAULT SUBPARTITION other_months)
SUBPARTITION BY LIST (region)
SUBPARTITION TEMPLATE (
-- 定义三级分区(2个 + default)
SUBPARTITION usa VALUES (‘usa‘),
SUBPARTITION europe VALUES (‘europe‘),
DEFAULT SUBPARTITION other_regions)
(
-- 定义一级分区(2个 + default)
START (2012) END (2014) EVERY (1),
DEFAULT PARTITION outlying_years
);
通过 pg_partitions 视图查看分区表设计情况。
SELECT partitionboundary, partitiontablename, partitionname, partitionlevel, partitionrank
FROM pg_partitions WHERE tablename=‘tb_cp_05‘;
如下视图也可以查看分区表的信息:
必须使用 ALTER TABLE 命令从顶级表来维护分区。
(1) 添加新分区
原分区表包含 subpartition template 设计:
ALTER TABLE tb_cp_05 DROP DEFAULT PARTITION;
ALTER TABLE tb_cp_05 ADD PARTITION START (date ‘2014-01-01‘) INCLUSIVE END (date ‘2014-02-01‘) EXCLUSIVE;
原分区不包含 subpartition template 设计:
ALTER TABLE tb_cp_05 ADD PARTITION START (date ‘2014-02-01‘) INCLUSIVE END (date ‘2014-03-01‘) EXCLUSIVE
(
SUBPARTITION usa VALUES (‘usa‘),
SUBPARTITION asia VALUES (‘asia‘),
SUBPARTITION europe VALUES (‘europe‘)
);
注意:如果存在默认分区,只能从默认分区中拆分新的分区
(2) 重命名分区
GP 中的对象长度限制为 63 个字符,并且受唯一性约束。子表的名称格式:
<父表名称>_<分区层级>_prt_<分区名称>
修改父表名称,将会影响所有分区表
# 对应分区表将会改为:tbcp05_1_prt_5
ALTER TABLE tb_cp_05 rename to tbcp05;
只修改分区名称:
# 对应分区表将会改为:tbcp05_1_prt_jun13
ALTER TABLE tbcp05 RENAME PARTITION FOR(‘2013-06-01‘) TO Jun13;
(3) 删除分区
# 删除指定的分区
ALTER TABLE tb_cp_04 DROP PARTITION other;
# 删除默认分区:
ALTER TABLE tb_cp_04 DROP DEFAULT PARTITION;
# 对于多级分区表,为同一层每一个分区删除默认分区:
ALTER TABLE tb_cp_06 ALTER PARTITION FOR (RANK(1)) DROP DEFAULT PARTITION;
ALTER TABLE tb_cp_06 ALTER PARTITION FOR (RANK(2)) DROP DEFAULT PARTITION;
(4) 添加默认分区
# 使用ALTER TABLE命令添加默认分区:
ALTER TABLE tbcp05 ADD DEFAULT PARTITION other;
# 如果是多级分区表,同一层每个分区都需要默认分区:
ALTER TABLE tb_cp_06 ALTER PARTITION FOR (RANK(1)) ADD DEFAULT PARTITION other;
ALTER TABLE tb_cp_06 ALTER PARTITION FOR (RANK(2)) ADD DEFAULT PARTITION other;
(5) 清空分区数据
# 使用ALTER TABLE命令来清空分区。
ALTER TABLE tbcp05 TRUNCATE PARTITION FOR (RANK(1));
(6) 交换分区
交换分区是用一个普通的 TABLE 与现有的分区交换身份。使用 ALTER TABLE 命令来交换分区。只能交换最低层次的分区表。
CREATE TABLE jan13(LIKE tb_cp_02) WITH(appendonly=true);
INSERT INTO jan13 VALUES(1,‘2013-01-15‘,123.45);
ALTER TABLE tb_cp_02 EXCHANGE PARTITION for(date ‘2013-01-01‘) WITH TABLE jan13;
(7) 拆分分区
使用 ALTER TABLE 命令将现有的一个分区拆分成两个。例如:将一个月分区数据拆分到一个1-15日的分区和另一个16-31日的分区
ALTER TABLE tb_cp_02 SPLIT PARTITION FOR(‘2013-01-01‘) AT (‘2013-01-16‘)
INTO (PARTITION jan131to15, PARTITION jan0816to31);
如果分区表有默认分区,要添加新分区只能从默认分区拆分:
ALTER TABLE tb_cp_03 SPLIT DEFAULT PARTITION
START (2014) INCLUSIVE END (2015) EXCLUSIVE
INTO (PARTITION y2014, DEFAULT PARTITION);
(8) 修改子分区模板
使用 ALTER TABLE SET SUBPARTITION TEMPLATE 命令来修改现在分区表的子分区模板。例如:
ALTER TABLE tb_cp_05 SET SUBPARTITION TEMPLATE
(
SUBPARTITION usa VALUES(‘usa‘),
SUBPARTITION africa VALUES(‘africa‘),
DEFAULT SUBPARTITION other
);
使用新模板后为表 tb_cp_05 添加一个分区,
ALTER TABLE tb_cp_05 ADD PARTITION Feb14 START (‘2014-02-01‘) INCLUSIVE END(‘2014-03-01‘) EXCLUSIVE;
(1) 装载分区表
(2) 验证分区策略
# EXPLAIN查看查询计划是否扫描了相关分区
EXPLAIN SELECT * FROM tb_cp_05 WHERE date=‘2013-12-01’ AND region=‘usa’;
(3) 分区选择性扫描的限制
如果查询计划显示分区表没有被选择性的扫描,可能和以下的限制有关:
=, <, <=, >, >=, <>
CREATE SEQUENCE myserial START 101; -- 创建索引
SELECT * FROM myserial; -- 查询索引
SELECT setval(‘myserial’,201); -- 设置索引
INSERT INTO tb02 VALUES(nextval(‘myserial’), ‘abc’); -- 使用索引
ALTER SEQUENCE myserial RESTART WITH 105; -- 修改索引
DROP SEQUENCE myserial; -- 删除索引
注意:如果启用了镜像功能,nextval 不允许在 UPDATE 和 DELETE 语句中被使用
在分布式数据库如 GP 中,应保守使用索引。GP会自动为主键建立主键索引,并确保索引在查询工作负载(如表关联、查询)中真正被使用到。
GP中常用的两种:B-tree 和 Bitmap 索引。
CREATE INDEX idx_01 ON tb_cp_02(id); -- 创建 B-tree 索引
CREATE INDEX bmidx_01 ON tb_cp_02 USING BITMAP(date); -- 创建位图索引
REINDEX TABLE tb_cp_02; -- 重建全部索引
REINDEX INDEX bmidx_01; -- 重建特定索引
DROP INDEX bmidx_01; -- 删除索引,在装载数据时,通常先删除索引,再装载数据
CREATE VIEW vw_01 AS SELECT * FROM tb_cp_03 WHERE gender=‘F’; -- 创建视图
DROP VIEW vw_01; -- 删除视图
(1) 表 1: GP 的并发控制-锁模式
锁模式 | 相关SQL命令 | 冲突的锁 |
---|---|---|
ACCESS SHARE | SELECT | ACCESS EXCLUSIVE |
ROW SHARE | SELECT FOR UPDATE, SELECT FOR SHARE | EXCLUSIVE, ACCESS EXCLUSIVE |
ROW EXCLUSIVE | INSERT, COPY | SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, ACCESS EXCLUSIVE |
SHARE UPDATE EXCLUSIVE | VACUUM (without FULL), ANALYZE | SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, ACCESS EXCLUSIVE |
SHARE | CREATE INDEX | ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE ROW EXCLUSIVE, EXCLUSIVE, ACCESS EXCLUSIVE |
SHARE ROW EXCLUSIVE | ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, ACCESS EXCLUSIVE | |
EXCLUSIVE | DELETE, UPDATE | ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, ACCESS EXCLUSIVE |
(2) 事务使用
事务允许将多个 SQL 语句放在一起作为一个整体操作,所有 SQL 一起成功或失败
在 GP 中执行事务的 SQL 命令:
begin
insert into tb_cp_01 values();
savepoint p1;
insert into tb_cp_01 values();
roleback to p1;
end
(3) 事务隔离级别
SQL 标准定义了 4 个事务隔离级别:
事务 ID 管理,在每个数据库每 2 百万个事务的时候,对每张表执行 VACUUM 是很有必要的。
VACUUM tb_cp_02; -- 回收空间
ANALYZE tb_cp_02; -- 收集查询优化器需要的统计信息
服务器日志文件存放在每个实例数据目录的 pg_log 目录下,格式:gpdb-YYYY-MM-DD_TIME.csv
每天用心记录一点点。内容也许不重要,但习惯很重要!
标签:random 工作 选择性 3.5 access 存储 数据管理 having 标准
原文地址:https://www.cnblogs.com/binarylei/p/9062415.html