[草稿]pg入门篇

[TOC]

安装与卸载

  • 快速安装 PostgreSQL 10.12
#.开始安装
cd /opt/
wget -c http://iso.sqlfans.cn/postgresql/postgresql-10.12-1-linux-x64-binaries.tar.gz
wget -c http://iso.sqlfans.cn/postgresql/install_pgsql_1012.sh
wget -c http://iso.sqlfans.cn/postgresql/my_pgsql.conf
bash install_pgsql_1012.sh /opt /data 1921

#.登陆测试
/opt/pgsql/bin/psql -h 127.0.0.1 -p 1921 -U postgres -d postgres -c "SELECT * FROM pg_shadow;"
  • 快速卸载
ps aux | fgrep 'postgres' | fgrep "bin" | awk '{print $2}' | xargs kill -9
rm -rf /data/pgsql*
rm -rf /opt/pgsql
userdel -r postgres

基本操作

登入与登出

#.登陆测试
/opt/pgsql/bin/psql -h 127.0.0.1 -p 1921 -U postgres -d postgres -c "SELECT * FROM pg_shadow;"

#.登录数据库
/opt/pgsql/bin/psql -h 127.0.0.1 -p 1921 -U postgres -d postgres

--.使用 user02 登录 testdb 数据库
\c testdb user02

--.退出交互式界面
\quit
\q

数据库的管理

  • 与 MySQL 不同,PostgreSQL 不支持 create if not exists 语法
--.建议先创建账号,再创建数据库
CREATE USER user_test WITH PASSWORD 'Aa_123456';
CREATE DATABASE db1 WITH OWNER=user_test ENCODING='UTF-8';

--.创建数据库,分配owner为postgres
CREATE DATABASE db2 WITH OWNER=postgres ENCODING='UTF-8';

--.查看数据库清单
SELECT * from pg_database;
\list
\l

--.切换上下文数据库
\connect db1
\c db1

--.查看所有数据库的大小
select datname, pg_database_size(datname) AS size_byte, pg_size_pretty(pg_database_size(datname)) as size_kb from pg_database order by size_byte desc;

--.查看指定数据库的大小
select pg_size_pretty(pg_database_size('db1'));

--.删除数据库
DROP DATABASE db2;

数据表的管理

--.切换上下文数据库
\c db1

--.创建数据表
CREATE TABLE aaa (id int NOT NULL, name character(32), number char(5), CONSTRAINT aaa_pk PRIMARY KEY (id)) with(fillfactor=85);
INSERT INTO aaa (id, name, number) VALUES (1, '张三', '1023');
SELECT * FROM aaa;

--.查看当前数据库下所有的表名
SELECT * FROM pg_tables where schemaname = 'public';
\d

--.查看特定表的所有字段情况
\d aaa;

--.查看当前数据库下所有表的大小
select relname, pg_total_relation_size(relid) as size_byte, pg_size_pretty(pg_total_relation_size(relid)) as size_kb 
from pg_stat_user_tables where schemaname='public' 
order by pg_relation_size (relid) desc;

--.通过系统数据字典查询表结构
select col.table_schema,col.table_name,col.ordinal_position,col.column_name,col.data_type,col.character_maximum_length
  ,col.numeric_precision,col.numeric_scale,col.is_nullable,col.column_default,des.description
from information_schema.columns col 
left join pg_description des on col.table_name::regclass = des.objoid and col.ordinal_position = des.objsubid
where table_schema = 'public' and table_name = 'aaa'
order by ordinal_position;

--.通过系统数据字典查询表结构
select table_catalog,table_schema,table_name,column_name,ordinal_position,data_type,character_maximum_length,is_nullable 
from information_schema.columns where table_schema='public';

--.通过系统数据字典查询索引信息
select A.SCHEMANAME,A.TABLENAME,A.INDEXNAME,A.TABLESPACE,A.INDEXDEF,B.AMNAME,C.INDEXRELID
  ,C.INDNATTS,C.INDISUNIQUE,C.INDISPRIMARY,C.INDISCLUSTERED,D.DESCRIPTION
from PG_AM B 
left join PG_CLASS F on B.OID = F.RELAM 
left join PG_STAT_ALL_INDEXES E on F.OID = E.INDEXRELID 
left join PG_INDEX C on E.INDEXRELID = C.INDEXRELID 
left outer join PG_DESCRIPTION D on C.INDEXRELID = D.OBJOID,PG_INDEXES A
where A.SCHEMANAME = E.SCHEMANAME and A.TABLENAME = E.RELNAME and A.INDEXNAME = E.INDEXRELNAME 
and E.SCHEMANAME = 'public' and E.RELNAME = 'aaa';

--.删除数据表
drop table if exists aaa;

增删改查

--.创建测试表
\c db1
CREATE TABLE IF NOT EXISTS aaa (id int NOT NULL, name character(32), number char(5), CONSTRAINT aaa_pk PRIMARY KEY (id)) with(fillfactor=85);

#.增删改查
INSERT INTO aaa (id, name, number) VALUES (1, '张三', '1023');
INSERT INTO aaa (id, name, number) VALUES (2, '李四', '1024');
INSERT INTO aaa (id, name, number) VALUES (3, '王五', '1025');
UPDATE aaa SET name='麻子' WHERE id=3;
SELECT * FROM aaa WHERE id>0;

账号的管理

  • 创建超级用户
--.创建超级用户
CREATE ROLE root SUPERUSER PASSWORD 'rIFz_1Se4B7pBK6Z' LOGIN;
CREATE ROLE dba_admin SUPERUSER PASSWORD 'Admin_147' LOGIN;
SELECT * FROM pg_shadow;
  • 创建业务账号
