Postgresql学习笔记

概述

postgresql是一个开源的关系型数据库,可以作为mysql的替代品。
本篇意在让读者快速的了解postgresql的基本概念,使用的版本是postgresql9.6本,如有错误欢迎指正。

参考书籍

《PostgreSQL 9 Administration Cookbook》第二版。

本篇省略的东西

有些内容比较冗长,或者使用场景较少,或者过于复杂,建议参考具体的手册,本篇将会省略。

  • 选择postgresql的理由。
  • 常用的用于操作的语法、语句。
  • 数据库函数的编写与执行。
  • 不同数据库、模式、表空间之间的数据移动。
  • 访问其他postgres数据库或者其他类型的数据库。
  • 自动数据库维护的定制化配置。
  • 数据库的复制配置。
  • 数据库的升级操作。

postgres服务使用

发音

post-gres-q-l。

下载、安装、启动

基本上主流unix操作系统的库里都有制作好的安装包,直接安装即可,然后用相应的系统服务启动。
也可以使用命令行工具启动或者停止。
-m参数可以指定关闭方式,fast会等待所有操作完毕后再关闭,immediate则会强行关闭。

pg_ctl -D Datadir start
pg_ctl -D Datadir -m fast stop
pg_ctl -D Datadir -m immediate stop

每个服务在初始化的时候都会被分配一个系统标识符,很多系统操作需要使用到,可以通过如下命令获得。

pg_controldata Datadir | grep “system identifier”

版本号

postgreql的版本号组成为:主版本号.次版本号.维护版本号,它的特性和兼容性是由主版本号和次版本号共同决定的。

psql --version

连接

初始管理员用户:postgres,密码:postgres,数据库:postgres。

psql postgres://user:password@host:port/db
psql -U user -W password -h host -p port -d db

变量 默认值
user 当前用户
password
host localhost
port 5432
db postgres

每个连接在同一时刻只允许有一个活跃的事务,并且在任何时刻只允许有一个完全活跃的语句。

数据库

psql -l

template0和template1是两个数据库模板,template1是可以修改的,用来自定义。

命令行执行语句和脚本

psql -c "SELECT current_time"
psql -f test.sql

postgres客户端

帮助

postgres=# help
postgres=# ?
postgres=# \h

注释

-- 单行注释
/*
* 多行注释
*/

退出

postgres=# \q

开关一行显示一列数据

postgres=# \x

运行操作系统的命令

postgres=# \! cat test.sql

命令从文件中定向输入

postgres=# \i test.sql

临时数据库配置,LOCAL表示仅对当前事务生效

postgres=# SET work_mem = '16MB';
postgres=# SET LOCAL work_mem = '16MB';
postgres=# RESET work_mem;
postgres=# SHOW work_mem;

管理数据库插件

postgres=# CREATE EXTENSION myext;
postgres=# ALTER EXTENSION myext UPDATE;
postgres=# DROP EXTENSION myext;

更新所有表大小和数据分布的统计信息

postgres=# ANALYZE;

垃圾回收

postgres=# VACUUM;

postgres数据管理

服务(server)

  • 一个操作系统中可以启动多个postgres服务。
  • 每个服务由多个进程组成,为首的进程名为postmaster。
  • 每个服务要占用一个端口,多个服务不能共享端口。
  • 每个服务都有一个data目录用于存放数据,目录不允许修改,否则会破坏数据库,并且无法修复。
  • 服务使用4字节长的内部事务标识符,即时发生重叠后仍然继续使用,这会导致问题,所以需要定期进行VACUUM操作。

数据库(database)

  • 一个服务中可以拥有多个数据库。
  • 数据库默认是任何用户可连接的,创建好后需要修改相应的权限。
  • 数据库之间的数据是隔离的,不能进行联表。
  • 数据库默认的数据块大小为8192。

模式(schema)

  • 一个数据库中可以有多个模式,模式相当于表的命名空间,类似于mysql中的database,可以使用带模式的完整名称来访问或者创建对象。
  • 不同模式之间的表是可以联表查询的。
  • 可以通过对用户设置search_path参数来指定默认搜索的模式。

表(table)

  • 一个模式中可以有多张表。
  • 表是由多个关系元素组成的,大字段数据放在另一个名为TOAST的表中,每张表都有一个TOAST表和TOAST索引。
  • 用双引号括起来的表和没用双引号括起来的表是不一样的,即使名字一样。
  • 双引号括起来的表区分大小写,没用双引号括起来的表不区分大小写。

列(column)

  • 每张表都由许多列组成,每一列有一个列名、类型、默认值等属性,用来存储每一条记录中的各种值。
  • 文本类型统一由一种数据类型存储,支持长度从1B到1G,经过优化,存储少的时候很高效,存储多的时候会自动管理和压缩。
  • 自增类型serial本质上就是整数,通过创建并关联到一个SEQUENCE类型的对象来记录自增值。

