Initial commit of akmon project
This commit is contained in:
450
doc_eldercare/eldercare_postgresql_deployment_guide.md
Normal file
450
doc_eldercare/eldercare_postgresql_deployment_guide.md
Normal file
@@ -0,0 +1,450 @@
|
||||
# PostgreSQL 养老系统数据库部署指南
|
||||
|
||||
## 概述
|
||||
本文档提供了PostgreSQL兼容版本的养老管理系统数据库的部署和配置指南。
|
||||
|
||||
## PostgreSQL版本要求
|
||||
- **最低版本:** PostgreSQL 13+
|
||||
- **推荐版本:** PostgreSQL 15+
|
||||
- **必需扩展:** uuid-ossp, pgcrypto
|
||||
|
||||
## 主要改进
|
||||
|
||||
### 1. PostgreSQL特性兼容
|
||||
- ✅ 使用 `CURRENT_TIMESTAMP` 替代 `now()`
|
||||
- ✅ 使用 `CREATE TABLE IF NOT EXISTS` 避免重复创建
|
||||
- ✅ 使用 `ON CONFLICT DO NOTHING` 处理重复插入
|
||||
- ✅ 添加数据约束检查(CHECK constraints)
|
||||
- ✅ 使用PostgreSQL原生UUID生成函数
|
||||
|
||||
### 2. RLS策略优化
|
||||
- ✅ 创建 `get_current_user_id()` 函数替代 `auth.uid()`
|
||||
- ✅ 支持session变量获取用户ID
|
||||
- ✅ 添加错误处理和默认值
|
||||
|
||||
### 3. 数据完整性增强
|
||||
- ✅ 添加CHECK约束验证数据范围
|
||||
- ✅ 外键级联删除配置
|
||||
- ✅ 唯一约束和索引优化
|
||||
- ✅ 时间顺序验证约束
|
||||
|
||||
### 4. 触发器和函数
|
||||
- ✅ 自动更新时间戳触发器
|
||||
- ✅ 自动生成老人编号
|
||||
- ✅ 健康预警自动生成
|
||||
- ✅ 入住率自动计算
|
||||
|
||||
## 部署步骤
|
||||
|
||||
### 第一步:环境准备
|
||||
|
||||
```bash
|
||||
# 1. 检查PostgreSQL版本
|
||||
psql --version
|
||||
|
||||
# 2. 连接到数据库
|
||||
psql -h localhost -U your_user -d your_database
|
||||
|
||||
# 3. 检查扩展可用性
|
||||
\dx
|
||||
```
|
||||
|
||||
### 第二步:执行SQL脚本
|
||||
|
||||
```sql
|
||||
-- 在PostgreSQL中执行
|
||||
\i eldercare_system_database_postgresql.sql
|
||||
```
|
||||
|
||||
### 第三步:验证安装
|
||||
|
||||
```sql
|
||||
-- 检查系统状态
|
||||
SELECT * FROM eldercare_system_status();
|
||||
|
||||
-- 检查表创建
|
||||
\dt ec_*
|
||||
|
||||
-- 检查索引
|
||||
\di idx_ec_*
|
||||
|
||||
-- 检查触发器
|
||||
\df *elder*
|
||||
|
||||
-- 检查RLS策略
|
||||
SELECT schemaname, tablename, policyname, permissive, roles, cmd, qual
|
||||
FROM pg_policies
|
||||
WHERE tablename LIKE 'ec_%';
|
||||
```
|
||||
|
||||
### 第四步:配置用户认证
|
||||
|
||||
```sql
|
||||
-- 方法1:使用session变量
|
||||
-- 在应用连接时设置用户ID
|
||||
SET app.current_user_id = 'your-user-uuid';
|
||||
|
||||
-- 方法2:修改get_current_user_id函数
|
||||
-- 根据实际认证系统调整函数实现
|
||||
CREATE OR REPLACE FUNCTION get_current_user_id()
|
||||
RETURNS uuid AS $$
|
||||
BEGIN
|
||||
-- 示例:从JWT token获取用户ID
|
||||
RETURN (current_setting('jwt.claims.user_id', true))::uuid;
|
||||
-- 或从其他认证源获取
|
||||
END;
|
||||
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
||||
```
|
||||
|
||||
### 第五步:插入测试数据
|
||||
|
||||
```sql
|
||||
-- 插入示例数据
|
||||
SELECT insert_sample_eldercare_data();
|
||||
|
||||
-- 验证数据
|
||||
SELECT * FROM public.ec_facilities;
|
||||
```
|
||||
|
||||
## 性能优化配置
|
||||
|
||||
### 1. PostgreSQL配置优化
|
||||
|
||||
```sql
|
||||
-- 内存配置
|
||||
shared_buffers = '256MB' # 25% of RAM
|
||||
effective_cache_size = '1GB' # 75% of RAM
|
||||
work_mem = '4MB' # Per connection
|
||||
maintenance_work_mem = '64MB'
|
||||
|
||||
-- 连接配置
|
||||
max_connections = 100
|
||||
listen_addresses = '*'
|
||||
|
||||
-- 日志配置
|
||||
log_statement = 'mod'
|
||||
log_duration = on
|
||||
log_min_duration_statement = 1000
|
||||
```
|
||||
|
||||
### 2. 索引监控
|
||||
|
||||
```sql
|
||||
-- 检查索引使用情况
|
||||
SELECT
|
||||
schemaname,
|
||||
tablename,
|
||||
indexname,
|
||||
idx_scan,
|
||||
idx_tup_read,
|
||||
idx_tup_fetch
|
||||
FROM pg_stat_user_indexes
|
||||
WHERE schemaname = 'public'
|
||||
AND tablename LIKE 'ec_%'
|
||||
ORDER BY idx_scan DESC;
|
||||
|
||||
-- 检查未使用的索引
|
||||
SELECT
|
||||
schemaname,
|
||||
tablename,
|
||||
indexname,
|
||||
idx_scan
|
||||
FROM pg_stat_user_indexes
|
||||
WHERE idx_scan = 0
|
||||
AND schemaname = 'public'
|
||||
AND tablename LIKE 'ec_%';
|
||||
```
|
||||
|
||||
### 3. 查询性能分析
|
||||
|
||||
```sql
|
||||
-- 分析慢查询
|
||||
SELECT
|
||||
query,
|
||||
calls,
|
||||
total_time,
|
||||
mean_time,
|
||||
rows
|
||||
FROM pg_stat_statements
|
||||
WHERE query LIKE '%ec_%'
|
||||
ORDER BY mean_time DESC
|
||||
LIMIT 10;
|
||||
```
|
||||
|
||||
## 数据维护
|
||||
|
||||
### 1. 定期清理
|
||||
|
||||
```sql
|
||||
-- 设置定期清理任务
|
||||
SELECT cron.schedule('eldercare-cleanup', '0 2 * * *', 'SELECT cleanup_expired_data();');
|
||||
|
||||
-- 手动执行清理
|
||||
SELECT cleanup_expired_data();
|
||||
```
|
||||
|
||||
### 2. 数据完整性检查
|
||||
|
||||
```sql
|
||||
-- 执行完整性检查
|
||||
SELECT check_elder_data_integrity();
|
||||
|
||||
-- 查看约束违反
|
||||
SELECT conname, conrelid::regclass
|
||||
FROM pg_constraint
|
||||
WHERE NOT convalidated;
|
||||
```
|
||||
|
||||
### 3. 统计信息更新
|
||||
|
||||
```sql
|
||||
-- 更新表统计信息
|
||||
ANALYZE public.ec_elders;
|
||||
ANALYZE public.ec_care_tasks;
|
||||
ANALYZE public.ec_vital_signs;
|
||||
|
||||
-- 自动更新配置
|
||||
ALTER TABLE public.ec_elders SET (autovacuum_analyze_scale_factor = 0.05);
|
||||
```
|
||||
|
||||
## 备份和恢复
|
||||
|
||||
### 1. 逻辑备份
|
||||
|
||||
```bash
|
||||
# 备份整个数据库
|
||||
pg_dump -h localhost -U your_user -d your_database -f eldercare_backup.sql
|
||||
|
||||
# 仅备份养老系统表
|
||||
pg_dump -h localhost -U your_user -d your_database -t 'ec_*' -f eldercare_tables_backup.sql
|
||||
|
||||
# 恢复数据库
|
||||
psql -h localhost -U your_user -d your_database -f eldercare_backup.sql
|
||||
```
|
||||
|
||||
### 2. 物理备份
|
||||
|
||||
```bash
|
||||
# 使用pg_basebackup
|
||||
pg_basebackup -h localhost -D /backup/postgresql -U replication_user -W
|
||||
|
||||
# 配置连续归档
|
||||
archive_mode = on
|
||||
archive_command = 'cp %p /backup/archive/%f'
|
||||
```
|
||||
|
||||
## 监控和告警
|
||||
|
||||
### 1. 系统监控
|
||||
|
||||
```sql
|
||||
-- 监控连接数
|
||||
SELECT count(*) as active_connections
|
||||
FROM pg_stat_activity
|
||||
WHERE state = 'active';
|
||||
|
||||
-- 监控锁等待
|
||||
SELECT
|
||||
blocked_locks.pid AS blocked_pid,
|
||||
blocked_activity.usename AS blocked_user,
|
||||
blocking_locks.pid AS blocking_pid,
|
||||
blocking_activity.usename AS blocking_user,
|
||||
blocked_activity.query AS blocked_statement
|
||||
FROM pg_catalog.pg_locks blocked_locks
|
||||
JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
|
||||
JOIN pg_catalog.pg_locks blocking_locks ON blocking_locks.locktype = blocked_locks.locktype
|
||||
JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
|
||||
WHERE NOT blocked_locks.GRANTED;
|
||||
```
|
||||
|
||||
### 2. 业务监控
|
||||
|
||||
```sql
|
||||
-- 创建监控视图
|
||||
CREATE OR REPLACE VIEW public.vw_eldercare_monitoring AS
|
||||
SELECT
|
||||
'active_elders' as metric_name,
|
||||
COUNT(*) as metric_value,
|
||||
CURRENT_TIMESTAMP as measured_at
|
||||
FROM public.ec_elders WHERE status = 'active'
|
||||
UNION ALL
|
||||
SELECT
|
||||
'pending_tasks',
|
||||
COUNT(*),
|
||||
CURRENT_TIMESTAMP
|
||||
FROM public.ec_care_tasks WHERE status = 'pending'
|
||||
UNION ALL
|
||||
SELECT
|
||||
'active_alerts',
|
||||
COUNT(*),
|
||||
CURRENT_TIMESTAMP
|
||||
FROM public.ec_health_alerts WHERE status = 'active';
|
||||
```
|
||||
|
||||
## 安全配置
|
||||
|
||||
### 1. 用户权限管理
|
||||
|
||||
```sql
|
||||
-- 创建只读用户
|
||||
CREATE USER eldercare_readonly WITH PASSWORD 'secure_password';
|
||||
GRANT CONNECT ON DATABASE your_database TO eldercare_readonly;
|
||||
GRANT USAGE ON SCHEMA public TO eldercare_readonly;
|
||||
GRANT SELECT ON ALL TABLES IN SCHEMA public TO eldercare_readonly;
|
||||
|
||||
-- 创建应用用户
|
||||
CREATE USER eldercare_app WITH PASSWORD 'app_password';
|
||||
GRANT CONNECT ON DATABASE your_database TO eldercare_app;
|
||||
GRANT USAGE ON SCHEMA public TO eldercare_app;
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO eldercare_app;
|
||||
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO eldercare_app;
|
||||
```
|
||||
|
||||
### 2. SSL配置
|
||||
|
||||
```sql
|
||||
-- 在postgresql.conf中启用SSL
|
||||
ssl = on
|
||||
ssl_cert_file = 'server.crt'
|
||||
ssl_key_file = 'server.key'
|
||||
ssl_ca_file = 'ca.crt'
|
||||
|
||||
-- 在pg_hba.conf中要求SSL连接
|
||||
hostssl all eldercare_app 0.0.0.0/0 md5
|
||||
```
|
||||
|
||||
### 3. 审计日志
|
||||
|
||||
```sql
|
||||
-- 启用审计扩展(如果可用)
|
||||
CREATE EXTENSION IF NOT EXISTS pgaudit;
|
||||
|
||||
-- 配置审计
|
||||
ALTER SYSTEM SET pgaudit.log = 'write,ddl';
|
||||
SELECT pg_reload_conf();
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 1. 常见问题
|
||||
|
||||
**问题:** RLS策略阻止数据访问
|
||||
```sql
|
||||
-- 临时禁用RLS(仅用于调试)
|
||||
ALTER TABLE public.ec_elders DISABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- 检查当前用户ID设置
|
||||
SELECT get_current_user_id();
|
||||
|
||||
-- 重新启用RLS
|
||||
ALTER TABLE public.ec_elders ENABLE ROW LEVEL SECURITY;
|
||||
```
|
||||
|
||||
**问题:** 触发器执行失败
|
||||
```sql
|
||||
-- 检查触发器状态
|
||||
SELECT
|
||||
trigger_name,
|
||||
event_object_table,
|
||||
trigger_schema,
|
||||
action_statement
|
||||
FROM information_schema.triggers
|
||||
WHERE trigger_schema = 'public'
|
||||
AND event_object_table LIKE 'ec_%';
|
||||
```
|
||||
|
||||
**问题:** 性能问题
|
||||
```sql
|
||||
-- 检查慢查询
|
||||
SELECT
|
||||
query,
|
||||
calls,
|
||||
total_time/calls as avg_time_ms
|
||||
FROM pg_stat_statements
|
||||
WHERE query LIKE '%ec_%'
|
||||
ORDER BY total_time DESC
|
||||
LIMIT 5;
|
||||
```
|
||||
|
||||
### 2. 日志分析
|
||||
|
||||
```bash
|
||||
# 分析PostgreSQL日志
|
||||
tail -f /var/log/postgresql/postgresql.log | grep "ec_"
|
||||
|
||||
# 使用pgbadger分析日志
|
||||
pgbadger /var/log/postgresql/postgresql.log -o report.html
|
||||
```
|
||||
|
||||
## 升级和维护
|
||||
|
||||
### 1. 版本升级
|
||||
|
||||
```bash
|
||||
# 使用pg_upgrade升级
|
||||
pg_upgrade -b /old/version/bin -B /new/version/bin -d /old/data -D /new/data
|
||||
|
||||
# 或使用pg_dump/restore方式
|
||||
pg_dump old_database | psql new_database
|
||||
```
|
||||
|
||||
### 2. 架构变更
|
||||
|
||||
```sql
|
||||
-- 添加新列示例
|
||||
ALTER TABLE public.ec_elders
|
||||
ADD COLUMN IF NOT EXISTS emergency_contact_phone VARCHAR(32);
|
||||
|
||||
-- 创建迁移脚本
|
||||
CREATE OR REPLACE FUNCTION migrate_eldercare_schema_v2()
|
||||
RETURNS VOID AS $$
|
||||
BEGIN
|
||||
-- 添加新功能...
|
||||
RAISE NOTICE 'Schema migration completed';
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
```
|
||||
|
||||
## 测试验证
|
||||
|
||||
### 1. 功能测试
|
||||
|
||||
```sql
|
||||
-- 测试老人数据插入
|
||||
DO $$
|
||||
DECLARE
|
||||
test_elder_id uuid;
|
||||
BEGIN
|
||||
INSERT INTO public.ec_elders (name, gender, birthday, facility_id)
|
||||
VALUES ('测试老人', 'male', '1950-01-01',
|
||||
(SELECT id FROM public.ec_facilities LIMIT 1))
|
||||
RETURNING id INTO test_elder_id;
|
||||
|
||||
RAISE NOTICE '测试老人创建成功,ID: %', test_elder_id;
|
||||
|
||||
-- 清理测试数据
|
||||
DELETE FROM public.ec_elders WHERE id = test_elder_id;
|
||||
END $$;
|
||||
```
|
||||
|
||||
### 2. 性能测试
|
||||
|
||||
```sql
|
||||
-- 测试查询性能
|
||||
EXPLAIN (ANALYZE, BUFFERS)
|
||||
SELECT e.*, f.name as facility_name
|
||||
FROM public.ec_elders e
|
||||
JOIN public.ec_facilities f ON e.facility_id = f.id
|
||||
WHERE e.status = 'active';
|
||||
```
|
||||
|
||||
## 结论
|
||||
|
||||
PostgreSQL版本的养老管理系统数据库提供了:
|
||||
- ✅ 完整的PostgreSQL兼容性
|
||||
- ✅ 增强的数据完整性约束
|
||||
- ✅ 优化的性能和索引
|
||||
- ✅ 完善的安全策略
|
||||
- ✅ 自动化的维护功能
|
||||
|
||||
通过本指南的配置,您可以在PostgreSQL环境中成功部署和运行养老管理系统。
|
||||
Reference in New Issue
Block a user