PostgreSQL 数据库操作 #

数据库概述 #

在 PostgreSQL 中,数据库是表的容器,一个 PostgreSQL 服务器可以管理多个数据库。

text
┌─────────────────────────────────────────────────────────────┐
│                    PostgreSQL 架构                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   PostgreSQL 服务器                                         │
│   ├── postgres (系统数据库)                                 │
│   ├── template0 (原始模板)                                  │
│   ├── template1 (自定义模板)                                │
│   ├── mydb1 (用户数据库)                                    │
│   ├── mydb2 (用户数据库)                                    │
│   └── ...                                                   │
│                                                             │
│   每个数据库包含:                                           │
│   ├── 表 (Tables)                                          │
│   ├── 索引 (Indexes)                                       │
│   ├── 视图 (Views)                                         │
│   ├── 函数 (Functions)                                     │
│   ├── 序列 (Sequences)                                     │
│   └── 其他对象...                                           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

创建数据库 #

CREATE DATABASE 基本语法 #

sql
CREATE DATABASE database_name
    [ WITH ]
    [ OWNER = user_name ]
    [ TEMPLATE = template_name ]
    [ ENCODING = encoding_name ]
    [ LC_COLLATE = collate_name ]
    [ LC_CTYPE = ctype_name ]
    [ TABLESPACE = tablespace_name ]
    [ CONNECTION LIMIT = limit ];

基本创建 #

sql
-- 创建简单数据库
CREATE DATABASE myapp;

-- 创建带参数的数据库
CREATE DATABASE myapp
    WITH 
    OWNER = myuser
    ENCODING = 'UTF8'
    LC_COLLATE = 'en_US.UTF-8'
    LC_CTYPE = 'en_US.UTF-8'
    CONNECTION LIMIT = 100;

创建参数说明 #

text
┌─────────────────┬─────────────────────────────────────────────┐
│ 参数            │ 说明                                        │
├─────────────────┼─────────────────────────────────────────────┤
│ OWNER           │ 数据库所有者,默认当前用户                  │
│ TEMPLATE        │ 模板数据库,默认 template1                  │
│ ENCODING        │ 字符编码,如 UTF8, SQL_ASCII               │
│ LC_COLLATE      │ 字符串排序规则                              │
│ LC_CTYPE        │ 字符分类规则                                │
│ TABLESPACE      │ 表空间,默认 pg_default                     │
│ CONNECTION LIMIT│ 最大连接数,-1 表示无限制                   │
└─────────────────┴─────────────────────────────────────────────┘

使用模板创建 #

sql
-- PostgreSQL 有两个内置模板数据库
-- template0: 原始模板,不能修改
-- template1: 可自定义模板

-- 使用 template0 创建(纯净数据库)
CREATE DATABASE mydb TEMPLATE template0;

-- 使用 template1 创建(继承模板修改)
CREATE DATABASE mydb TEMPLATE template1;

-- 创建自定义模板
CREATE DATABASE my_template;
-- 在 my_template 中创建通用表、函数等
-- 然后用它作为模板
CREATE DATABASE new_project TEMPLATE my_template;

指定编码和区域 #

sql
-- 创建中文数据库
CREATE DATABASE mydb_cn
    ENCODING = 'UTF8'
    LC_COLLATE = 'zh_CN.UTF-8'
    LC_CTYPE = 'zh_CN.UTF-8';

-- 查看可用的编码
SELECT * FROM pg_encoding;

-- 查看可用的区域设置(Linux)
-- locale -a

查看数据库 #

使用 psql 命令 #

sql
-- 在 psql 中列出所有数据库
\l

-- 输出示例:
--                                                  List of databases
--    Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges
-- -----------+----------+----------+-------------+-------------+-----------------------
--  myapp     | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
--  postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
--  template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          + postgres=CTc/postgres
--  template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          + postgres=CTc/postgres

-- 查看详细列表
\l+

-- 查看特定数据库
\l myapp

使用 SQL 查询 #

sql
-- 查询所有数据库
SELECT 
    datname AS name,
    pg_catalog.pg_get_userbyid(datdba) AS owner,
    pg_encoding_to_char(encoding) AS encoding,
    datcollate AS collate,
    datctype AS ctype