表空间(tablespace)

  • 默认情况下,所有的数据都会放在postgres指定的data目录下,通过定义表空间,可以让postgres将数据存放在不同的设备上。
  • 表空间是通过软链接来实现的。
  • 建议为每个数据库设立一个单独的表空间,尤其是不同数据库中有同名的模式或者表的时候。

postgres=# CREATE TABLESPACE tbs LOCATION '/usr/local/tbs';

视图(view)

  • 视图本质上是预定义好的一个sql查询,以一张表的形式给出,在每次调用时都会执行相应的sql查询。

postgres=# CREATE VIEW view AS SELECT * FROM tb;

  • 当视图足够简单的时候,postgres是支持视图更新的,相应的更新会传递到相应的表中。
    还可以使用INSTEAD OF触发器或者规则来实现视图更新,请参考具体的操作手册。
  • 物化视图可以预先将数据查询出来,这样调用的时候就不必反复查询了,更新需要手动更新。

postgres=# CREATE MATERIALIZED VIEW view AS SELECT * FROM tb;
postgres=# REFRESH MATERIALIZED VIEW view;

行(row)

  • 行即表中的一条数据。
  • postgres中每个行都有一个行版本,而且还有两个系统列xmin和xmax,分别标示这个行被创建和删除的事务。
    删除时,设置xmax为删除事务号,不会实际执行删除。
  • UPDATE操作被认为是紧跟INSERT操作后的DELETE操作。

索引(index)

  • 索引可以用来给表添加约束或者提高查询速度。
  • 在涉及高比例插入\删除的表中,会造成索引膨胀,这时候可以重建索引。

reindexdb

  • 创建CONCURRENTLY索引时不会持有全表锁,这条指令分成两个步骤,第一部分创建索引并标记为不可用,这时候INSERT、UPDATE、DELETE操作已经开始维护索引了,但是查询不能使用索引。建立完毕后才会被标记为可用。

postgres=# CREATE CONCURRENTLY INDEX index ON tb(id);

  • 可以手工设置索引的可用性。

UPDATE pg_index SET indisvalid = false WHERE indexrelid = index::regclass;

postgres目录结构

子目录 用途
base 主数据目录。此目录中每个数据库都有自己的目录,以oid号命名,其中包含用于每张表和索引的文件
global 数据库中的系统表,在所有的数据库中共享
pg_clog 事务状态文件
pg_dynshmem 动态共享内存信息
pg_multixact 行锁状态文件
pg_notify 监听和通知的状态文件
pg_replslot 复制槽位的信息
pg_serial 已提交的序列化事务信息
pg_snapshot 输出的快照文件
pg_stat 服务活动统计以及持久文件
pg_stat_tmp 服务活动统计以及临时文件
pg_subtrans 子事务状态文件
pg_tblspc 连接到外部的表空间
pg_twophase “两阶段提交”事务状态
pg_xlog 事务日志WAL

postgres权限控制

连接权限

首先要修改数据目录下的postgresql.conf文件来允许它监听所有地址。修改完后需要重启服务。

listen_addresses = '*'

postgres连接的权限在数据目录下的pg_hba.conf文件中按照指定格式进行定义,每次连接会按照顺序检查每条规则,直到匹配到通过策略或者拒绝策略。

#TYPE DATABASE USER ADDRESS METHOD
host all all 127.0.0.1/32 password

每条策略的参数如下:

  • type:连接类型,local表示允许本地socket连接、host表示允许ip连接、hostssl表示允许ssl连接。
  • database:连接的数据库,all表示所有、sameuser表示用户名和数据库名相同、其他表示数据库名称。
  • user:连接的用户,all表示所有用户、其他表示连接的数据库用户。
  • address:允许连接的子网和子网掩码。
  • method:认证方式,trust表示允许、password表示密码、md5表示加密密码、cert表示证书、ldap表示ldap认证,对于证书认证之后还会有一个参数来配置证书。

权限模型

  • postgres采用角色(ROLE)-权限(PRIVILEGE)模型。
  • 权限主要有USAGE、SELECT、INSERT、UPDATE、DELETE五种。
  • 角色分两种,可以登录的用户(USER)与不可以登录的组(GROUP)。
  • 角色可以继承。

postgres=# CREATE USER user;
postgres=# CREATE ROLE role NOLOGIN;
postgres=# GRANT role1 TO role2;

特殊权限

  • postgres中有一些特殊权限,不能被授予,也不会被继承,分别是SUPERUSER、CREATEDB和CREATEUSER;
  • 特殊权限单独对用户进行授予或者回收。

角色切换与权限继承

  • 用户可以切换到自己拥有的角色。

postgres=# SET ROLE TO role;

  • 可以通过NOINHERIT参数来创建不会继承角色的用户,这样用户只有切换角色才能获得相应的权限。

postgres=# CREATE USER user NOINGERIT;

