安装
下载地址:www.enterprisedb.com/downloads/p...
- 傻瓜式安装
- 配置环境变量(PG_HOME:D:\Program Files\PostgreSQL\17)、(%PG_HOME%\bin;) -- 命令行无用
- windows 服务里面启动(配置的手动启动)

提供工具: server、pgAdmin(可视化管理工具)、stack builder(安装包或者 tools)、命令行
连接
- navicate 连接失败 [authentication method 10 not supposed]
原因: 客户端不支持认证方式,需要更改 scram-sha-256 为 md5 -- 未实践 - pgAdmin 同时被安装,打开pgAdmin进行图形化管理
操作
- 创建数据库
sql
-- tablespace 决定了数据文件最终放到哪个磁盘里面
CREATE DATABASE localdb
WITH OWNER = postgres ENCODING = 'UTF8'
-- 'libc'代表操作系统标准 C 库(glibc 等)提供的 locale 支持、'icu'提供更高级别的国际化支持,主要影响排序、字符比较等操作
LOCALE_PROVIDER = 'libc'
-- 最大并发连接数
CONNECTION LIMIT = -1
-- 是否可以作为模板被其他数据库复制(表、函数、扩展等基础结构)
IS_TEMPLATE = False;
- 创建表
- 路径:Schemas > public > Tables > Create > Table。
- columns数据类型
基本数据类型 | 1. 字符串 2. 数值类型(demical = numeric, 可指定精度)(real=float4、double precision = float8)(serial = 自增整数) 3. 时间日期(date、timetz 带时区、timestamptz 带时区、interval 时间跨度) 4. enum 类型需要 create type 命令创建 |
---|---|
复合类型 | 1. composite 2. sql: create type xx as ( name type,name type ) 3. 使用 row('nameval', ' nameval' )组建组合类型 4. 创建表的时候,会创建同名的 type 5. 查询复合类型的列名: select (name).r from xx |
数组类型 | [ ] or array 关键字 数组构造: {x,x,x} or array[x,x,x,] |
网络地址 | cidr(网络地址)、inet(主机地址,可选子网掩码)、 macaddr(mac 地址) |
范围类型 | www.modb.pro/db/17350918... 内置了基础类型的范围类型(如numrange、daterange等),举例:[2025-07-01, 2025-07-10) |
JSON 类型 | json、jsonb(二进制格式) |
HStore 类型 | 存储"键-值"字符串字典。 'name=>"John", age=>"30"'::hstore 支持 GiST (平衡搜索树)或 GIN (倒排索引)索引 |
几何类型 | point、line(无限线)、lseg(线段)、box(长方体盒子)、path(几何路径)、polygon(闭合几何路径)、circle |
自定义类型 |
- 主键自增使用 serial 类型:nextval('t_user_id_req'::regclass)。
- 't_user_id_req'是内建的序列,
- regclass 代表其是内部对象,做显式转换
- nextval 是序列递增器
- 非分布式、非分库分表推荐主键自增:
sql
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
- 字段顺序不能直接调整,新字段只能追加到末尾
- 需要重新建表+迁移数据
- 创建视图等调整展示顺序
- 索引
- B+索引、联合索引同 mysql
- 表达式/函数索引 on t_xxx(lower(xxx))
- 全文索引 on t_xxx using gin(xxx)
- 范围索引 on gist(xxx)
- 数组索引 on gin(tags)
- options
- 对部分数据索引: where
- 不阻塞写 CONCURRENTLY
- 触发器
- rule 仅用于兼容旧代码,使用触发器进行替代
- 推荐场景
- 复杂日志审计
- 分区表路由
查询
- Query Tool 打开编辑器, F5 运行,F6 提交数据
- PSQL Tool 命令行工具
- /d+ tablename。展示完整表信息。
- -/i 文件路径。执行外部 sql 文件。
RLS 策略:Row-Level Security Policy
对特定的行拥有指定的操作权限
sql
-- 新建用户,并grant权限
CREATE USER guest WITH PASSWORD 'guest';
GRANT CONNECT ON DATABASE localdb TO guest;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO guest;
sql
-- 创建policy
ALTER TABLE tablename ENABLE ROW LEVEL SECURITY;
CREATE POLICY alice_policy ON tableaname FOR SELECT TO username USING (condition) ; //condition可填(columnname = current_user)等
-- 检查是否生效
SELECT relname, relrowsecurity, relforcerowsecurity FROM pg_class WHERE relname = 'tablename'; // relrowsecurity = true代表生效
SELECT * FROM pg_policies WHERE tablename = 'tablename'; //策略列表
FDW : 外部数据集成
新建csv文件
csv
id,name,age,money
10,c1,20,1000
20,c2,30,10000
sql
CREATE EXTENSION file_fdw; --file_fdw内置,启用即可
CREATE SERVER file_server FOREIGN DATA WRAPPER file_fdw;
CREATE FOREIGN TABLE fore_user (
id INT,
name TEXT,
age int,
amount NUMERIC
) SERVER file_server
OPTIONS (
filename 'D:\Program Files\PostgreSQL\17\upload_data\upload.csv',
format 'csv',
header 'true'
);
select * from fore_user;



