(1) 启动数据库:net start postgresql
(2) 停止数据库:net stop postgresql
(1) 连接数据库 : psql [-hlocalhost -p5432] -Upostgres [-d 数据库名] //本地可省略-h-p
注释:用户名postgres(超级管理员),pgAdmin > tools > query tools(可执行sql)
(2) 退出数据库:exit | quit | \q
(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查看指令
数据库库权限: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...;
显示数据库:\l
当前数据库:\c
切换数据库:\c 数据库名
创建数据库:create database 数据库名;
删除数据库:drop database 数据库名;
改数据库名:alter database 数据库名 rename to 新数据库名;
显示所有表:\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 '注释' | '';
注释:只有表的所有者才能改表结构
显示模式:select * from pg_namspace; // \dn
创建模式:create schema 模式名 [authorization 拥有者];
删除模式:drop schema 模式名; // drop schema 模式名 cascade // 删除模式及对象
改模式名:alter schema 模式名 rename to 新模式名;
改拥有者:alter schema 模式名 owner to 新拥有者;
插入数据: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 into 表 values(x, x...) returning 字段, 字段...; // 可返回*
更新数据返回结果:update 表 set 字段=值 where 条件 returning 字段, 字段...; // 可返回*
删除数据返回结果:delete from 表 where 条件 returning 字段, 字段...; // 可返回*
全部查询:select * from 表名 [where 条件]; // table 表名;全表查询
字段查询:select 字段1 [, 字段2...] from 表名 [where 条件];
去重查询:select distinct 字段1 [, 字段2...] from 表名 [where 条件];
注释:查询项目可做 + - * / % 运算,select num+1,表名 [AS] 表别名, 列名 [AS] 列别名
逻辑运算符:not > and > or
>, >=, <, <=, =, !=, <>, between and, in, not in, like, not like,exists, not exists
注释:不等取值取不到null值
分组查询:select 字段... from 表 where 条件 group by 分组字段 having 分组后条件;
根据查询分组:select 字段1, 字段2 from 表 group by 1,2;// 根据查询的第一第二个字段分组
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;// 根据查询的第一第二个字段排序
select * from 表名 where 条件 limit 查询记录数;
select * from 表名 where 条件 limit 查询件数 offset 开始位置; // 开始位置默认0
注释: 不支持 【limit n, m】。【limit 1 offset 2】; //去掉前2个记录,显示1条记录
隐式内联: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条件
(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; // 不去重
标量子查询: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);
with 临时表1(字段别名,...) as ( select * from 表 where 条件), 临时表名2 as (...from 表|临时表);
插入更新删除:with 临时表名 as ( insert|update|delete ... returning * ) // 返回插入更新删除结果
列约束:字段 类型 PRIMARY KEY; // 字段无引号
表约束:[constraint] [约束名] primary key(字段 [, 字段...])); //约束名指定也是空值
追加约束:alter table 表名 add primary key(字段 [, 字段...]); // 只能没有主键时追加
删除约束:alter table 表名 drop primary 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
注释:主表字段必须是主键或索引项目,外键约束名不可重复。
列约束:字段 类型 UNIQUE,
表约束:[constraint] [约束名] unique(字段 [, 字段...])
追加约束:alter table 表名 add [constraint] [约束名] unique(字段 [, 字段...])
删除约束:alter table 表名 drop index 约束名; // 约束名(也是索引名)
注释:默认约束名是字段名,多列唯一默认名是第一个字段名。多个单列唯一每一列单独验证是否唯一。一个多列唯一,值合并做唯一验证(允许某一列重复)。
列约束:字段 类型 check(age >0 && age <20), // 或者 (age =18 or age=20)
表约束:[constraint] [约束名] CHECK (字段1 >= 字段2)); // 默认名 表_chk_连番
添加约束:alter table 表名 add [constraint] [约束名] check( 数值字段 > 值 | 字段 );
删除约束:alter table 表名 drop check 约束名;
注释:只能用于数值,日期类型
列约束:字段 类型 NOT NULL,
表约束:无
修改表字段追加约束:alter table 表名 alter [column] 字段名 set not null;
修改表字段删除约束:alter table 表名 alter [column] 字段名 drop not null;
列约束:字段 类型 DEFAULT 值,
表约束:无
修改默认值:alter table 表名 alter [column] 字段名 set defalut 值;
删除默认值:alter table 表名 alter [column] 字段名 drop default;
列自增:字段 数值类型 generated always as identity 约束 // 底层是序列
注释:插入 insert into 表名 values (default, ...), 或者不指定列名
创建序列:create sequence 模式.序列名 increment by 步长值 minvalue 最小值 maxvalue 最大值 start 开始值 cache 缓存数量 no cycle; // no cycle不循环生成
列自增:字段 数值类型 default nextval('序列名')
列自增:字段 serial
原子性:事务更新删除,全变更或全不变更
一致性:事务结束,与数据保持一致
隔离性:事务处理在另一个事务之前或之后
持久性:事务完成,永久改变
开启事务1:start transaction;
开启事务2:begin;
提交:commit;
回滚:rollback;
(1) 读未提交, read uncommitted
(2) 读已提交,read committed
(3) 可重复读,repeatable read
(4) 串行化,serializable
查看隔离级别:show transaction_isolation;
设置隔离级别:start transaction isolation level 隔离级别;
并发问题:(1)脏读, (2)不可重复读, (3)幻读
注释:postgreSQL实际只实现两种隔离级别(读已提交,串行化),
设置 (读未提交,读已提交)=读已提交。设置(可重复读,串行化)=串行化。
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;
显示索引:\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
explain [analyze] select * from ...;
方式1:insert into values (...),(...) 多条一起插入比一条一条插入效率高
方式2:先删除索引,插入后再建立索引
方式3:批量插入,按主键顺序插入,手动提交事务,可以提高插入效率
用 join 代替子查询(子查询会建立临时表)
显示视图:\dv
(1). 简化业务,将多个复杂条件改为视图。避免基本表变更,影响业务。
(2). mysql对用户授权,只能控制表权限,通过视图可以控制用户字段权限。
(1). 创建视图:create [or replace] view 视图名 as select * from 表;
(3). 删除视图:drop view 视图名 [cascade | restrict(默认)]; // cascade同时删除依赖视图的对象
(5). 查询视图数据:select * from 视图名;
视图中的行数据,必须与基本表的行一一对应。不能用group, with ,union ,limit ,distinct,聚合函数
(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;
declare写在begin之前
定义:declare 变量名 类型 [not null] [default | := | = 值]; // id integer; name varchar;
基于表的数据行定义:变量名 表名%ROWTYPE; //表的一行数据的类型
基于表的数据列定义:变量名 表名.字段%TYPE; //表的一个字段的类型
基于已定义变量类型:变量名 已定义变量%TYPE; //使用定义过的类型
常量定义:declare 常量名 constant 类型 := 值; // 必须初始化,不能更改值
变量设值:变量名 := 值;
分歧写在begin end之间
(1) if 条件 then ...; [elseif 条件 then ...] else ...; end if;
(2) case 字段 when 值 [,值] then ... [when 值 then ...] else ... end case;
循环写在begin end之间
loop
exit when 退出条件;
处理...
continue when 跳过条件;
end loop;
while 执行条件 loop
处理...
end loop;
for 下标i in 起始值(小).. 终止值(大) [by 步长值] loop
// 降序[ reverse 起始值(大).. 终止值(小) ]
处理...
end loop;
for 变量 in 查询sql loop
处理...
end loop;
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 $$;
Do $$
declare 变量名 类型; // 没有变量可省略
begin
处理...;
end;
$$;
过程嵌套
Do $$
declare 变量名 类型;
begin
处理...
declare 变量名 类型;
begin
处理...
end;
处理...
end;
$$;
create [or replace] procedure 过程名( [in|out|inout] 参数名 类型 [default|= 值])
AS $$
declare 变量名 类型;
begin
处理...
end $$
language plpgsql;
call 过程名(参数...);
(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;
(2) 调用存储函数:select 函数名();
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;
注释:return null使原插入处理失效,返回 new 原处理正常执行,可以before改new的值变更处理
(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];
整数:smallint (2字节 -32768~32767), int (integer 4字节 -21亿~21亿), bigint (8字节)
浮点:real (4字节) , double precision (8字节)
精度:numeric (m, n) , decimal(m, n) // m总位数,n小数位数
定长字符串:char(n) / character(n) // 不足补空白
变长字符串:varchar(n) /character varying(n)
二进制:bytea (4字节)
文本:text
日期:date,
时间:time ,
日期时间:timestamp
布尔:boolean ( true/yes/t/y/1, false/no/f/n/0 )
自增:smallserial(2字节),serial(4字节),bigserial(8字节)
count, max , min ,sum
case when 表达式 then 字段值 [...] else 字段值 end [as 别名]; // 表达式成立则字段1否则字段2
case 字段 when 值 then 字段值 [...] else 字段值 end [as 别名]; // 如果是值1则字段1...否则字段2
coalesce(数据, 数据...) // 返回第一个不为null的值
注释:nullif(值, 字段) 两个值相等,返回null, 不相等返回第一个值。只能得到值1或null两种结果
数字转字符: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'
向上取整:ceil(值) // ceiling(数值) 小数有值进1
向下取整:floor(值) // 小数舍弃
向0取值:trunc(值) // 正数有小数舍弃,负数有小数进1
四舍五入:round(x, y) // round(x)
拼接:concat(s1,s2) // 忽略null,双竖线拼接有null返回null, concat_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
系统日期: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'
日期+时间=日时,日期-日期=天数