一、PostgreSQL语法
PostgreSQL表、模式、库三者之间的关系
库 -> 模式 -> 表、视图、函数等等对象。
在postgresql的交互式终端psql中,"\"开头的命令称为元命令(类似mysql的show语句),用于快速管理数据库。
常见元命令:
\1 列出所有数据库
\c [数据库名] 或 \connect [数据库名]
\dn 列出所有模式(Schema)
\? 显示pgsql命令的说明(元命令查询帮助)
\q 退出psql
\dt 列出当前数据库的所有表
\d [TABLE] 查看表结构
\du 列出所有用户
库和表相关命令
1.列出库
方法一:\l
方法二:\l+
方法三:select datname from pg_database;
pg_database是系统表,存储了PostgreSQL实例中所有数据库的元信息(如数据库名称、所有者、编码等)。属于系统目录(system catalog):类似mysql的information_schema,但postgresql的系统目录更底层且直接存储在pg_catalog模式中。
pg_database是系统目录表,所以无论当前连接到哪个数据库,该表始终可见,系统表默认属于pg_catalog模式,而pg_catalog始终位于搜索路径(search_path)的首位。因此,查询时无需显式指定模式(如 pg_catalog.pg_database)
2.创建库
create database 库名;
3.删除库
drop database 库名;
4.切换库
\c 库名;
5.查看库大小
方法一:以字节为单位返回数据库的大小
select pg_database_size('库名');
方法二:人性化返回数据库的大小(带k、m等等)
select pg_size_pretty(pg_database_size('库名'));
6.列出表
\dt; (显示search_path中模式里的表,默认public。)
\d (列出表,视图和序列。)
\d+ (列出表,视图和序列。)
\dt my_schema.* (列出指定模式下的表(例如 my_schema))
\dt *.* (查看当前数据库的所有表(包括系统表))
select * from pg_tables where schemaname='public'; (使用sql方式列出当前数据库中public模式下的所有表及其详细信息。)
7.创建表
create table tablename(字段1 类型,字段2 类型 ,... 字段n 类型);
8.复制表
create table new_table as table table_name;
9.删除表
drop table 表名;
10.查看表结构
\d 表名;
11.在指定模式中创建表
create table 模式名.表名(字段1 类型,字段2 类型 ,... 字段n 类型);
模式操作命令
1.创建模式
create schema 模式名;
2.显示搜索路径
show search_path;
3.删除模式
drop schema 模式名;
4.查看所有模式
\dn
select 列名 from 模式名.表名;
select schema_name from information_shcema.schemata;
schema_name是列名 information_schema是模式名 shcemata是表名
5.切换当前模式
切换到单个schema
set search_path to new_schema;
切换到多个schema(按优先级排序)
set search_path to 模式名1,模式名2;
6.查看当前所在schema
select current_schema();
7.查看搜索路径(search path)
show search_path;
数据操作相关
1.添加数据
insert into tablename values(value1,value2,...valuen);
2.查询数据
select * from tablename;
3.修改数据
update tablename set 字段=值 where 条件;
4.删除数据
delete from tablename where 条件;
PostgreSQL的三种备份方式
1.SQL转储
2.文件系统级备份
3.连续归档
SQL转储最常用
备份语法,使用pg_dump命令。(一次备份一个库。)
pg_dump dbname > dumpfile
pg_dump -h host1 dbname | psql -h host2 dbname # 从主机1转储到主机2
恢复语法,使用psql命令。
psql dbname < dumpfile
psql --set ON_ERROR_STOP=om dbname < infile # 遇到错误退出。
备份给定数据库集簇中的全部内容,使用pg_dumpall命令。
备份语法
pg_dumpall > dumpfile
恢复语法
psql -f dumpfile postgres
杂七杂八
配置密码
alter user username with password 'password';
远程连接
psql -h remoteip
二、PostgreSQL示例
sql
列出库
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale
Provider | Access privileges
-----------+----------+----------+-------------+-------------+------------+-------
----------+-----------------------
postgres | postgres | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | | libc
|
template0 | postgres | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | | libc
| =c/postgres +
| | | | | |
| postgres=CTc/postgres
template1 | postgres | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | | libc
| =c/postgres +
| | | | | |
| postgres=CTc/postgres
(3 rows)
postgres=# \l+
List of databases
Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale
Provider | Access privileges | Size | Tablespace | Descript
ion
-----------+----------+----------+-------------+-------------+------------+-------
----------+-----------------------+---------+------------+------------------------
--------------------
postgres | postgres | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | | libc
| | 7229 kB | pg_default | default administrative
connection database
template0 | postgres | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | | libc
| =c/postgres +| 7073 kB | pg_default | unmodifiable empty data
base
| | | | | |
| postgres=CTc/postgres | | |
template1 | postgres | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | | libc
| =c/postgres +| 7153 kB | pg_default | default template for ne
w databases
| | | | | |
| postgres=CTc/postgres | | |
(3 rows)
postgres=# select datname from pg_database;
datname
-----------
postgres
template1
template0
(3 rows)
创建、删除、切换库
postgres=# create database mydb;
CREATE DATABASE
postgres=# drop database mydb;
DROP DATABASE
postgres=# \c mydb
connection to server on socket "/tmp/.s.PGSQL.5432" failed: FATAL: database "mydb" does not exist
Previous connection kept
postgres=# create database mydb;
CREATE DATABASE
postgres=# \c mydb
You are now connected to database "mydb" as user "postgres".
查看库大小
mydb=# select pg_database_size('mydb');
pg_database_size
------------------
7484207
(1 row)
mydb=# select pg_size_pretty(pg_database_size('mydb'));
pg_size_pretty
----------------
7309 kB
(1 row)
列出表
mydb=# create table aaa (id int,name varchar);
CREATE TABLE
mydb=# \dt;
List of relations
Schema | Name | Type | Owner
--------+------+-------+----------
public | aaa | table | postgres
(1 row)
mydb=# \d
List of relations
Schema | Name | Type | Owner
--------+------+-------+----------
public | aaa | table | postgres
(1 row)
mydb=# \d+
List of relations
Schema | Name | Type | Owner | Persistence | Access method | Size | Des
cription
--------+------+-------+----------+-------------+---------------+------------+----
---------
public | aaa | table | postgres | permanent | heap | 8192 bytes |
(1 row)
mydb=# dt my_schema.*
mydb-# ;
ERROR: syntax error at or near "dt"
LINE 1: dt my_schema.*
^
mydb=# dt *.*
mydb-# ;
ERROR: syntax error at or near "dt"
LINE 1: dt *.*
^
mydb=# \dt *.*;
List of relations
Schema | Name | Type | Owner
--------------------+--------------------------+-------------+----------
information_schema | sql_features | table | postgres
information_schema | sql_implementation_info | table | postgres
information_schema | sql_parts | table | postgres
information_schema | sql_sizing | table | postgres
pg_catalog | pg_aggregate | table | postgres
pg_catalog | pg_am | table | postgres
pg_catalog | pg_amop | table | postgres
pg_catalog | pg_amproc | table | postgres
pg_catalog | pg_attrdef | table | postgres
pg_catalog | pg_attribute | table | postgres
pg_catalog | pg_auth_members | table | postgres
pg_catalog | pg_authid | table | postgres
pg_catalog | pg_cast | table | postgres
pg_catalog | pg_class | table | postgres
pg_catalog | pg_collation | table | postgres
pg_catalog | pg_constraint | table | postgres
pg_catalog | pg_conversion | table | postgres
pg_catalog | pg_database | table | postgres
pg_catalog | pg_db_role_setting | table | postgres
pg_catalog | pg_default_acl | table | postgres
pg_catalog | pg_depend | table | postgres
pg_catalog | pg_description | table | postgres
pg_catalog | pg_enum | table | postgres
pg_catalog | pg_event_trigger | table | postgres
pg_catalog | pg_extension | table | postgres
pg_catalog | pg_foreign_data_wrapper | table | postgres
pg_catalog | pg_foreign_server | table | postgres
pg_catalog | pg_foreign_table | table | postgres
pg_catalog | pg_index | table | postgres
pg_catalog | pg_inherits | table | postgres
pg_catalog | pg_init_privs | table | postgres
pg_catalog | pg_language | table | postgres
pg_catalog | pg_largeobject | table | postgres
pg_catalog | pg_largeobject_metadata | table | postgres
pg_catalog | pg_namespace | table | postgres
mydb=# \dt my_schema.*;
Did not find any relation named "my_schema.*".
mydb=# select * from pg_tables where schemaname='public';
schemaname | tablename | tableowner | tablespace | hasindexes | hasrules | hastri
ggers | rowsecurity
------------+-----------+------------+------------+------------+----------+-------
------+-------------
public | aaa | postgres | | f | f | f
| f
(1 row)
创建表
mydb=# create table test(id int,name char(10),age int);
CREATE TABLE
mydb=# create table test2 as table test;
SELECT 0
mydb=# \dt;
List of relations
Schema | Name | Type | Owner
--------+-------+-------+----------
public | aaa | table | postgres
public | test | table | postgres
public | test2 | table | postgres
(3 rows)
删除表
mydb=# drop table test2;
DROP TABLE
mydb=# \dt;
List of relations
Schema | Name | Type | Owner
--------+------+-------+----------
public | aaa | table | postgres
public | test | table | postgres
(2 rows)
查看表结构
mydb=# \d test;
Table "public.test"
Column | Type | Collation | Nullable | Default
--------+---------------+-----------+----------+---------
id | integer | | |
name | character(10) | | |
age | integer | | |
创建模式
mydb=# \c postgres;
You are now connected to database "postgres" as user "postgres".
postgres=# create schema hr;
CREATE SCHEMA
查看默认模式
postgres=# show search_path;
search_path
-----------------
"$user", public
(1 row)
删除模式、查看所有模式
postgres=# drop schema hr;;
DROP SCHEMA
postgres=# drop schema hr cascade;
ERROR: schema "hr" does not exist
postgres=# create schema hr;
CREATE SCHEMA
postgres=# drop schema hr cascade;
DROP SCHEMA
postgres=# \dn;
List of schemas
Name | Owner
--------+-------------------
public | pg_database_owner
(1 row)
postgres=# select schema_name from information_schema.schemata;
schema_name
--------------------
information_schema
pg_catalog
pg_toast
public
(4 rows)
在指定模式中创建表、查看当前模式、查看当前所在shcema、查看搜索路径
postgres=# create schema hr;
CREATE SCHEMA
postgres=# create table hr.employees (id serial primary key,name text);
CREATE TABLE
postgres=# set search_path to hr;
SET
postgres=# set search_path to hr,public;
SET
postgres=# select current_schema();
current_schema
----------------
hr
(1 row)
postgres=# show search_path;
search_path
-------------
hr, public
(1 row)
PostgreSQL模式隔离性
postgres=# create database mydb; # 创建数据库test
ERROR: database "mydb" already exists
postgres=# \c mydb # 使用test库。
You are now connected to database "mydb" as user "postgres".
mydb=# create schema schema1; # 创建模式1.
CREATE SCHEMA
mydb=# create schema schema2; # 创建模式2.
CREATE SCHEMA
mydb=# create table shcema1.users (id int);
ERROR: schema "shcema1" does not exist
LINE 1: create table shcema1.users (id int);
^
mydb=# create table schema1.users (id int); # 在模式1创建users表
CREATE TABLE
mydb=# insert into schema1.users values(1); # 向模式1的users表插入数据1.
INSERT 0 1
mydb=# create table schema2.users (id int); # 在模式2创建users表
CREATE TABLE
mydb=# insert into schema2.users values(2); # 向模式2的users表插入数据2.
INSERT 0 1
mydb=# select * from schema1.users; # 显式指定模式名来查询模式1的users表数据。
id
----
1
(1 row)
mydb=# select * from schema2.users; # 显式指定模式名来查询模式2的users表数据。
id
----
2
(1 row)
mydb=# set search_path to schema1; # 设置搜索路径为模式1,查询时无需显式指定模式名。
SET
mydb=# select * from users;
id
----
1
(1 row)
mydb=# set search_path to schema2; # 设置搜索路径为模式2,查询时无需显式指定模式名。
SET
mydb=# select * from users;
id
----
2
(1 row)
数据操作相关
postgres=# create table test(id int,name char(10),age int);
CREATE TABLE
postgres=# insert into test values(1,'zhangsan',18);
INSERT 0 1
postgres=# select * from test;
id | name | age
----+------------+-----
1 | zhangsan | 18
(1 row)
postgres=# update test set age=20 where id=1;
UPDATE 1
postgres=# select * from test;
id | name | age
----+------------+-----
1 | zhangsan | 20
(1 row)
postgres=# delete from test where id=1;
DELETE 1
postgres=# select * from test;
id | name | age
----+------+-----
(0 rows)
备份相关
sql转储单个库及恢复
转储
postgres=# create database my_db;
CREATE DATABASE
postgres=# \c my_db
You are now connected to database "my_db" as user "postgres".
my_db=# create schema s1;
CREATE SCHEMA
my_db=# create schema s2;
CREATE SCHEMA
my_db=# create table s1.a(id int)
my_db-# ;
CREATE TABLE
my_db=# create table s2.a(id int);
CREATE TABLE
my_db=# insert into s1.a values(1);
INSERT 0 1
my_db=# insert into s2.a values(2);
INSERT 0 1
my_db=# select * from s1.a;
id
----
1
(1 row)
my_db=# select * from s2.a;
id
----
2
(1 row)
my_db=# exit;
[postgres@localhost ~]$ pg_dump my_db > aaa # 备份my_db库到aaa文件中
[postgres@localhost ~]$ ls
aaa logfile
[postgres@localhost ~]$ cat aaa # 查看备份信息
--
-- PostgreSQL database dump
--
-- Dumped from database version 15.4
-- Dumped by pg_dump version 15.4
SET statement_timeout = 0;
SET lock_timeout = 0;
...略
通过查看备份文件内的信息,发现这是该文件内容是由一些sql命令组合而成的。
恢复
postgres=# drop database my_db;
DROP DATABASE
[postgres@localhost ~]$ psql my_db < aaa
psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: FATAL: database "my_db" does not exist
postgres=# create database my_db;
CREATE DATABASE
postgres=# exit
[postgres@localhost ~]$ psql my_db < aaa
SET
SET
SET
SET
SET
set_config
------------
(1 row)
SET
SET
SET
SET
CREATE SCHEMA
ALTER SCHEMA
CREATE SCHEMA
ALTER SCHEMA
SET
SET
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
COPY 1
COPY 1
[postgres@localhost ~]$ psql
psql (15.4)
Type "help" for help.
postgres=# \c my_db
You are now connected to database "my_db" as user "postgres".
my_db=# \dt
Did not find any relations.
my_db=# select * from s1.a;
id
----
1
(1 row)
my_db=# select * from s2.a;
id
----
2
(1 row)
已经恢复过后,如果重复恢复会报错。报错信息如下:
[postgres@localhost ~]$ psql my_db < aaa
SET
SET
SET
SET
SET
set_config
------------
(1 row)
SET
SET
SET
SET
ERROR: schema "s1" already exists
ALTER SCHEMA
ERROR: schema "s2" already exists
ALTER SCHEMA
SET
SET
ERROR: relation "a" already exists
ALTER TABLE
ERROR: relation "a" already exists
ALTER TABLE
COPY 1
COPY 1
在默认情况下,psql的脚本即使遇到一个sql错误也会继续执行。如果想让遇到一个sql错误后直接退出该脚本,可以在恢复时手动设置参数ON_ERROR_STOP=on。
[postgres@localhost ~]$ psql --set ON_ERROR_STOP=on my_db < aaa
SET
SET
SET
SET
SET
set_config
------------
(1 row)
SET
SET
SET
SET
ERROR: schema "s1" already exists
转储一个数据库集簇的全部内容。
准备数据
postgres=# create database aaa;
CREATE DATABASE
postgres=# \c aaa
aaa=# create table q(id int);
CREATE TABLE
aaa=# create schema c1;
CREATE SCHEMA
aaa=# create schema c2;
aaa=# create table c1.q(id int);
CREATE TABLE
aaa=# create table c2.q(id int);
aaa=# insert into q values(1);
INSERT 0 1
aaa=# select * from q;
id
----
1
(1 row)
aaa=# insert into c1.q values(2);
INSERT 0 1
aaa=# insert into c2.q values(3);
INSERT 0 1
aaa=# select * from c1.q;
id
----
2
(1 row)
aaa=# select * from c2.q;
id
----
3
(1 row)
postgres=# select datname from pg_database;
datname
-----------
postgres
template1
template0
my_db
aaa
(5 rows)
备份
[postgres@localhost ~]$ pg_dumpall > bbb
[postgres@localhost ~]$ cat bbb
--
-- PostgreSQL database cluster dump
--
SET default_transaction_read_only = off;
...略
模拟误删除
postgres=# drop database my_db;
DROP DATABASE
postgres=# drop database aaa;
DROP DATABASE
postgres=# select datname from pg_database;
datname
-----------
postgres
template1
template0
(3 rows)
恢复
[postgres@localhost ~]$ psql -f bbb # 这里面有两个库,如果只想恢复一个,指定库名即可。
SET
SET
SET
psql:bbb:14: ERROR: role "postgres" already exists
ALTER ROLE
You are now connected to database "template1" as user "postgres".
SET
SET
SET
SET
SET
set_config
------------
(1 row)
SET
SET
SET
SET
SET
SET
SET
SET
SET
set_config
------------
(1 row)
SET
SET
SET
SET
CREATE DATABASE
ALTER DATABASE
You are now connected to database "aaa" as user "postgres".
SET
SET
SET
SET
SET
set_config
------------
(1 row)
SET
SET
SET
SET
CREATE SCHEMA
ALTER SCHEMA
CREATE SCHEMA
ALTER SCHEMA
SET
SET
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
COPY 1
COPY 1
COPY 1
SET
SET
SET
SET
SET
set_config
------------
(1 row)
SET
SET
SET
SET
CREATE DATABASE
ALTER DATABASE
You are now connected to database "my_db" as user "postgres".
SET
SET
SET
SET
SET
set_config
------------
(1 row)
SET
SET
SET
SET
CREATE SCHEMA
ALTER SCHEMA
CREATE SCHEMA
ALTER SCHEMA
SET
SET
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
COPY 2
COPY 2
You are now connected to database "postgres" as user "postgres".
SET
SET
SET
SET
SET
set_config
------------
(1 row)
SET
SET
SET
SET
验证
postgres=# select datname from pg_database;
datname
-----------
postgres
template1
template0
aaa
my_db
(5 rows)
postgres=# \c aaa
You are now connected to database "aaa" as user "postgres".
aaa=# select * from q;
id
----
1
(1 row)
aaa=# select * from c1.q;
id
----
2
(1 row)
aaa=# select * from c2.q;
id
----
3
(1 row)
aaa=# \c my_db;
You are now connected to database "my_db" as user "postgres".
my_db=# select * from s1.a;
id
----
1
1
(2 rows)
my_db=# select * from s2.a;
id
----
2
2
(2 rows)
远程连接相关
dnf安装的pgsql配置文件在
/var/lib/pgsql/data/postgresql.conf
源码编译安装的pgsql配置文件在
/usr/local/pgsql/data/postgresql.conf
postgresql的默认监听地址是127.0.0.1 想使用别的主机远程连接postgresql,需要修改配置文件。
再开一个终端页,用root身份来修改配置文件,修改之后换回原终端,用postgresql身份登录的终端来重启postgresql。
[root@localhost ~]# vim /usr/local/pgsql/data/postgresql.conf
listen_addresses = '*' # what IP address(es) to listen on;
[postgres@localhost ~]$ pg_ctl -D /usr/local/pgsql/data/ -l logfile restart
waiting for server to shut down.... done
server stopped
waiting for server to start.... done
server started
[postgres@localhost ~]$ ls
aaa bbb logfile
[postgres@localhost ~]$ netstat -anpt | grep postgre
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 0.0.0.0:5432 0.0.0.0:* LISTEN 12416/postgres
tcp6 0 0 :::5432 :::* LISTEN 12416/postgres
postgresql默认只能本地访问postgresql,需要修改pg_hba.conf。
[root@localhost ~]# vim /usr/local/pgsql/data/pg_hba.conf
# IPv4 local connections:
host all all 0.0.0.0/0 trust
host all all 127.0.0.1/32 trust
## 扩展:127.0.0.1/32表示广播、单播、可通信地址都是它。因为子网是32位,只有这一个ip地址。
如果将其更改为127.0.0.1/30 那可用ip为127.0.0.1 127.0.0.2 广播地址为127.0.0.3
ip 127.0.0. 000000 00
mask 255.255.255.111111 00
网络位 主机位
主机位二进制为00
只有三种排列方式
01 十进制 1
10 十进制 2
11 十进制 3
主机位全1是广播地址。
host:连接类型,适用于通过tcp/ip进行的远程连接。
all:定义那些数据库可接受这个规则。
all:定义了哪些用户可以接受这个规则。
0.0.0.0/0:特殊的CIDR(无类别域间路由)表示法,表示任何ip地址。
trust:认证方法。trust表示信任,无需任何认证即可访问数据库。
[postgres@localhost ~]$ pg_ctl -D /usr/local/pgsql/data/ -l logfile restart
waiting for server to shut down.... done
server stopped
waiting for server to start.... done
server started
客户端
[root@localhost ~]# psql -h 192.168.10.101
psql: 错误: 连接到"192.168.10.101"上的服务器,端口5432失败:No route to host
服务器是否在该主机上运行并接受TCP/IP连接?
# 出现此类错误说明,服务端防火墙未关闭或者服务端的服务未监听正确的地址/端口。
服务端
[root@localhost ~]# firewall-cmd --add-service=postgresql
success
客户端
[root@localhost ~]# psql -h 192.168.10.101
psql: 错误: 连接到"192.168.10.101"上的服务器,端口5432失败:FATAL: role "root" does not exist
#出现此错误,说明用户未切换到postgres。
[root@localhost ~]# useradd postgres
[root@localhost ~]# su - postgres
[postgres@localhost ~]$ psql -h 192.168.10.101
psql (15.12, 服务器 15.4)
输入 "help" 来获取帮助信息.
postgres=#
服务端
[root@localhost ~]# vim /usr/local/pgsql/data/pg_hba.conf
# IPv4 local connections:
host all all 0.0.0.0/0 md5
host all all 127.0.0.1/32 trust
postgres=# alter user postgres with password '123456';
ALTER ROLE
[postgres@localhost ~]$ pg_ctl -D /usr/local/pgsql/data/ -l logfile restart
waiting for server to shut down.... done
server stopped
waiting for server to start.... done
server started
客户端
[postgres@localhost ~]$ psql -h 192.168.10.101
用户 postgres 的口令:
psql (15.12, 服务器 15.4)
输入 "help" 来获取帮助信息.
postgres=#
忘记密码怎么办?修改pg_hba.conf文件,将本地的MD5更改为trust,重启服务。登录数据库修改密码,再将trust改为md5,重启服务。使用刚修改的密码登录即可。