PostgreSQL15学习笔记

1. CMD命令

1.1 数据库启动与停止

(1) 启动数据库:net start postgresql 

(2) 停止数据库:net stop postgresql 

1.2 数据库连接与退出

(1) 连接数据库 : psql [-hlocalhost -p5432] -Upostgres [-d 数据库名]  //本地可省略-h-p

注释:用户名postgres(超级管理员),pgAdmin > tools > query tools(可执行sql)

(2) 退出数据库:exit | quit | \q

1.3 数据库备份与还原

(1) 全部数据库备份:pg_dumpall -U 用户名 -f 文件.sql  // 有几个库就需要输入几次密码

(2) 单数据库全表备份:pg_dump -U用户名 -f 文件.sql [-d] 数据库名 // -d可有可无

(3) 多表备份:pg_dump -U 用户名 -t 表名1 -t 表名2 -f 文件.sql 数据库名

(4) 还原:psql -U 用户名 -f 文件.sql  [[-d] 数据库名]// 单数据库还原默认postgres数据库

注释:数据库启动(热备份-逻辑备份),数据库停止(冷备份-物理备份)

-a 只存数据,-s 只存格式,pg_dump --help查看指令

PostgreSQL15学习笔记_第1张图片

2. SQL语言

2.1 DCL-用户权限

数据库库权限:superuser(全部权限), login(登录), createdb(建库权限), createrole(建组权限), 

表权限:all, select, insert, update, delete, truncate, references, trigger 

创建组或用户:create role|user 组名|用户名 [password '密码' ] 库权限 [库权限...]

注释:创建组的最后可加 noinherit 或 inherit ,noinherit代表用户登录会话没有库权限,用set role 组名可变成组角色,创建的表归组所有,set role none;或 reset role;恢复权限。

查询组或用户:select from pg_roles|pg_user; // \du

改组名或用户名:alter role|user 组名|用户名 rename to 新名;

删除组或用户:drop role|user 组名|用户名 [名...];

改密码:alter role|user 组名|用户名 password '密码'

追加单个表权限:grant 表权限 on [table] 表名 to 组名|用户名;

追加所有表权限:grant 表权限 on all tables in schema 模式名 to 组名|用户名;

注释:【to 角色名】 后追加 【with grant option】使目标可以授权给其他角色

撤销单个表权限:revoke 表权限 on [table] 表名 from 组名|用户名;

撤销所有表权限:revoke 表权限 on all tables in schema 模式名 from 组名|用户名;

加库权限:alter role|user 组名|用户名 login createdb createrole;

删库权限:alter role|user 组名|用户名 nologin nocreatedb nocreaterole;

注释:角色表pg_roles包含用户表pg_user的信息,创建的角色有登录login权限则创建的是用户。

授予组权限给角色:grant 组名 to 用户1, 用户2...;

撤销角色的组权限:revoke 组名 from 用户1, 用户2...;

2.2. DDL-数据库与表

2.2.1 数据库操作

显示数据库:\l

当前数据库:\c

切换数据库:\c 数据库名

创建数据库:create database 数据库名;

删除数据库:drop database 数据库名;

改数据库名:alter database 数据库名 rename to 新数据库名;

2.2.2 表操作

显示所有表:\dt

查看表结构:\d 表名

创建表:create table 表名(字段名 类型 [约束], ...)

快速创建:create table 表名 as select * from 表; // 结构数据一致

快速创建:create table 表名 as select * from 表 where 1=2; // 结构一致,无数据

快速创建:create table 表名 (like 表2); // 赋值表结构,无数据

重建表:truncate table 表名; 

删除表:drop table [if exists] 表名;

修改表名:alter table 表名 rename to 新表名;

添加字段:alter table 表名 add [column] 字段名 类型 约束;

删除字段:alter table 表名 drop [column] 字段名;

变更字段名:alter table 表名 rename [column] 字段名 to 新字段名;

修改字段属性alter table 表名 alter [column] 字段名 type 类型;

