# 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环境中成功部署和运行养老管理系统。