PostgreSQL 模式(SCHEMA)

PostgreSQL 模式(Schema)完全指南

Schema 是 PostgreSQL 中 数据库内的命名空间,用于 组织表、视图、函数、索引 等对象,避免命名冲突,提升权限管理与安全性。


一、什么是 Schema?

概念说明
数据库(Database)最高层级,隔离连接
模式(Schema)数据库内的子命名空间
表(Table)属于某个 Schema
数据库 myapp
├── Schema: public          ← 默认
│   ├── users
│   └── orders
├── Schema: analytics       ← 自定义
│   └── user_stats
└── Schema: audit           ← 审计
    └── login_logs

二、为什么使用 Schema?

优势说明
命名隔离不同团队用同名表(如 users
权限控制给不同角色分配不同 Schema
逻辑分组按模块划分(crm, billing, logs
多租户支持每个租户一个 Schema
安全隔离隐藏敏感表

三、创建 Schema

1. SQL 命令(推荐)

CREATE SCHEMA analytics;
CREATE SCHEMA IF NOT EXISTS billing;

2. 指定所有者

CREATE SCHEMA crm AUTHORIZATION crm_user;

3. psql 命令行

CREATE SCHEMA reporting;

四、在 Schema 中创建表

-- 方法 1:显式指定
CREATE TABLE analytics.daily_active_users (
    date DATE PRIMARY KEY,
    cnt INTEGER
);

-- 方法 2:设置搜索路径(推荐)
SET search_path TO analytics, public;

-- 之后直接写表名
CREATE TABLE monthly_revenue (
    month DATE,
    revenue NUMERIC(12,2)
);

五、搜索路径(search_path)—— 关键!

-- 查看当前搜索路径
SHOW search_path;
-- 输出: "$user", public

-- 设置搜索路径
SET search_path TO billing, public;

-- 现在 CREATE TABLE users ... 会创建在 billing.users

最佳实践:每个应用连接时设置 search_path,避免混淆。


六、查询 Schema 中的对象

-- 列出所有 Schema
\dn

-- 列出某个 Schema 的表
\dt analytics.*

-- SQL 查询
SELECT schemaname, tablename 
FROM pg_tables 
WHERE schemaname = 'analytics';

七、跨 Schema 查询

-- 显式指定
SELECT * FROM analytics.users;

-- 别名
SELECT a.id, b.name 
FROM crm.customers a
JOIN billing.invoices b ON a.id = b.customer_id;

八、权限管理(Schema 级)

-- 创建角色
CREATE ROLE analyst LOGIN PASSWORD 'pass123';

-- 授予 Schema 使用权
GRANT USAGE ON SCHEMA analytics TO analyst;

-- 授予表权限
GRANT SELECT ON ALL TABLES IN SCHEMA analytics TO analyst;

-- 未来表自动授权
ALTER DEFAULT PRIVILEGES IN SCHEMA analytics 
GRANT SELECT ON TABLES TO analyst;

九、多租户架构示例

-- 为每个租户创建 Schema
CREATE SCHEMA tenant_1001 AUTHORIZATION tenant_1001_user;
CREATE SCHEMA tenant_1002 AUTHORIZATION tenant_1002_user;

-- 每个租户有相同表结构
CREATE TABLE tenant_1001.users ( ... );
CREATE TABLE tenant_1002.users ( ... );

-- 应用连接时动态设置
SET search_path TO tenant_1001, public;

十、移动表到其他 Schema

ALTER TABLE public.temp_data SET SCHEMA analytics;

十一、删除 Schema

-- 删除空 Schema
DROP SCHEMA analytics;

-- 删除含对象的 Schema(级联)
DROP SCHEMA analytics CASCADE;

-- 安全删除
DROP SCHEMA IF EXISTS old_schema CASCADE;

十二、pgAdmin 图形化操作

  1. 右键 SchemasCreateSchema
  2. 填写名称 → Save
  3. 右键新 Schema → CreateTable 建表
  4. 拖拽表 → 移动到其他 Schema

十三、一键创建多模块 Schema 脚本

-- init_schemas.sql
-- 运行:psql -U postgres -d myapp -f init_schemas.sql

-- 创建 Schema
CREATE SCHEMA IF NOT EXISTS crm AUTHORIZATION crm_user;
CREATE SCHEMA IF NOT EXISTS billing AUTHORIZATION billing_user;
CREATE SCHEMA IF NOT EXISTS analytics;
CREATE SCHEMA IF NOT EXISTS audit;

-- 设置默认搜索路径
ALTER DATABASE myapp SET search_path TO public;

-- 示例表
SET search_path TO crm;
CREATE TABLE customers (
    id BIGSERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    created_at TIMESTAMPTZ DEFAULT now()
);

SET search_path TO billing;
CREATE TABLE invoices (
    id BIGSERIAL PRIMARY KEY,
    customer_id BIGINT,
    amount NUMERIC(12,2),
    issued_at DATE
);

十四、常见错误与解决

错误原因解决
schema "analytics" does not existSchema 未创建CREATE SCHEMA analytics;
permission denied for schema analytics无 USAGE 权限GRANT USAGE ON SCHEMA ...
relation "users" does not exist搜索路径不对SET search_path 或用 schema.table
cannot drop schema because other objects depend on it有表CASCADE

十五、最佳实践 Checklist

项目建议
命名小写 + 下划线,如 crm, billing_v2
默认 Schema保留 public 给扩展
搜索路径连接时 SET search_path
权限GRANT USAGE ON SCHEMA + GRANT ON TABLES
清理定期 DROP SCHEMA old_... CASCADE
多租户tenant_{id} + 动态 search_path

十六、快速上手:3 分钟创建并使用 Schema

-- 1. 创建 Schema
CREATE SCHEMA shop;

-- 2. 设置搜索路径
SET search_path TO shop, public;

-- 3. 建表
CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    name TEXT
);

-- 4. 插入数据
INSERT INTO products (name) VALUES ('Phone');

-- 5. 查询
SELECT * FROM products;  -- 自动找 shop.products

小结:Schema 使用 5 步法

1. CREATE SCHEMA name;
2. GRANT USAGE ON SCHEMA name TO role;
3. SET search_path TO name, public;
4. CREATE TABLE ... (自动归属)
5. 查询时用 schema.table 或依赖 search_path

现在就动手
创建一个 blog Schema,建 postscomments 表,设置搜索路径,然后插入一条数据。


需要我生成:

  • 多租户动态切换 Schema 的 Python 代码?回复 Python 多租户
  • 自动创建 12 个月分区 Schema 脚本?回复 分区 Schema
  • pgAdmin 批量管理 Schema?回复 pgAdmin Schema

随时告诉我!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注