修改字段约束:alter table 表名 alter [column] 字段名 set 约束; // not null, defalut '1'...

添加删除表注释:comment on table 表名 is '注释' | '';

添加删除列注释:comment on column 表名.列名 is '注释' | '';

注释:只有表的所有者才能改表结构

2.2.3 模式操作

显示模式:select * from pg_namspace; // \dn

创建模式:create schema 模式名 [authorization 拥有者];

删除模式:drop schema 模式名; // drop schema 模式名 cascade // 删除模式及对象

改模式名:alter schema 模式名 rename to 新模式名;

改拥有者:alter schema 模式名 owner to 新拥有者;

2.3. DML-数据增删改

插入数据:insert into 表名 [(字段1, 字段2, ...)] values (值1, 值2, ...) [,(值1, 值2...)];

修改数据:update 表名 set 字段1=值1 [, 字段2=值2, ...]  [where 条件];

删除数据:delete from 表名 [where 条件];

注释:insert into 表 (字段..) select 字段 ... from 表2; // 将表2查出数据复制到表1

插入项目可填写null或default

插入数据返回结果:insert intovalues(x, x...) returning 字段, 字段...;  // 可返回*

更新数据返回结果:update set 字段=值 where 条件 returning 字段, 字段...; // 可返回*

删除数据返回结果:delete fromwhere 条件 returning 字段, 字段...; // 可返回*

2.4. DQL-数据查询

2.4.1 查询(select)

全部查询:select * from 表名 [where 条件]; // table 表名;全表查询

字段查询:select 字段1 [, 字段2...] from 表名 [where 条件];

去重查询:select distinct 字段1 [, 字段2...] from 表名 [where 条件];

注释:查询项目可做 + - * / % 运算,select num+1,表名 [AS] 表别名, 列名 [AS] 列别名

2.4.2 查询条件(where)

逻辑运算符:not > and > or

>, >=, <, <=, =, !=, <>, between and, in, not in, like, not like,exists, not exists

注释:不等取值取不到null值

2.4.3 分组(group by)

分组查询:select 字段... from 表 where 条件 group by 分组字段 having 分组后条件;

根据查询分组:select 字段1, 字段2 from 表 group by 1,2;// 根据查询的第一第二个字段分组 

2.4.4 排序(order by)

select * from 表名 where 条件 order by 排序字段 [asc]; // 升序

select * from 表名 where 条件 order by 排序字段 desc; // 降序

select * from 表名 where 条件 order by 字段1 desc, 字段2 asc;

根据查询字段排序:select 字段1, 字段2 from 表 order by 1,2;// 根据查询的第一第二个字段排序

2.4.5 分页(limit)

select * from 表名 where 条件 limit 查询记录数; 

select * from 表名 where 条件 limit 查询件数 offset 开始位置; // 开始位置默认0

注释: 不支持 【limit n, m】。【limit 1 offset 2】; //去掉前2个记录,显示1条记录

2.4.6 表关联(join)

隐式内联:select * from 表1, 表2 where 条件; // 内连接

显示内联on:select * from 表1 [inner] join 表2 on 关联条件 where 条件

显示内联using:select * from 表1 [inner|full] join 表2 using(同名字段) where 条件;

显示内联natural:select * from 表1 natural join 表2; //不可写on条件

交叉连接:select * from 表1 cross join 表2; // 笛卡尔积,不可写on或using链接条件可用where

左外联结:select * from 表1 left [outer] join 表2 on 关联条件 where 条件;

右外联结:select * from 表1 right [outer] join 表2 on 关联条件 where 条件;

全外联结:select * from 表1 full [outer] join 表2 on 关联条件 where 条件;

注释:join的内联,左联,右联,外联,必须指定on条件

2.4.7 联合查询(合并查询)

(1) 并集

select * from 表1  union select * from 表2; // 合并后去重排序

select * from 表1  union all select * from 表2;

(2) 交集(优先级最高)

