PostgreSQL 入门
PG 简介
PostgreSQL
是一个免费的对象-关系数据库服务器(ORDBMS),在灵活的 BSD
许可证下发行
- PostgreSQL 官网
https://www.postgresql.org/
- PostgreSQL 中文社区
http://www.postgres.cn/v2/home
- 全球数据库排行
https://db-engines.com/en/
- 国产数据库排行
https://www.modb.pro/dbRank
PG 的历史
PostgreSQL
最初设想于 1986 年,当时被叫做Berkley Postgres Project
- 该项目一直到 1994 年都处于演进和修改中,直到开发人员
Andrew Yu
和Jolly Chen
在Postgres
中添加了一个 SQL(Structured Query Language
,结构化查询语言)翻译程序,该版本叫做Postgres95
,在开放源代码社区发放, 以社区的形式运作。 - 1996 年,再次对
Postgres95
做了较大的改动,并将其作为PostgresSQL6.0
版发布。该版本的Postgres
提高了后端的速度,包括增强型 SQL92 标准以及重要的后端特性(包括子选择、默认值、约束和触发器) - 2005 年,发布 8.0 版本,开始支持
windows系统
环境 PostgreSQL 9.0
:支持64位windows系统
,异步流数据复制
、Hot Standby
;PostgreSQL 9.1
:支持数据同步复制,unlogged tabels
、serializable snapshot isolation
、FDW
外部表。- 此版本后,
PostgreSQL
开始得到中国多个行业用户的关注,开始有应用于电信、保险、制造业等边缘系统。 - 目前生产环境主流的版本是
PostgreSQL 12
- 2021-09-30,PostgreSQL 全球开发组宣布,功能最为强大的开源数据库,
PostgreSQL 14
版本正式发布!
PG 的社区
- 纯社区
- 最终用户:希望社区长久,期望可以享受免费的、可持续发展的、开源的、不被任何商业公司、不被任何国家控制的企业级数据库。去 O,去 DB2 ,去 Sybase;
- 云厂商:自研是最佳选择,但是自研有一些问题:譬如需要培养生态,需要市场背书,需要大量研发资源,可能需要重复造轮子;
- 数据库厂商: 需要一款可以无法律风险,二次分发的开源数据库,唯有 PG
- 数据库服务|DaaS 服务提供商
- 完善的组织结构
- 开源许可独特性
- BSD 许可协议(英语:Berkeley Software Distribution license)是自由软件中使用最广泛的许可协议之一。BSD 就是遵照这个许可证来发布。BSD 许可协议,二开版本可开源也可闭源商用。
- 跟其他条款相比,从 GNU 通用公共许可证(GPL)到限制重重的著作权(Copyright),BSD 许可证比较宽松,甚至跟公有领域更为接近。”Take it down to the copy center and make as many copies as you want”。可以说,GPL 强迫后续版本必须一样是自由软件,BSD 的后续版本可以选择要继续是 BSD 或其他自由软件条款或封闭软件等等。
PostgreSQL 与 MySQL 的比较
PostgreSQL 相对于 MySQL 的优势
- 在 SQL 的标准实现上要比 MySQL 完善,而且功能实现比较严谨。
- 对表连接支持较完整,优化器的功能较完整,支持的索引类型很多,复杂查询能力较强。
- PG 主表采用堆表存放,MySQL 采用索引组织表,能够支持比 MySQL 更大的数据量。
- PG 的主备复制属于物理复制,相对于 MySQL 基于 binlog 的逻辑复制,数据的一致性更加可靠,复制性能更高,对主机性能的影响也更小。
- PostgreSQL 支持 JSON 和其他 NoSQL 功能,如本机 XML 支持和使用 HSTORE 的键值对。它还支持索引 JSON 数据以加快访问速度,特别是 10 版本 JSONB 更是强大。
- PostgreSQL 完全免费,而且是 BSD 协议,MySQL 现在主要是被 Oracle 公司控制(GPL 协议)。
MySQL 相对于 PG 的优势
innodb
的基于回滚段实现的MVCC机制
,相对 PG 新老数据一起存放的基于XID的MVCC机制
,是占优的。新老数据一起存放,需要定时触 发VACUUM
,会带来多余的 IO 和数据库对象加锁开销,引起数据库整体的并发能力下降。而且VACUUM
清理不及时,还可能会引发数据膨胀。
MVCC (Multiversion Concurrency Control) 中文全程叫多版本并发控制,是现代数据库(包括 MySQL、Oracle、PostgreSQL 等)引擎实现中常用的处理读写冲突的手段,目的在于提高数据库高并发场景下的吞吐性能。
MySQL
采用索引组织表,这种存储方式非常适合基于主键匹配的查询、删改操作,但是对表结构设计存在约束。MySQL
的优化器较简单,系统表、运算符、数据类型的实现都很精简,非常适合简单的查询操作。MySQL
相对于 PG 在国内的流行度更高,PG 在国内显得就有些落寞了。MySQL
的存储引擎插件化机制,使得它的应用场景更加广泛,比如除了innodb
适合事务处理场景外,myisam
适合静态数据的查询场景。
PostgreSQL 的下载安装
Windows 上安装 PostgreSQL
访问官网下载地址 https://www.enterprisedb.com/downloads/postgres-postgresql-downloads
下载最新发布的
PostgreSQL 16
双击下载安装包,开始安装选择安装组件
设置数据库路径
设置超级用户的密码
设置端口号,可以直接用默认 5433 就行
去掉勾选,直接点 Finish
打开 pgAdmin 4
点击左侧的 Servers > Postgre SQL 10
输入密码,点击 OK 即可,控制面板如下
打开 SQL Shell(psql)
远程访问
- 打开 postgresql 安装目录的 data 子目录
- 修改 pg_hba.conf 文件:在 IPV4 部分添加新的一行: host all all 0.0.0.0/0 md5
- 控制面板–> 系统与安全–> Windows 防火墙, 关闭防火墙。
- 重启 postGresql 服务
Linux 上安装 PostgreSQL
下载安装
访问官网下载地址 https://www.postgresql.org/download/
选择相应的版本和平台
1
2
3
4
5
6
7
8Install the repository RPM:
sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
Install PostgreSQL:
sudo yum install -y postgresql14-server
Optionally initialize the database and enable automatic start:
sudo /usr/pgsql-14/bin/postgresql-14-setup initdb
sudo systemctl enable postgresql-14
sudo systemctl start postgresql-14导入 yum 源
1
sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
安装
PostgreSQL
服务1
sudo yum install -y postgresql14-server
初始化数据库
1
sudo /usr/pgsql-14/bin/postgresql-14-setup initdb
启动 PostgreSQL 服务
1
2
3
4#设置 PostgreSQL 服务为开机启动
sudo systemctl enable postgresql-14
#启动 PostgreSQL 服务
sudo systemctl start postgresql-14
修改 postgres 账号密码
PostgreSQL
安装成功之后,会默认创建一个名为postgres
的 Linux 用户,初始化数据库后,会有名为postgres
的数据库,来存储数据库的基础信息,例如用户信息等等,相当于 MySQL 中默认的名为 mysql 数据库。postgres
数据库中会初始化一名超级用户postgres
为了方便我们使用
postgres
账号进行管理,我们可以修改该账号的密码进入
PostgreSQL
命令行通过 su 命令切换
linux
用户为postgres
会自动进入命令行1
su postgres
启动 SQL Shell
1
psql
修改密码
1
ALTER USER postgres WITH PASSWORD 'NewPassword';
配置远程访问
开放端口
1
2sudo firewall-cmd --add-port=5432/tcp --permanent
sudo firewall-cmd --reload修改 IP 绑定
1
2
3
4
5#修改配置文件
vi /var/lib/pgsql/14/data/postgresql.conf
#将监听地址修改为*
#默认 listen_addresses 配置是注释掉的,所以可以直接在配置文件开头加入该行
listen_addresses='*'允许所有 IP 访问
1
2
3
4
5#修改配置文件
vi /var/lib/pgsql/14/data/pg_hba.conf
#在文件尾部加入
host all all 0.0.0.0/0 md5重启 PostgreSQL 服务
1
2#重启 PostgreSQL 服务
sudo systemctl restart postgresql-14
PostgreSQL 的基本使用
登录
登录
1
2
3
4psql -h 服务器 -U 用户名 -d 数据库 -p 端口地址 // -U 是大写
psql -U dbuser -d exampledb -h 127.0.0.1 -p 5432
psql (连接数据库,默认用户和数据库都是postgres)
相当于系统用户 postgres 以同名数据库用户的身份,登录数据库,这是不用输入密码的。如果一切正常,系统提示符会变为 "postgres =#",表示这时已经进入了数据库控制台。
数据库操作
数据库操作
1
2
3
4
5
6
7
8#创建数据库
CREATE DATABASE mydb;
#查看所有数据库
\l
#切换当前数据库
\c mydb
#删除数据库
drop database <dbname>
数据库值类型
创建表格时每列都必须使用数据类型。PotgreSQL 中主要有三类数据类型:
- 数值数据类型
- 字符串数据类型
- 日期/时间数据类型
数值数据类型
名字 存储长度 描述 范围 smallint 2 字节 小范围整数 -32768 到+32767 integer 4 字节 常用的整数 -32768 到+32767 bigint 8 字节 大范围整数 -9223372036854775808 到 +9223372036854775807 decimal 可变长 用户指定的精度,精确 小数点前 131072 位;小数点后 16383 位 numeric 可变长 用户指定精度,精确 小数点前 131072 位;小数点后 16383 位 real 4 字节 可变精度,不精确 6 位十进制数字精度 double 8 字节 可变精度,不精确 15 位十进制数字精度 字符串字符串类型包括
- char(size),character(size):固定长度字符串,size 规定了需存储的字符数,由右边的空格补齐;
- varchar(size),character varying(size):可变长度字符串,size 规定了需存储的字符数;
- text:可变长度字符串。
日期/时间 表示日期或时间的数据类型有:
- timestamp:日期和时间;
- date:日期,无时间;
- time:时间;
其他数据类型类型还有
布尔值 boolean
(true 或 false),货币数额 money
和几何数据
等
数据库表操作
CRUD 表
1
2
3
4
5
6
7
8
9
#创建表
CREATE TABLE test(id int,body varchar(100));
#在表中插入数据
insert into test(id,body) values(1,'hello,postgresql');
#查看当前数据库下所有表
\d
#查看表结构,相当于 desc
\d testPostgreSQL 使用序列来标识字段的自增长
数据类型有
smallserial
、serial
和bigserial
。这些属性类似于 MySQL 数据库支持的AUTO_INCREMENT
属性SMALLSERIAL
、SERIAL
和BIGSERIAL
范围:伪类型 存储大小 SALLSERIAL 2 字节 SERIAL 4 字节 BIGSERIAL 8 字节
示例
1
2
3
4
5
6
7
8
9
10
11
12
13#创建表
CREATE TABLE COMPANY(
ID SERIAL PRIMARY KEY,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);
#插入数据
INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY)
VALUES ( 'Paul', 32, 'California', 20000.00 );
INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY)
VALUES ('Allen', 25, 'Texas', 15000.00 );
Schema
PostgreSQL 模式(SCHEMA)可以看着是一个表的集合。
一个模式可以包含视图、索引、数据类型、函数和操作符等。
相同的对象名称可以被用于不同的模式中而不会出现冲突,例如 schema1 和 myschema 都可以包含名为 mytable 的表。
使用模式的优势:
- 允许多个用户使用一个数据库并且不会互相干扰
- 将数据库对象组织成逻辑组以便更容易管理。
- 第三方应用的对象可以放在独立的模式中,这样它们就不会与其他对象的名称发生冲突
模式类似于操作系统层的目录,但是模式不能嵌套
1
2
3
4
5
6
7
8
9
10
11
12
13
14#创建schema:
create schema myschema;
create table myschema.company(
ID INT NOT NULL,
NAME VARCHAR (20) NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR (25),
SALARY DECIMAL (18, 2),
PRIMARY KEY (ID)
);
#删除schema:
drop schema myschema;
#删除一个模式以及其中包含的所有对象:
DROP SCHEMA myschema CASCADE;
备份 PostgreSQL 数据库
如果在生产环境中使用 PostgreSQL,请务必采取预防措施以确保用户的数据不会丢失
单数据库
PostgreSQL
提供了pg_dump
实用程序来简化备份单个数据库的过程。 必须以对要备份的数据库具有读取权限的用户身份运行此命令。
以
postgres
用户身份登录:1
sudo su - postgres
通过运行以下命令将数据库的内容转储到文件中。替换 dbname 为要备份的数据库的名称
1
pg_dump dbname > dbname.bak
生成的备份文件 dbname.bak 可以使用 scp 传输到另一台主机,也可以存储在本地以供以后使用。要演示恢复丢失的数据,请删除示例数据库并在其位置创建一个空数据库:
- 使用 psql 恢复数据库
1
2
3
4
5psql test < dbname.bak
#备份格式有几种选择:
# 1. *.bak:压缩二进制格式
# 2. *.sql:明文转储
# 3. *.tar:tarball注意:默认情况下,
PostgreSQL
将忽略备份过程中发生的任何错误。这可能导致备份不完整。要防止这种情况,您可以使用-1
选项运行pg_dump
命令。 这会将整个备份过程视为单个事务
,这将在发生错误时阻止部分备份。所有数据库
由于
pg_dump
一次只创建一个数据库的备份,因此它不会存储有关数据库角色或其他群集范围配置的信息。 要存储此信息并同时备份所有数据库,可以使用pg_dumpall
。创建备份文件:
1
pg_dumpall > pg_backup.bak
从备份还原所有数据库:
1
psql -f pg_backup.bak postgres
示例
1
2
3
4
5
6
7
8
9备份数据库
pg_dump -U postgres -f /tmp/postgres.sql postgres (导出postgres数据库保存为postgres.sql)
pg_dump -U postgres -f /tmp/postgres.sql -t test postgres (导出postgres数据库中表test的数据)
pg_dump -U postgres -F t -f /tmp/postgres.tar postgres (导出postgres数据库以tar形式压缩保存为postgres.tar)
恢复数据库
psql -U postgres -f /tmp/postgres.sql bk01 (恢复postgres.sql数据到bk01数据库)
pg_restore -- 从 pg_dump 创建的备份文件中恢复 PostgreSQL 数据库, 用于恢复由 pg_dump 转储的任何非纯文本格式中的 PostgreSQL 数据库。
pg_restore -U postgres -d bk01 /tmp/postgres.tar (恢复postgres.tar数据到bk01数据库)
用户操作
用户操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#创建用户并设置密码
CREATE USER 'username' WITH PASSWORD 'password';
CREATE USER test WITH PASSWORD 'test';
#修改用户密码
$ ALTER USER 'username' WITH PASSWORD 'password';
#数据库授权,赋予指定账户指定数据库所有权限
$ GRANT ALL PRIVILEGES ON DATABASE 'dbname' TO 'username';
#将数据库 mydb 权限授权于 test
GRANT ALL PRIVILEGES ON DATABASE mydb TO test;
#但此时用户还是没有读写权限,需要继续授权表
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO xxx;
#注意,该sql语句必须在所要操作的数据库里执行
#移除指定账户指定数据库所有权限
REVOKE ALL PRIVILEGES ON DATABASE mydb from test
#删除用户
drop user test
# 查看用户
\dupg_hba.conf
配置中的第一项设置的意思是:本地用户通过unix socket
登陆时,使用peer
方式认证
```1
2# "local" is for Unix domain socket connections only
local all all peer1
2
3
4
5
6
7
> `peer`是用`PostgreSQL`所在的操作系统上的`用户登陆`。`peer`方式中,`client`必须和`PostgreSQL`在**同一台机器**上。只要当前`系统用户`和要登陆到`PostgreSQL`的用户名相同,就可以登陆。在刚部署`PostgreSQL`之后,切换到系统的`postgres`用户后,直接执行`psql`就能进入`PostgreSQL`就是这个原因(当前系统用户为名`postgre`,`PostgreSQL`中的用户名也是`postgre`)。
* 在`PostgreSQL`中创建一个没有密码的用户:
``` sql
create user local_user1;- 切换到local_user1用户后,就可以直接通过unix_socket登陆PostgreSQL:
1
2
3
4
5
6# su - local_user1
[local_user1@10 ~]$ psql postgres
psql (9.2.24)
Type "help" for help.
postgres =>注意:要指定数据库名,如果不指定默认使用与用户同名的数据库。
peer
不是常用的方式!最常用的方式是通过密码远程登陆
PostgreSQL 角色管理
角色管理
在
PostgreSQL
里没有区分用户和角色的概念,"CREATE USER"
为"CREATE ROLE"
的别名,这两个命令几乎是完全相同的,唯一的区别是"CREATE USER"
命令创建的用户默认带有LOGIN
属性,而"CREATE ROLE"
命令创建的用户默认不带LOGIN
属性创建david 角色和sandy 用户
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29postgres =# CREATE ROLE david; //默认不带 LOGIN 属性
CREATE ROLE
postgres =# CREATE USER sandy; //默认具有 LOGIN 属性
CREATE ROLE
postgres =# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------+-----------
david | Cannot login | {}
postgres | Superuser, Create role, Create DB, Replication | {}
sandy | | {}
postgres =#
postgres =# SELECT rolname from pg_roles ;
rolname
----------
postgres
david
sandy
(3 rows)
postgres =# SELECT usename from pg_user; //角色 david 创建时没有分配 login 权限,所以没有创建用户
usename
----------
postgres
sandy
(2 rows)
postgres =#
创建用户时赋予角色属性
- 如果要在创建角色时就赋予角色一些属性,可以使用下面的方法。
首先切换到postgres 用户。
创建角色bella 并赋予其CREATEDB 的权限。
1
2
3
4
5
6
7
8
9
10
11
12postgres =# CREATE ROLE bella CREATEDB ;
CREATE ROLE
postgres =# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------+-----------
bella | Create DB, Cannot login | {}
david | | {}
postgres | Superuser, Create role, Create DB, Replication | {}
sandy | | {}
postgres =#
创建角色renee 并赋予其创建数据库及带有密码登录的属性。
1
2
3
4
5
6
7
8
9
10
11
12
13postgres =# CREATE ROLE renee CREATEDB PASSWORD 'abc123' LOGIN;
CREATE ROLE
postgres =# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------+-----------
bella | Create DB, Cannot login | {}
david | | {}
postgres | Superuser, Create role, Create DB, Replication | {}
renee | Create DB | {}
sandy | | {}
postgres =#测试renee 角色
1
2
3
4
5postgres -DEV:~> psql -U renee -d postgres
psql (9.1.0)
Type "help" for help.
postgres =>
给已存在用户赋予各种权限
赋予登录权限
1
2
3
4
5
6
7
8
9
10
11
12
13postgres =# ALTER ROLE bella WITH LOGIN;
ALTER ROLE
postgres =# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------+-----------
bella | Create DB | {}
david | | {}
postgres | Superuser, Create role, Create DB, Replication | {}
renee | Create DB | {}
sandy | | {}
postgres =#赋予renee 创建角色的权限
1
2
3
4
5
6
7
8
9
10
11
12
13postgres =# ALTER ROLE renee WITH CREATEROLE;
ALTER ROLE
postgres =# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------+-----------
bella | Create DB | {}
david | | {}
postgres | Superuser, Create role, Create DB, Replication | {}
renee | Create role, Create DB | {}
sandy | | {}
postgres =#
控制台常用命令总结
控制台常用命令总结
1
2
3
4
5
6
7
8
9
10\password 命令(设置密码)
\q 命令(退出)
\h:查看 SQL 命令的解释,比如\h select。
\?:查看 psql 命令列表。
\l:列出所有数据库。
\c [database_name]:连接其他数据库。
\c - [username]: 切换用户
\d:列出当前数据库的所有表格。
\d [table_name]:列出某一张表格的结构。
\du:列出所有用户。