FROM pg_database
WHERE datistemplate = false
ORDER BY datname;

-- 查看数据库大小
SELECT 
    datname,
    pg_size_pretty(pg_database_size(datname)) AS size
FROM pg_database
ORDER BY pg_database_size(datname) DESC;

-- 输出示例:
--   datname  |  size
-- -----------+---------
--  myapp     | 15 MB
--  postgres  | 8497 kB
--  template1 | 8497 kB
--  template0 | 8497 kB

查看当前数据库 #

sql
-- 查看当前连接的数据库
SELECT current_database();

-- 在 psql 中
\conninfo
-- 输出:You are connected to database "myapp" as user "postgres" on host "localhost" at port "5432".

选择数据库 #

psql 命令行连接 #

bash
# 连接指定数据库
psql -d myapp
psql -d myapp -U myuser -h localhost -p 5432

# 使用连接字符串
psql "postgresql://myuser:mypassword@localhost:5432/myapp"

psql 内部切换 #

sql
-- 在 psql 中切换数据库
\c myapp

-- 切换数据库和用户
\c myapp myuser

-- 切换数据库、用户和主机
\c myapp myuser localhost

修改数据库 #

ALTER DATABASE 语法 #

sql
ALTER DATABASE database_name 
    [ WITH ] [ option [ ... ] ];

-- 可用选项
ALTER DATABASE database_name RENAME TO new_name;
ALTER DATABASE database_name OWNER TO new_owner;
ALTER DATABASE database_name SET TABLESPACE new_tablespace;
ALTER DATABASE database_name SET configuration_parameter = value;
ALTER DATABASE database_name RESET configuration_parameter;

重命名数据库 #

sql
-- 重命名数据库(需要断开所有连接)
ALTER DATABASE myapp RENAME TO myapp_v2;

-- 如果有连接,需要先断开
-- 查看连接
SELECT pid, usename, application_name, client_addr 
FROM pg_stat_activity 
WHERE datname = 'myapp';

-- 断开所有连接
SELECT pg_terminate_backend(pid) 
FROM pg_stat_activity 
WHERE datname = 'myapp' AND pid <> pg_backend_pid();

修改所有者 #

sql
-- 修改数据库所有者
ALTER DATABASE myapp OWNER TO myuser;

设置数据库参数 #

sql
-- 设置数据库级别的参数
ALTER DATABASE myapp SET work_mem = '256MB';
ALTER DATABASE myapp SET log_statement = 'all';
ALTER DATABASE myapp SET timezone = 'Asia/Shanghai';

-- 重置参数
ALTER DATABASE myapp RESET work_mem;

-- 查看数据库参数
SELECT * FROM pg_db_role_setting;

删除数据库 #

DROP DATABASE 语法 #

sql
DROP DATABASE [ IF EXISTS ] database_name;

删除数据库 #

sql
-- 删除数据库
DROP DATABASE myapp;

-- 如果存在则删除
DROP DATABASE IF EXISTS myapp;

-- 注意:删除数据库会永久删除所有数据!

强制删除(断开连接) #

sql
-- 方法1:先断开连接再删除
SELECT pg_terminate_backend(pid) 
FROM pg_stat_activity 
WHERE datname = 'myapp' AND pid <> pg_backend_pid();

DROP DATABASE myapp;

-- 方法2:使用函数(需要创建)
CREATE OR REPLACE FUNCTION drop_database_force(dbname TEXT) 
RETURNS VOID AS $$
DECLARE
    pid INTEGER;
BEGIN
    FOR pid IN 
        SELECT pid FROM pg_stat_activity WHERE datname = dbname AND pid <> pg_backend_pid()
    LOOP
        EXECUTE 'SELECT pg_terminate_backend(' || pid || ')';
    END LOOP;
    EXECUTE 'DROP DATABASE ' || quote_ident(dbname);
END;
$$ LANGUAGE plpgsql;

-- 使用函数
SELECT drop_database_force('myapp');

数据库权限 #

授予数据库权限 #

sql
-- 授予连接权限
GRANT CONNECT ON DATABASE myapp TO myuser;

-- 授予创建 schema 权限
GRANT CREATE ON DATABASE myapp TO myuser;