select * from 表1 intersect select * from 表2; // 表1 a,a,b, 表2 a,a,c 得到相同a,a去重得到a

select * from 表1 intersect all select * from 表2; // 表1 a,a,b, 表2 a,a,c 得到相同a,a

注释:a,a,b和a,c intersect all只得到1个a

(3) 差集

select * from 表1 except [distinct] select * from 表2; // 得到表2中没有的表1数据,去重

select * from 表1 except all select * from 表2; // 不去重

2.4.8 嵌套子查询

标量子查询:select * from 表1 where 字段 = (select 字段 from 表2); 

行子查询:select * from 表1 where (字段, 字段) = (select 字段, 字段 from 表2);

列子查询:select * from 表1 where 字段 [in|any|all] (select 字段 from 表2);

表子查询:select * from 表1 where (字段, 字段) [in|any]  (select 字段, 字段 from 表2); 

2.4.9 临时表(WITH)

with 临时表1(字段别名,...) as ( select * from 表 where 条件), 临时表名2 as (...from 表|临时表);

插入更新删除:with 临时表名 as ( insert|update|delete ... returning * ) // 返回插入更新删除结果

3. 约束(参照mysql)

3.1 主键约束(primary key)

列约束:字段 类型 PRIMARY KEY; // 字段无引号

表约束:[constraint] [约束名] primary key(字段 [, 字段...])); //约束名指定也是空值

追加约束:alter table 表名 add primary key(字段 [, 字段...]); // 只能没有主键时追加

删除约束:alter table 表名 drop primary key; // 只能全部主键删除

3.2 外键约束(foreign key)

列约束:

表约束:[constraint] [约束名] foreign key(字段) references 主表(主字段)

追加约束:alter table 表名 add [constraint] [约束名] foreign key(字段) references 主表(主字段)

删除约束:alter table 表名 drop foreign key 约束名; // 约束名无引号

更新删除行为:

no action 不可删除更新, 

restrict     不可删除更新(更新删除,默认)

cascade   同时删除更新子表, 

set null    子表更新成null

建表或追加约束语句后追加 on update cascade on delete set null; // 更新主表,同时更新子表。删除主表,子表设置为null

注释:主表字段必须是主键或索引项目,外键约束名不可重复。

3.3 唯一约束(unique)

列约束:字段 类型 UNIQUE,

表约束:[constraint] [约束名] unique(字段 [, 字段...])

追加约束:alter table 表名 add [constraint] [约束名] unique(字段 [, 字段...])

删除约束:alter table 表名 drop index 约束名; // 约束名(也是索引名)

注释:默认约束名是字段名,多列唯一默认名是第一个字段名。多个单列唯一每一列单独验证是否唯一。一个多列唯一,值合并做唯一验证(允许某一列重复)。

3.4 检查约束(check)

列约束:字段 类型 check(age >0 && age <20), // 或者 (age =18 or age=20)

表约束:[constraint] [约束名] CHECK (字段1 >= 字段2)); // 默认名 表_chk_连番

添加约束:alter table 表名 add [constraint] [约束名] check( 数值字段 > 值 | 字段 );

删除约束:alter table 表名 drop check 约束名; 

注释:只能用于数值,日期类型

3.5 非空约束(not null)

列约束:字段 类型 NOT NULL,

表约束:无

修改表字段追加约束:alter table 表名 alter [column] 字段名 set not null;

修改表字段删除约束:alter table 表名 alter [column] 字段名 drop not null;

3.6 默认值(default)

列约束:字段 类型 DEFAULT 值,

表约束:无

修改默认值:alter table 表名 alter [column] 字段名 set defalut 

删除默认值:alter table 表名 alter [column] 字段名 drop default;

3.7 自增

3.7.1 标识列 identity

列自增:字段 数值类型 generated always as identity 约束 // 底层是序列

注释:插入 insert into 表名 values (default, ...),  或者不指定列名

3.7.2 序列 sequence