--.创建数据库,与MySQL不同,PostgreSQL不支持create if not exists语法
CREATE DATABASE xxx_pay_gateway WITH OWNER=postgres ENCODING='UTF-8';
\l

--.创建业务账号(先授权数据库,再进入数据库授权表权限)
CREATE USER user_pay_gateway WITH PASSWORD 'Aa_123456';
GRANT ALL PRIVILEGES ON DATABASE xxx_pay_gateway TO user_pay_gateway;
\c xxx_pay_gateway
GRANT ALL PRIVILEGES ON all tables in schema public TO user_pay_gateway;
  • 创建只读账号
--.允许访问特定库的所有表
CREATE USER user_bigdata_readonly WITH PASSWORD 'Aa_123456';
\c xxx_pay_gateway
GRANT SELECT ON all tables in schema public TO user_bigdata_readonly;

--.只允许访问特定库的特定表,比如 aaa
CREATE USER user_bigdata_readonly WITH PASSWORD 'Aa_123456';
\c db1
GRANT SELECT ON TABLE aaa TO user_bigdata_readonly;
  • 查询与修改账号
--.查看账号
SELECT * FROM pg_shadow;
select * from pg_user;
SELECT * FROM pg_roles;

--.查看数据库用户
\du

--.查看当前连接的用户名
select user;

--.设置用户密码过期时间
alter user user_bigdata_readonly valid until '2024-12-31';

--.密码永不过期
alter user user_bigdata_readonly valid until 'infinity';

--.禁用与启用,疑似低版本(比如 pg 10.12)不支持
alter user user_bigdata_readonly lock;
alter user user_bigdata_readonly unlock;

--.限制用户的连接数
ALTER USER user_bigdata_readonly WITH CONNECTION LIMIT 200;

--.修改密码
ALTER USER user_bigdata_readonly WITH PASSWORD 'Q8yWuLJ1q_Sth9fA';
  • 角色和用户的区别:角色默认没有登录权限,而用户有登录权限
--.创建角色
create role role01 with password 'Aa_1234456';

--.创建用户继承角色的权限
create user user01 with password 'Aa_1234456' inherit;

--.创建用户不继承角色的权限
create user user02 with password 'Aa_1234456' noinherit;

--.将角色赋给用户
grant role01 to user01, user02;

--.赋权给角色
--.此时 user01 用该表的查询权限,但 user02 没有 (noinherit)
grant select on table tb01 to role01;

--.使用 user02 登录数据库
\c testdb user02
  • 授权与撤销
--.授权:先授权数据库,再授权表权限(需要管理员进入数据库进行授权)
GRANT ALL PRIVILEGES ON DATABASE xxx_pay_gateway TO user_pay_gateway;
\c xxx_pay_gateway
GRANT ALL PRIVILEGES ON all tables in schema public TO user_pay_gateway;

--.仅赋予读写权限
-- grant select,insert,update,delete ON ALL TABLES IN SCHEMA public to user_pay_gateway;

--.撤销:先撤销数据库权限,再撤销表权限
REVOKE ALL PRIVILEGES ON DATABASE xxx_pay_gateway FROM user_pay_gateway;
REVOKE ALL PRIVILEGES ON all tables in schema public FROM user_pay_gateway;
  • 删除账号,当用户有表和数据库依赖关系时,需要先删除或转移相关的表和数据库
--.删除账号
DROP USER user_pay_gateway;

索引与调优

索引的创建与删除

  • 准备测试数据
--.创建测试表
\c db1
CREATE TABLE IF NOT EXISTS xxx (id int NOT NULL, name character(32), nickname character(32), number char(5));

INSERT INTO xxx (id, name, nickname, number) VALUES (1, '曹操', '孟德', '1023');
INSERT INTO xxx (id, name, nickname, number) VALUES (2, '刘备', '玄德', '1024');
INSERT INTO xxx (id, name, nickname, number) VALUES (3, '孙权', '仲谋', '1025');
  • 索引的创建
--.切换上下文数据库
\c db1

--.创建索引
CREATE INDEX idx_1 ON xxx USING btree(name) WITH (fillfactor='90');

--.创建函数索引
CREATE INDEX idx_2 ON xxx USING btree(upper(nickname) varchar_pattern_ops);

--.创建复合索引
CREATE INDEX idx_3 ON xxx USING btree(id, upper(name) varchar_pattern_ops);
  • 索引的确认与删除
--.切换上下文数据库
\c db1

--.删除索引
DROP INDEX idx_3;

--.查看索引
select * from pg_indexes;
select * from pg_statio_all_indexes;

--.查看索引使用记录
select * from pg_stat_all_indexes;
select * from pg_stat_user_indexes;

--.如果不通过 analyze 来更新统计信息,得到的执行计划是不准确的
analyze xxx;

--.分析执行计划
explain analyze SELECT * FROM xxx WHERE id=2;
explain analyze SELECT name FROM xxx where id>1 ORDER BY 1 LIMIT 8;
  • 索引的高级用法
--.切换上下文数据库
\c db1

--.创建部分索引,对于固定条件的查询(示例 id=1 为固定的条件)使用部分索引可以减少索引的大小,同时提升查询效率
select * from xxx where id=1 and name=?;
create index idx_name_id on xxx(name) where id=1;

--.创建索引时加 CONCURRENTLY 关键字,可以并行创建,且不会堵塞DML操作,否则会堵塞DML操作
create index CONCURRENTLY idx_id on xxx(id);

--.如何加快创建索引的速度,调大maintenance_work_mem,可以提升创建索引的速度,但是需要考虑实际的可用内存
begin;
set local maintenance_work_mem='2GB';
create index idx on xxx(id);
end;
Copyright © www.sqlfans.cn 2024 All Right Reserved更新时间: 2024-10-16 19:07:04

results matching ""

    No results matching ""