PostgreSQL
安装
Ubuntu
sudo apt install postgresql postgresql-client
CentOS
wget https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
yum install -y ./pgdg-redhat-repo-latest.noarch.rpm
yum install -y postgresql12-server # or postgresql-server
docker
version: "3.1"
services:
db_postgres:
image: postgres:12
container_name: postgresql-server
environment:
- "POSTGRES_PASSWORD=gang2019"
# POSTGRES_PASSWORD_FILE=/run/secrets/postgres-passwd
volumes:
- pgdata:/var/lib/postgresql/data
- pginit:/docker-entrypoint-initdb.d # contains init-user-db.sh
ports:
- 5432:5432
volumes:
pgdata:
driver: local
pginit:
driver: local
可以和
adminer
部署在同一集群,从而方便数据库管理。
配置
远程访问
设置访问地址和端口(默认监听localhost
):
# edit: /var/lib/pgsql/12/data/postgresql.conf
listen_addresses = '*' # listen to all address
port = 5432
网络访问规则
用户访问时规则从上到下匹配,匹配到规则后按相应规则校验是否能访问数据库,不再使用后续规则。因此,匹配范围大的规则通常放在靠后位置。
# edit: /var/lib/pgsql/12/data/pg_hba.conf
# IPv4 local connections:
# TYPE DATABASE USER ADDRESS METHOD
host all gary 0.0.0.0/0 md5 #*
host all all 127.0.0.1/32 ident
*
:密码认证方法,可使用md5
或scram-sha-256
(推荐)。对于已有用户切换密码验证方法,参考:PostgreSQL中使用scram-sha-256认证 - 墨天轮 (modb.pro)。
设置防火墙规则:
sudo firewall-cmd --add-service=postgresql --permanent
数据存储位置
新的数据存储位置的所有者需要是数据库服务进程的用户(postgres
),同时访问权限应该为700/750
(即不能包含others访问权限)。如果已经经过初始化,则需要将原数据存储目录下的内容复制到新目录下(cp -ra
)。
启动服务
==初始化数据库==(CentOS):
sudo /usr/pgsql-12/bin/postgresql-12-setup initdb # or postgresql-setup initdb
启动数据库:
sudo service postgresql start # => WSL2
sudo systemctl enable --now postgresql-12
服务的日志数据位于:/var/lib/pgsql/data/log/
。
命令行工具
访问数据库
安装完毕后,会在系统中创建一个超级用户postgres
(密码为空)。使用该用户管理据库。
sudo -i -u postgres
psql \
-h,--host=PGHOST \ # 服务器地址或UNIX套接字地址:/var/run/postgresql*
-p,--port=PGPORT \ # 端口:5432
-U,--username=NAME \ # 用户名:postgres,使用相应地系统账号登录
-w,--no-password \ # 不提供密码
-W,--password \ # 输入密码提示
[dbname] # 默认:与用户名同名的数据库
*
:如果未指定主机IP地址,则默认连接本地套接字地址。
查看数据库服务版本:
SELECT version();
使用\q
退出数据库终端。
Peer authentication and password authentication.
本地账号默认使用peer
方式登录,即使用当前系统用户的身份凭据作为数据库的身份凭据。如果要在当前系统用户登录其他账户,应该采用密码认证模式,将认证方式从peer
改为md5
。针对默认账户postgres
,首先使用peer
模式登录系统后为其设置密码\password postgres
。
# edit: /etc/postgresql/12/main/pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD
local all postgres md5
local
代表UNIX域套接字。
导入导出数据
pg_dump -h src_host -U src_user src_db > table-to-copy.sql
-f,--filename=FILENAME # 代替重定向命令输出
-a,--data-only # 仅导出数据(不包含模式)
-s,--schema-only # 仅导出表结构定义
-C,--create # 包含创建数据库的命令
-n,--schema=SCHEMA # 只导出指定名称的模式
-N,--exclude-schema=SCHEMA # 不导出指定名称的模式
-t,--table=TABLE # 仅导出指定名称的表
psql -h dst_host -U dst_user -d dst_db -f table-to-copy.sql
可多次使用
-t
选项一次性导出多个表。
用户管理
命令行模式:
createuser -h localhost USERNAME -P # 最后需要输入postgres的密码*
*
:如果使用密码登录,则需在数据库访问规则中添加密码访问规则(md5
)。
显示用户信息:
\du -- lists all user
授权
使用管理员账户登录为用户授权。
授权数据库访问权限:
GRANT CREATE ON DATABASE database_name TO [GROUP] role_name;
权限声明包括:CREATE,CONNECT,TEMPORARY,TEMP
或全部权限ALL [PRIVILEGES]
。
授权表的访问权限:
\c DB_NAME # use ngsoc
GRANT SELECT ON TABLE table_name TO [GROUP] role_name;
GRANT ... ON ALL TABLES IN SCHEMA schema_name TO [GROUP] role_name;
权限声明包括一个或多个:SELECT,INSERT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER
或使用ALL
表示所有权限。
PostgreSQL: Documentation: 9.0: GRANT
执行SQL脚本
psql obejctrocket [options] -d db_name -f test.sql
在交互式环境下执行SQL脚本:
\c db_name
\i /path/TO/file_name.sql
数据库管理命令
Database管理
\l -- list databases
\c db_name -- use database
select * from pg_catalog.pg_collation; -- show collation
Basically, information schema is a set of views of pg_catalog.
PostgreSQL supports the standard SQL types int
, smallint
, real
, double precision,
char(N)
, varchar(N)
, date
, time
, timestamp
, and interval
, as well as other types of general utility and a rich set of geometric types. PostgreSQL can be customized with an arbitrary number of user-defined data types.
Constants that are not simple numeric values usually must be surrounded by single quotes (').
创建database
使用SQL语句创建数据库。或使用数据库命令行工具,创建:
createdb mydb # <-> CREATE DATABASE mydb
删除database
dropdb mydb # DROP DATABASE mydb
Schema管理
获取命名空间信息
命名空间(schema)是一个数据库所包含数据表的逻辑分组。
SELECT catalog_name,schema_name,schema_owner
FROM information_schema.schemata;
SELECT nspname,nsponwer,nspacl FROM pg_catalog.pg_namespace;
schema_name
和nspname
是一一对应的。
创建Schema
CREATE SCHEMA [IF NOT EXISTS] schema_name [AUTHORIZATION user_name]
[schema_element [...]];
DROP SCHEMA schema_name;
schema_name
:defaults to user_name
.
user_name
:the new schema's owner, defaults to the current user.
schema_element
:Schema中需要创建的内容(包括TABLE, VIEW, INDEX, GRANT
等),也可在创建Schema之后创建内容。
切换Schema
set search_path to schema_name;
Table管理
获取数据表
pgsql
命令:
\d[+] -- show tables [and schema]
-- Schema | Name | Type | Owner
-- -------+----------------+-------------------+----------
-- public | pokemon | partitioned table | postgres
-- public | pokemon_gen_01 | table | postgres
\dn -- show user created schema
SQL语句:
SELECT schemaname,tablename,tableowner,*
FROM pg_catalog.pg_tables
WHERE schemaname != 'pg_catalog'
AND schemaname != 'information_schema';
SELECT table_schema,table_name
FROM information_schema.tables
WHERE table_schema = 'public';
获取数据表详细信息
pgsql
命令:
\d[+] table_name -- -> DESC table: '+'显示更多列和分区定义
SQL语句:
SELECT column_name,data_type
FROM information_schema.columns
WHERE table_schema = 'table_name';
创建数据表
If a schema name is given (for example, CREATE TABLE myschema.mytable ...
) then the table is created in the specified schema. Otherwise it is created in the current schema. Temporary tables exist in a special schema, so a schema name cannot be given when creating a temporary table. The name of the table must be distinct from the name of any other table, sequence, index, view, or foreign table in the same schema.
复制数据表
跨数据库复制数据表
不支持直接跨数据库复制表格,需要首先将数据从一个数据库导出,再导入另一个数据库。
修改表格
ALTER TABLE [IF EXISTS] name RENAME TO new_name
ALTER TABLE [IF EXISTS] name SET SCHEMA new_schema
ALTER TABLE [IF EXISTS] name RENAME [COLUMN] column_name TO new_column_name
数据表分区
The partitioned table itself is a “virtual” table having no storage of its own. Instead, the storage belongs to partitions, which are otherwise-ordinary tables associated with the partitioned table. Each partition stores a subset of the data as defined by its partition bounds. All rows inserted into a partitioned table will be routed to the appropriate one of the partitions based on the values of the partition key column(s). Updating the partition key of a row will cause it to be moved into a different partition if it no longer satisfies the partition bounds of its original partition.
分区引用的列使用PARTITION BY
声明。
CREATE TABLE table_name (column1 data_type, column2 data_type, …)
PARTITION BY RANGE(col_name1,...);
CREATE TABLE table_part_xx PARTITION OF table_name
FOR VALUES FROM ('2006-02-01') TO ('2006-03-01');
每个分区被存储为一个目录。
INSERT INTO TABLE table_name
PARTITION (partition1='partition1_val', partition2='partition2_val', ...)
VALUES (col1_val, col2_val, …, partition1_val, partition2_val, …);
必须在创建时定义分区,创建分区表后,仅能添加或移除分区。
ALTER TABLE [ IF EXISTS ] name
ATTACH PARTITION partition_name { FOR VALUES partition_bound_spec | DEFAULT }
ALTER TABLE [IF EXISTS] name DETACH PARTITION partition_name
不支持分区和分解和合并,可以将相关分区先移出父表,再修改分区定义,并将移出的子表格数据写回父表。
数据类型
PostgreSQL 数据类型 | 菜鸟教程 (runoob.com)
继承
CREATE TABLE cities (
name text,
population real,
elevation int -- (in ft)
);
CREATE TABLE capitals (
state char(2) UNIQUE NOT NULL
) INHERITS (cities); -- 继承表的定义并进行扩展
ONLY