创建序列:create sequence 模式.序列名 increment by 步长值 minvalue 最小值 maxvalue 最大值 start 开始值 cache 缓存数量 no cycle;  // no cycle不循环生成

列自增:字段 数值类型 default nextval('序列名')

3.7.3 serial类型

列自增:字段 serial 

4. 事务与锁

4.1 事务

4.1.1 四大特性

原子性:事务更新删除,全变更或全不变更

一致性:事务结束,与数据保持一致

隔离性:事务处理在另一个事务之前或之后

持久性:事务完成,永久改变

4.1.2 开启事务

开启事务1:start transaction;

开启事务2:begin;

4.1.3 结束事务

提交:commit;

回滚:rollback;

4.1.4 事务隔离级别

(1) 读未提交, read uncommitted

(2) 读已提交,read committed

(3) 可重复读,repeatable read

(4) 串行化,serializable

查看隔离级别:show transaction_isolation;

设置隔离级别:start transaction isolation level 隔离级别;

并发问题:(1)脏读, (2)不可重复读, (3)幻读

注释:postgreSQL实际只实现两种隔离级别(读已提交,串行化),

设置 (读未提交,读已提交)=读已提交。设置(可重复读,串行化)=串行化。

4.2. 锁

1 ACCESS SHARE(访问共享)// 查询语句自动加锁

2 ROW SHARE(行共享)

3 ROW EXCLUSIVE(行排他)

4 SHARE UPDATE EXCLUSIVE(更新排他)

5 SHARE(共享锁)

6 SHARE ROW EXCLUSIVE(共享行排他)

7 EXCLUSIVE(排他)

8 ACCESS EXCLUSIVE(访问排他)默认

锁表:begin; lock table 表名 in 锁 mode; sql crud... commit;

5. 索引

显示索引:\di

创建索引:create [ unique | fulltext ] index 索引名 on 表名(字段1 [, 字段2, ...]) [using btree(默认) | hash | gist | gin | brin] [字段 asc | desc [nulls first | last] ] ; // 只有btree支持唯一索引,除了hash都支持联合索引

删除索引:drop index 索引名;

注释:pg索引与mysql索引不一样,pg没有聚集索引,都是二级索引

创建聚集索引:create index 索引名 on 表名 using btree(字段1,字段2) include (字段3); // 根据字段1和字段2创建联合索引,不用回表查出就能检索字段3

6. SQL优化

6.1 SQL性能分析

explain [analyze] select * from ...;

6.2 SQL性能优化

6.2.1 插入优化

方式1:insert into values (...),(...) 多条一起插入比一条一条插入效率高

方式2:先删除索引,插入后再建立索引

方式3:批量插入,按主键顺序插入,手动提交事务,可以提高插入效率

6.2.8 查询优化

用 join 代替子查询(子查询会建立临时表)

7. 视图

显示视图:\dv

7.1. 视图作用

(1). 简化业务,将多个复杂条件改为视图。避免基本表变更,影响业务。

(2). mysql对用户授权,只能控制表权限,通过视图可以控制用户字段权限。

7.2 视图命令

(1). 创建视图:create [or replace] view 视图名 as select * from 表; 

(3). 删除视图:drop view 视图名 [cascade | restrict(默认)]; // cascade同时删除依赖视图的对象

(5). 查询视图数据:select * from 视图名; 

7.3 视图(插入,更新,删除数据)

视图中的行数据,必须与基本表的行一一对应。不能用group, with ,union ,limit ,distinct,聚合函数

7.4 视图检测选项

(1). create view 视图名 as select * from 表 where 条件 with [cascaded] check option;

(2). create view 视图名 as select * from 表 where 条件 with local check option;

(3). create view 视图名 as select * from 视图 where 条件 with [cascaded] check option;

(4). create view 视图名 as select * from 视图 where 条件 with local check option;

8. PL/pgSQL

8.1 变量

declare写在begin之前