postgres支持的数据类型

  • 整数:smallint、integer、bigint
  • 实数:real、double
  • 自增数:smallserial、serial、bigserial
  • 高精度:decimal、numeric

  • 有限不定长字符串:varchar
  • 有限定长字符串:char
  • 无限不定长字符串:text
  • 位串:bit
  • UUID

几何

  • 点:point
  • 线:line、lseg
  • 矩形:box
  • 圆:circle
  • 路径:path
  • 多边形:polygon

其他

  • 布尔:boolean
  • 枚举:enum
  • 二进制:bytea
  • 时间:date、time、timestamp、interval
  • 货币:money
  • 网络地址:cidr、inet、macaddr
  • 数据格式:json、xml
  • 复合类型:table、type

postgres中一些系统变量、系统函数和系统视图

变量名 含义
current_user 当前用户
current_time 当前时间
current_timestamp 当前时间戳
current_schema 当前所在模式
current_user 当前登录的用户
session_user 当前会话的用户
函数名 功能
current_database0 当前连接的数据库
inet_server_addr() 当前服务的地址
inet_server_port() 当前服务的端口
version() 当前数据库的版本
pg_postmaster_start_time() 服务启动时间
pg_database_size() 当前数据库的大小
pg_size_pretty() 格式化尺寸数字
pg_relation_size(table) 某张表的表大小
pg_total_relation_size(table) 某张表的总大小
pg_reload_conf() 重新加载配置文件
generate_series(a, b) 从a到b顺序生成整数
random() 随机一个0到1之间的数
:: type 强制类型转换
pg_cancel_backend(pid) 取消当前查询
pg_terminate_backend(pid) 杀死后端进程
pg_stat_reset() 重置表的统计信息
pg_stat_statements_reset() 重置查询的统计信息
视图名 内容
pg_database 服务中的数据库信息
pg_catalog 系统信息
pg_extension 扩展插件信息
pg_available_extensions 可用扩展插件信息
pg_constraint 表之间的约束信息
pg_settings 数据库的配置
pg_stat_activity 后台进程的信息
pg_stat_user_tables 当前使用情况统计信息
pg_stat_database 数据库的统计信息
pg_stat_statements 被执行的查询的执行状态
pg_locks 锁信息
pg_prepared_xacts 准备事务的信息
pg_index 索引的信息
pg_class 实体的信息
pg_stat_replication 复制的状态

postgres脚本执行

postgres会按照顺序执行脚本中的每条指令,遇到错误会报错并继续执行接下来的指令。

事务

事务的功能是让一批指令要么同时执行成功,要么同时执行失败。本质上postgres会按照顺序执行指令,一旦遇到错误,就回滚之前的指令。
事务是不能够嵌套的,否则后续的BEGIN会被忽略。

postgres=# BEGIN;
postgres=# command1;
postgres=# command2;
postgres=# COMMIT;

因为事务的特性,使得事务中不能包含以下命令。

  • CREATE/DROP DATABASE/TABLESPACE
  • CREATE INDEX CONCURRENTCY
  • VACUUM
  • REINDEX DATABASE / REINDEX SYSTEM
  • CLUSTER

遇错退出

通过设置开关来实现遇到错误就停止脚本。

psql -f test.sql -v ON_ERROR_STOP=on
postgres=# \set ON_ERROR_STOP

数据导入与导出

postgres提供两个工具来进行数据导入和导出,pg_dump和pg_dumpall。

  • pg_dump工具产生一个默认轻量压缩的自定义格式归档文件,通过pg_restore恢复;pg_dumpall工具产生一个脚本文件,通过psql执行。
  • pg_dump不会导出角色和表空间;pg_dumpall可以导出全局对象,也可以只导出全局对象。
  • pg_dump和gp_restore可以并行,pg_dumpall和psql只能串行。
  • pg_dump也可以通过选项-F p来生成脚本文件。
    postgres还可以进行热物理备份,需要遵循步骤来处理备份中的增量数据,详细信息请参考手册。

复制

postgres提供两种复制方法,物理流复制和逻辑流复制。
之前还有一种基于日志文件传送的复制,主节点将数据库更改记录到事务日志,然后将日志文件从主节点传动到备节点,之后备节点再重演日志。现在它已经被流复制取代了,不推荐使用。

  • 物理流复制获取事务日志WAL并将数据传送到远程节点,WAL包含数据块中发生的改变的精确物理备份,因此远程节点是主节点的精确副本,也无法执行写入到数据库的事务。
  • 逻辑流复制允许远程节点复制数据而不需要保持数据库的完整副本,复制中所有形式的身份验证和安全工作都和普通的连接相同。逻辑流复制可以实现多主复制。
  • 复制槽位功能允许明确定义复制架构,还允许即使在节点连接断开的情况下跟踪节点的细节。逻辑流复制以及任何其他使用逻辑解码功能的工具都需要复制槽位,但对于物理流是可选的。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容