publication 和 subscription 实现逻辑复制
数据库迁移完整流程:www.bookstack.cn/read/pigsty...
粒度:行过滤、列过滤、基于操作(insert、update、delete)
核心:WAL 流传输,pgoutput 解码,执行
WAL:write-ahead-log,记录所有数据操作的日志
- 创建新库
sql
// 以localdb为模板建立新库,需要拿到排它锁。
CREATE DATABASE test WITH OWNER = postgres TEMPLATE = localdb ENCODING = 'UTF8' STRATEGY = 'file_copy' LOCALE_PROVIDER = 'libc' TABLESPACE = pg_default
CONNECTION LIMIT = -1 IS_TEMPLATE = False;
// 使用pg_dump /pg_restore, 不会锁模板库
- 设置 "wal_level" >= "logical"
- postgresql.conf 文件中配置wal_level = logical,然后重启实例
- 使用 SQL 命令修改
sql
// 两个语句不能再同一个事务里面执行,执行成功后需要重启实例
ALTER SYSTEM SET wal_level = logical;
SELECT pg_reload_conf();
- 发布端
sql
-- 创建sql
CREATE PUBLICATION age_update_pub FOR TABLE public.t_user WITH (publish = 'update');
SELECT pg_create_logical_replication_slot('age_slot', 'pgoutput');
-- 校验sql
SELECT * FROM pg_publication WHERE pubname = 'age_update_pub';
SELECT * FROM pg_publication_tables WHERE pubname = 'age_update_pub';
- 订阅端
sql
-- 创建sql
CREATE SUBSCRIPTION age_sub
CONNECTION 'host=localhost port=5432 dbname=localdb user=postgres password=xxxx'
PUBLICATION age_update_pub
WITH (
copy_data = true, -- 是否拷贝现有数据
create_slot = false, -- 自动创建复制槽
enabled = true, -- 立即启用
slot_name = 'age_slot' -- 复制槽名称(可选)
);
-- 校验 sql
SELECT s.srsubstate,s.srsublsn,c.relname
FROM pg_subscription_rel s
JOIN pg_class c ON s.srrelid = c.oid
ORDER BY c.relname;
- 如果同步失败,查看 postgres 日志
- pgadmin 查看日志:dashbord -> Logs

error
error1: could not drop replication slot "age_subsription" on publisher: ERROR: replication slot "age_subsription" does not exist
- 尝试删除不存在的 slot 错误
sql
DROP SUBSCRIPTION age_subscription NODROP SLOT; // 失败,"NODROP" 不被支持。pgsql version 17
sql
// 删除成功
-- 1. 如果订阅处于启用状态,先禁用
ALTER SUBSCRIPTION age_subscription DISABLE;
-- 2. 解除与复制槽的绑定
ALTER SUBSCRIPTION age_subscription SET (slot_name = NONE);
-- 3. 现在可以安全删除订阅本身
DROP SUBSCRIPTION age_subscription;
error2 : cannot update table "t_user" Column list used by the publication does not cover the replica identity.
解决: update or delete 操作需要把 identity 列加入到发布列表中