定义:declare 变量名 类型 [not null] [default | := | = ]// id integer; name varchar;

基于表的数据行定义:变量名 表名%ROWTYPE; //表的一行数据的类型

基于表的数据列定义:变量名 表名.字段%TYPE; //表的一个字段的类型

基于已定义变量类型:变量名 已定义变量%TYPE; //使用定义过的类型

常量定义:declare 常量名 constant 类型 := ; // 必须初始化,不能更改值

变量设值:变量名 := 值;

8.2 分歧条件

分歧写在begin end之间

(1) if 条件 then ...; [elseif 条件 then ...] else ...; end if;

(2) case 字段 when [,值] then ... [when 值 then ...] else ... end case;

8.3 循环

循环写在begin end之间

8.3.1 loop

loop
    exit when 退出条件;
    处理...
    continue when 跳过条件;
end loop;

PostgreSQL15学习笔记_第2张图片

8.3.2 while

while 执行条件 loop 
  处理...
end loop;

PostgreSQL15学习笔记_第3张图片

8.3.3 for

for 下标i in 起始值(小).. 终止值(大) [by 步长值] loop  
// 降序[ reverse 起始值(大).. 终止值(小) ]
    处理...
end loop;

PostgreSQL15学习笔记_第4张图片

8.3.4 foreach

for 变量 in 查询sql loop
  处理...
end loop;

PostgreSQL15学习笔记_第5张图片

8.4 游标

do $$
declare
  变量名 类型; // record 一行记录类型
  游标名 cursor for select ...;
  // 游标名 cursor(参数 类型) for select ...;
begin
  open 游标名;
  // open 游标名(参数);
  loop
    fetch 游标名 into 变量名;
    exit when not found;
  end loop;
  close 游标名;

// 异常处理
exception
  when 条件 then ...;

end $$; 

PostgreSQL15学习笔记_第6张图片

8.5 过程化SQL

Do $$
declare 变量名 类型; // 没有变量可省略
begin 
  处理...;
end;
$$;

PostgreSQL15学习笔记_第7张图片

过程嵌套

Do $$
declare 变量名 类型;
begin
  处理...

  declare 变量名 类型;
  begin
    处理...
  end;

  处理...
end;
$$;

PostgreSQL15学习笔记_第8张图片

8.6 存储过程(postgresql11开始支持)

8.6.1 创建存储过程

create [or replace] procedure 过程名( [in|out|inout] 参数名 类型 [default|= 值])
AS $$
declare 变量名 类型;
begin
  处理...
end $$
language plpgsql;

PostgreSQL15学习笔记_第9张图片

8.6.1 调用存储过程

call 过程名(参数...);

8.7 存储函数

(1) 创建存储函数

create [or replace] function 函数名( 
  [in默认|out|inout] [参数名 类型 [default|= 值] ] )
returns 类型
// as 'select $1 + $2 ;'  // $1代表参数,动态SQL
AS $$
declare 变量名 类型;
begin
  select xx into 变量 from ...;
  return 变量;
end $$
language plpgsql;

PostgreSQL15学习笔记_第10张图片

(2) 调用存储函数:select 函数名();

8.8 触发器

8.8.1 触发器函数

create [or replace] function 触发器函数名()  //不能传参
returns trigger
as $$  // $函数名
declare 变量名 类型;
begin
  // insert(new), update(old, new), delete(old)
  // 属性
  // TG_NAME  触发器名
  // TG_WHEN  'before', 'after', 'instend of'
  // TG_LEVEL 'ROW', 'STATEMENT'
  // TG_OP    'insert', 'update', 'delete'
  // TG_TABLE_NAME  表名
  // TG_TABLE_SCHEMA  模式名
  if tg_op = 'insert' then 
    ...
  end if;
  return ...;
end $$  // $函数名
language plpgsql;

PostgreSQL15学习笔记_第11张图片

注释:return null使原插入处理失效,返回 new 原处理正常执行,可以before改new的值变更处理 

8.8.2 触发器