-- 授予所有权限
GRANT ALL PRIVILEGES ON DATABASE myapp TO myuser;

-- 授予给角色
GRANT ALL PRIVILEGES ON DATABASE myapp TO myrole;

撤销权限 #

sql
-- 撤销连接权限
REVOKE CONNECT ON DATABASE myapp FROM myuser;

-- 撤销所有权限
REVOKE ALL PRIVILEGES ON DATABASE myapp FROM myuser;

查看权限 #

sql
-- 查看数据库权限
SELECT 
    datname,
    datacl
FROM pg_database
WHERE datname = 'myapp';

-- 解析权限
-- r = SELECT, w = UPDATE, d = DELETE, D = TRUNCATE
-- C = CREATE, c = CONNECT, T = TEMPORARY

数据库配置文件 #

postgresql.conf #

ini
# 主要配置参数

# 连接设置
listen_addresses = '*'        # 监听地址
port = 5432                   # 端口
max_connections = 100         # 最大连接数

# 内存设置
shared_buffers = 256MB        # 共享缓冲区
work_mem = 4MB                # 工作内存
maintenance_work_mem = 64MB   # 维护内存

# 日志设置
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d.log'
log_statement = 'ddl'         # none, ddl, mod, all

# 时区
timezone = 'Asia/Shanghai'

pg_hba.conf #

ini
# 客户端认证配置

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# 本地连接
local   all             all                                     trust

# IPv4 连接
host    all             all             127.0.0.1/32            scram-sha-256
host    all             all             192.168.1.0/24          scram-sha-256

# IPv6 连接
host    all             all             ::1/128                 scram-sha-256

# 复制连接
host    replication     replicator      192.168.1.100/32        scram-sha-256

重载配置 #

sql
-- 在 psql 中重载配置
SELECT pg_reload_conf();

-- 或使用命令行
-- pg_ctl reload

数据库维护 #

VACUUM 操作 #

sql
-- 清理死元组,更新统计信息
VACUUM mytable;

-- 完整清理(会锁表)
VACUUM FULL mytable;

-- 分析表(更新统计信息)
ANALYZE mytable;

-- 清理并分析
VACUUM ANALYZE mytable;

-- 查看表的膨胀情况
SELECT 
    schemaname,
    tablename,
    n_live_tup,
    n_dead_tup,
    n_dead_tup::float / NULLIF(n_live_tup, 0) AS dead_ratio
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC;

数据库备份 #

bash
# 使用 pg_dump 备份单个数据库
pg_dump -U postgres myapp > myapp_backup.sql

# 备份为压缩格式
pg_dump -U postgres -Fc myapp > myapp_backup.dump

# 备份所有数据库
pg_dumpall -U postgres > all_backup.sql

# 使用 pg_restore 恢复
pg_restore -U postgres -d myapp myapp_backup.dump

最佳实践 #

数据库命名规范 #

sql
-- 推荐
CREATE DATABASE my_app;        -- 小写,下划线分隔
CREATE DATABASE ecommerce;     -- 简洁明了
CREATE DATABASE app_dev;       -- 环境标识
CREATE DATABASE app_test;
CREATE DATABASE app_prod;

-- 不推荐
CREATE DATABASE My_App;        -- 大小写混合
CREATE DATABASE my-app;        -- 使用连字符
CREATE DATABASE 1app;          -- 数字开头

数据库设计原则 #

text
┌─────────────────────────────────────────────────────────────┐
│                    数据库设计原则                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 单一职责                                                │
│     一个数据库服务于一个应用或业务领域                      │
│                                                             │
│  2. 命名清晰                                                │
│     数据库名称应反映其用途                                  │
│                                                             │
│  3. 权限最小化                                              │
│     应用程序使用最小必要权限                                │
│                                                             │
│  4. 定期备份                                                │
│     制定备份策略,定期测试恢复                              │
│                                                             │
│  5. 监控维护                                                │
│     监控数据库大小、连接数、性能                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

学习路径 #

text
基础阶段
├── 数据库操作(本文)
├── 表操作
├── 数据CRUD
└── 基础查询

下一步 #

掌握了数据库操作后,接下来学习 表操作,了解如何创建和管理表!

最后更新:2026-03-29