4. 数据库环境搭建:PostgreSQL/MySQL安装、数据库初始化、用户与权限配置
数据库是服务目录平台的持久化核心,所有模板元数据、安全策略、用户信息与审计日志均依赖数据库的稳定运行。本章将指导你完成两种主流关系型数据库(PostgreSQL 与 MySQL)的安装、初始化脚本编写以及细粒度权限配置,确保平台在开发与生产环境中具备一致的数据底座。
4.1 数据库选型对比
服务目录平台对数据库的核心需求包括:JSON/JSONB 支持(存储模板结构)、行级安全策略(RLS/权限过滤)、事务完整性以及高并发下的查询性能。下表从关键维度对比 PostgreSQL 与 MySQL 的适用场景:
| 对比维度 | PostgreSQL | MySQL |
|---|---|---|
| JSON 支持 | 原生 JSONB,支持索引与内部查询 | JSON 类型,功能较基础 |
| 行级安全 | 内置 RLS,按用户/角色过滤行 | 需通过视图或应用层实现 |
| 并发控制 | MVCC 成熟,写并发性能优秀 | MVCC 实现,高并发下锁竞争较多 |
| 扩展性 | 支持分区表、并行查询、FDW | 分区表支持较晚,扩展能力稍弱 |
| 推荐场景 | 复杂模板、多租户、安全敏感 | 轻量部署、已有 MySQL 生态 |
选型建议: 服务目录平台推荐优先使用 PostgreSQL,其 JSONB 与行级安全特性可直接映射到模板版本管理与租户隔离需求。若团队运维以 MySQL 为主,也可通过应用层补偿权限逻辑。
4.2 PostgreSQL 安装与初始化
4.2.1 安装步骤(Ubuntu 22.04 示例)
# 更新包索引
sudo apt update
# 安装 PostgreSQL 16
sudo apt install postgresql-16 postgresql-client-16 -y
# 检查服务状态
sudo systemctl status postgresql
# 设置开机自启
sudo systemctl enable postgresql
4.2.2 数据库初始化脚本
安装完成后,使用 initdb 初始化数据目录(通常自动完成),然后创建服务目录平台专用的数据库与角色:
# 切换到 postgres 系统用户
sudo -i -u postgres
# 创建平台专用角色(非超级用户)
createuser --interactive --pwprompt catalog_admin
# 按提示输入密码,并选择 "n" 禁止创建数据库权限
# 创建数据库,指定所有者
createdb -O catalog_admin service_catalog_db
# 退出 postgres 用户
exit
4.2.3 验证连接
psql -h localhost -U catalog_admin -d service_catalog_db -W
关键配置: 编辑
/etc/postgresql/16/main/pg_hba.conf,将本地连接方式从 peer 改为 md5,以支持密码认证。修改后执行 sudo systemctl restart postgresql。
4.3 MySQL 安装与初始化
4.3.1 安装步骤(Ubuntu 22.04 示例)
# 安装 MySQL 8.0
sudo apt install mysql-server-8.0 -y
# 检查服务状态
sudo systemctl status mysql
# 运行安全安装向导
sudo mysql_secure_installation
4.3.2 数据库与用户创建
# 以 root 登录 MySQL
sudo mysql -u root
-- 创建数据库,指定字符集
CREATE DATABASE service_catalog_db
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
-- 创建应用用户,限制主机为 localhost
CREATE USER 'catalog_admin'@'localhost'
IDENTIFIED BY 'YourStrongPassword!';
-- 授予数据库全部权限
GRANT ALL PRIVILEGES ON service_catalog_db.*
TO 'catalog_admin'@'localhost';
-- 刷新权限
FLUSH PRIVILEGES;
-- 退出
EXIT;
安全注意: 生产环境禁止使用 root 用户连接应用。务必为服务目录平台创建专用数据库用户,并遵循最小权限原则——仅授予当前数据库的 SELECT、INSERT、UPDATE、DELETE 权限,不授予 SUPER、FILE 等管理权限。
4.4 用户与权限精细配置
服务目录平台通常采用多租户架构,不同团队或项目组只能访问自己的模板与配置。以下以 PostgreSQL 为例,演示如何通过角色继承与行级安全实现租户隔离。
4.4.1 角色层级设计
| 角色名称 | 层级 | 权限范围 |
|---|---|---|
catalog_admin |
数据库所有者 | DDL 操作、创建/修改表结构、管理其他角色 |
catalog_app |
应用连接角色 | DML 操作(SELECT/INSERT/UPDATE/DELETE),无 DDL |
tenant_reader_<id> |
租户只读角色 | 仅查询本租户数据,通过 RLS 策略限制 |
4.4.2 行级安全策略(RLS)配置
-- 以 catalog_admin 登录
psql -U catalog_admin -d service_catalog_db
-- 在模板表上启用 RLS
ALTER TABLE templates ENABLE ROW LEVEL SECURITY;
-- 创建基于租户 ID 的策略
CREATE POLICY tenant_isolation ON templates
FOR ALL
USING (tenant_id = current_setting('app.tenant_id')::UUID);
-- 创建只读角色并授权
CREATE ROLE tenant_reader_001;
GRANT SELECT ON templates TO tenant_reader_001;
-- 设置租户上下文(应用层在连接时执行)
SET app.tenant_id = '550e8400-e29b-41d4-a716-446655440000';
实现要点: 应用层在建立数据库连接后,需立即执行
SET app.tenant_id = '...' 语句。PostgreSQL 的 RLS 会自动根据该会话变量过滤行数据,无需在 SQL 查询中手动添加 WHERE 条件。
4.5 数据库初始化流程总览
下图展示了从安装到权限配置的完整链路,帮助你在实际操作中按序执行:
4.6 常见问题与避坑指南
- 认证失败: PostgreSQL 修改
pg_hba.conf后未重启服务;MySQL 未执行FLUSH PRIVILEGES。 - 权限过大: 直接使用 root 或超级用户连接应用,违反最小权限原则,存在安全风险。
- 字符集不一致: 数据库默认字符集与模板内容不匹配,导致中文或特殊字符存储异常。建议统一使用
UTF8(PostgreSQL)或utf8mb4(MySQL)。 - RLS 策略未生效: 忘记在表上执行
ENABLE ROW LEVEL SECURITY,或应用层未设置会话变量。 - 连接池耗尽: 应用层未合理配置连接池大小,导致数据库连接数超限。建议使用 PgBouncer(PostgreSQL)或 ProxySQL(MySQL)进行连接池管理。
生产环境检查清单:
- 数据库版本与平台兼容性确认(建议 PostgreSQL ≥ 14,MySQL ≥ 8.0)。
- 数据目录独立挂载(SSD 磁盘,定期快照备份)。
- 密码强度符合企业策略(长度 ≥ 16 位,包含大小写字母、数字、特殊字符)。
- 初始化脚本纳入版本控制(Git),与平台代码同步发布。
- 定期审计数据库用户与权限变更日志。