(1) 创建触发器

create trigger 触发器名
before | after | instead of(只能视图)
insert | update | delete  // 可用or连接指定多个
on 表名 
for each [row | statement]  // row行级,statement语句级
[when 条件] // 满足条件触发
execute function 触发器函数名(); // execute procedure 过程名();

(2) 改触发器名:alter trigger 触发器名 on 表名 rename to 新触发器名;

(3) 删除触发器:drop trigger 触发器 on 表名 [restrict(默认)|cascade]; // cascade删依赖

(4) 启动停止触发器:alter table 表名 [enable(启)|disable(停)] trigger [触发器名|all];

9. 数据类型与函数

9.1 数据类型

9.1.1 数值型

整数:smallint (2字节 -32768~32767), int (integer 4字节 -21亿~21亿), bigint (8字节)

浮点:real (4字节) , double precision (8字节)

精度numeric (m, n) , decimal(m, n)  // m总位数,n小数位数

9.1.2 字符型

定长字符串:char(n) / character(n)  // 不足补空白

变长字符串:varchar(n) /character varying(n)

二进制:bytea (4字节)

文本:text

9.1.3 日期型

日期:date

时间:time

日期时间:timestamp

9.1.4 其它类型

布尔:boolean ( true/yes/t/y/1,  false/no/f/n/0 )

自增:smallserial(2字节),serial(4字节),bigserial(8字节)

9.2 函数

9.2.1 聚合函数

count, max , min ,sum

9.2.2 流程函数

case when 表达式 then 字段值 [...] else 字段值 end [as 别名]; // 表达式成立则字段1否则字段2 

case 字段 when 值 then 字段值 [...] else 字段值 end [as 别名]; // 如果是值1则字段1...否则字段2

coalesce(数据, 数据...) // 返回第一个不为null的值

注释:nullif(值, 字段) 两个值相等,返回null, 不相等返回第一个值。只能得到值1或null两种结果

9.2.3 类型转换函数

数字转字符:to_char(数值, '99999') // 不足前补空格

字符转数字:to_number('字符', '99999') // cast('字符' as integer)  // '字符'::integer

日期转字符:to_char(日期, 'YYYY-MM-DD') // to_char(日期时间, 'YYYY-MM-DD hh24:MI:SS')

字符转日期:to_timestamp(字符串, 'YYYYMMDD hh24MISS') // to_date(字符串, 'yyyymmdd')

注释:隐式类型转换, 1+'2'=3, 1+'x'不可执行, 'a'||1='a1'

9.2.4 数值函数

向上取整:ceil(值)  // ceiling(数值)  小数有值进1

向下取整:floor(值) // 小数舍弃

向0取值:trunc(值)  // 正数有小数舍弃,负数有小数进1

四舍五入:round(x, y) // round(x)

9.2.5 字符函数

拼接:concat(s1,s2) // 忽略null,双竖线拼接有null返回nullconcat_ws(s, s1...)s分割

补齐:lpad(s1,len,s2), rpad(s1,len,s2) // 将s1用s2补齐到len位长度

去空:trim(s) // 去两侧空值 // 

截取:substring(s1 from 开始位置 [for 长度])  // substr(s, 开始下标 [, 长度])

截掉:left(s,n), right(s, n) // 截取字符,

取长:length(s) // char_length(s) character(s) 取字符长度, 1个汉字返回1。octet(字符)中文返回2

9.2.6 日期函数

系统日期:current_date

系统时间:current_time

系统日期时间:current_timestamp | now() 

获取年:extract(year from date|timestamp) // date_part('year', date|timestamp)

获取月:extract(month from date|timestamp) // date_part('month', date|timestamp)

获取日:extract(day from date|timestamp) // date_part('day', date|timestamp)

日期计算:日期+值(默认加的是日)+ interval '1 hour', '23 hours' , '1 month'

日期+时间=日时,日期-日期=天数

你可能感兴趣的:(postgresql,数据库)