# 数据模型统一重构执行指南 ## 概述 本指南详细说明如何安全地执行数据模型统一重构,将两个项目的数据模型统一为: - **vehicle_id**: 所有表中统一为 `BIGINT` 数字ID - **license_plate**: 所有表中统一为 `VARCHAR(50)` 车牌号字段名 ## ⚠️ 重要提醒 ### 风险评估 - **高风险操作**: 涉及大量表结构变更和数据迁移 - **停机需求**: 建议在维护窗口期间执行 - **数据备份**: 执行前必须进行完整备份 ### 前置条件 - [ ] 数据库连接正常 - [ ] 有足够的磁盘空间(建议预留当前数据量的50%) - [ ] 数据库用户有DDL权限 - [ ] 已停止所有相关应用服务 ## 📋 执行步骤 ### 第一阶段:准备工作 #### 1. 环境检查 ```bash # 检查数据库连接 psql -h localhost -U postgres -d qaup -c "SELECT version();" # 检查表是否存在 psql -h localhost -U postgres -d qaup -c " SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_name IN ('sys_vehicle_info', 'vehicle_locations', 'vehicle_trajectories', 'vehicle_commands', 'rule_violation_events'); " ``` #### 2. 数据备份 ```bash # 完整备份 pg_dump -h localhost -U postgres -d qaup > backup_before_unification_$(date +%Y%m%d_%H%M%S).sql # 验证备份文件 ls -lh backup_before_unification_*.sql ``` #### 3. 停止相关服务 ```bash # 停止QAUP-Management服务 # 停止CollisionAvoidanceSystem服务 # 验证服务已停止 ps aux | grep -E "(qaup|collision)" ``` ### 第二阶段:数据预检查 #### 1. 检查数据完整性 ```sql -- 检查sys_vehicle_info表 SELECT COUNT(*) as total_vehicles, COUNT(DISTINCT license_plate_number) as unique_plates, COUNT(CASE WHEN license_plate_number IS NULL THEN 1 END) as null_plates FROM sys_vehicle_info; -- 检查vehicle_locations表 SELECT COUNT(*) as total_locations, COUNT(DISTINCT vehicle_id) as unique_vehicles, COUNT(CASE WHEN vehicle_id IS NULL THEN 1 END) as null_ids FROM vehicle_locations; -- 检查是否有重复车牌号 SELECT license_plate_number, COUNT(*) FROM sys_vehicle_info GROUP BY license_plate_number HAVING COUNT(*) > 1; ``` #### 2. 检查字段约束 ```sql -- 检查车牌号格式 SELECT DISTINCT license_plate_number FROM sys_vehicle_info WHERE license_plate_number IS NULL OR length(license_plate_number) = 0 OR length(license_plate_number) > 50; -- 检查vehicle_locations中的vehicle_id SELECT DISTINCT vehicle_id FROM vehicle_locations WHERE vehicle_id IS NULL OR length(vehicle_id) = 0 OR length(vehicle_id) > 50; ``` ### 第三阶段:执行重构 #### 1. 预估执行时间 ```sql -- 预估数据量 SELECT 'sys_vehicle_info' as table_name, COUNT(*) as record_count FROM sys_vehicle_info UNION ALL SELECT 'vehicle_locations' as table_name, COUNT(*) as record_count FROM vehicle_locations UNION ALL SELECT 'vehicle_trajectories' as table_name, COUNT(*) as record_count FROM vehicle_trajectories UNION ALL SELECT 'vehicle_commands' as table_name, COUNT(*) as record_count FROM vehicle_commands UNION ALL SELECT 'rule_violation_events' as table_name, COUNT(*) as record_count FROM rule_violation_events; ``` **预估时间参考**: - 小型数据库(< 10万条记录):5-10分钟 - 中型数据库(10万-100万条记录):10-30分钟 - 大型数据库(> 100万条记录):30分钟-2小时 #### 2. 执行重构脚本 ```bash # 执行主要重构脚本 psql -h localhost -U postgres -d qaup -f sql/data_model_unification.sql # 检查执行结果 echo $? # 应该返回0表示成功 ``` #### 3. 监控执行过程 ```sql -- 在另一个终端中监控进度 -- 查看当前活动会话 SELECT pid, state, query FROM pg_stat_activity WHERE datname = 'qaup'; -- 查看锁状态 SELECT * FROM pg_locks WHERE database = (SELECT oid FROM pg_database WHERE datname = 'qaup'); ``` ### 第四阶段:验证结果 #### 1. 表结构验证 ```sql -- 验证sys_vehicle_info表结构 \d sys_vehicle_info -- 验证vehicle_locations表结构 \d vehicle_locations -- 验证vehicle_trajectories表结构 \d vehicle_trajectories -- 验证vehicle_commands表结构 \d vehicle_commands -- 验证rule_violation_events表结构 \d rule_violation_events ``` #### 2. 数据完整性验证 ```sql -- 检查数据量是否一致 SELECT 'sys_vehicle_info' as table_name, COUNT(*) as record_count FROM sys_vehicle_info UNION ALL SELECT 'vehicle_locations' as table_name, COUNT(*) as record_count FROM vehicle_locations UNION ALL SELECT 'vehicle_trajectories' as table_name, COUNT(*) as record_count FROM vehicle_trajectories UNION ALL SELECT 'vehicle_commands' as table_name, COUNT(*) as record_count FROM vehicle_commands UNION ALL SELECT 'rule_violation_events' as table_name, COUNT(*) as record_count FROM rule_violation_events; -- 检查字段统一性 SELECT 'sys_vehicle_info' as table_name, COUNT(*) as total_records, COUNT(vehicle_id) as has_vehicle_id, COUNT(license_plate) as has_license_plate FROM sys_vehicle_info UNION ALL SELECT 'vehicle_locations' as table_name, COUNT(*) as total_records, COUNT(vehicle_id) as has_vehicle_id, COUNT(license_plate) as has_license_plate FROM vehicle_locations UNION ALL SELECT 'vehicle_trajectories' as table_name, COUNT(*) as total_records, COUNT(vehicle_id) as has_vehicle_id, COUNT(license_plate) as has_license_plate FROM vehicle_trajectories UNION ALL SELECT 'vehicle_commands' as table_name, COUNT(*) as total_records, COUNT(vehicle_id) as has_vehicle_id, COUNT(license_plate) as has_license_plate FROM vehicle_commands; ``` #### 3. 业务视图验证 ```sql -- 测试业务视图 SELECT * FROM vehicle_complete_info LIMIT 5; SELECT * FROM vehicle_status_summary LIMIT 5; SELECT * FROM vehicle_info_with_location LIMIT 5; SELECT * FROM vehicle_trajectory_view LIMIT 5; ``` #### 4. 关联查询验证 ```sql -- 测试车辆ID关联 SELECT vi.vehicle_id, vi.license_plate, vl.vehicle_id as location_vehicle_id, vl.license_plate as location_license_plate FROM sys_vehicle_info vi LEFT JOIN vehicle_locations vl ON vi.vehicle_id = vl.vehicle_id LIMIT 10; -- 测试车牌号关联 SELECT vi.license_plate, COUNT(vl.id) as location_count FROM sys_vehicle_info vi LEFT JOIN vehicle_locations vl ON vi.license_plate = vl.license_plate GROUP BY vi.license_plate LIMIT 10; ``` ### 第五阶段:应用层验证 #### 1. 重启服务 ```bash # 启动QAUP-Management服务 # 启动CollisionAvoidanceSystem服务 # 检查服务状态 ps aux | grep -E "(qaup|collision)" ``` #### 2. 功能验证 - [ ] 车辆信息管理功能 - [ ] 实时位置监控功能 - [ ] 轨迹查询功能 - [ ] 报表生成功能 - [ ] API接口调用 #### 3. 性能验证 ```sql -- 测试查询性能 EXPLAIN ANALYZE SELECT * FROM vehicle_info_with_location WHERE license_plate = '京A12345'; -- 测试索引使用情况 SELECT schemaname, tablename, indexname, idx_scan, idx_tup_read FROM pg_stat_user_indexes WHERE tablename IN ('sys_vehicle_info', 'vehicle_locations', 'vehicle_trajectories', 'vehicle_commands'); ``` ## 🔄 回滚处理 ### 什么时候需要回滚 - 重构过程中出现错误 - 数据验证发现问题 - 应用层功能异常 - 性能严重下降 ### 回滚步骤 ```bash # 1. 停止所有服务 # 2. 执行回滚脚本 psql -h localhost -U postgres -d qaup -f sql/data_model_unification_rollback.sql # 3. 验证回滚结果 psql -h localhost -U postgres -d qaup -c " SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'sys_vehicle_info' AND column_name LIKE '%license%'; " # 4. 恢复数据备份(如果必要) # psql -h localhost -U postgres -d qaup < backup_before_unification_YYYYMMDD_HHMMSS.sql ``` ## 📊 监控和维护 ### 性能监控 ```sql -- 监控查询性能 SELECT schemaname, tablename, seq_scan, seq_tup_read, idx_scan, idx_tup_fetch FROM pg_stat_user_tables WHERE tablename IN ('sys_vehicle_info', 'vehicle_locations', 'vehicle_trajectories', 'vehicle_commands') ORDER BY seq_tup_read DESC; ``` ### 定期维护 ```sql -- 定期更新统计信息 ANALYZE sys_vehicle_info; ANALYZE vehicle_locations; ANALYZE vehicle_trajectories; ANALYZE vehicle_commands; ANALYZE rule_violation_events; -- 定期清理和重建索引 REINDEX TABLE sys_vehicle_info; REINDEX TABLE vehicle_locations; REINDEX TABLE vehicle_trajectories; REINDEX TABLE vehicle_commands; REINDEX TABLE rule_violation_events; ``` ## 📝 常见问题解答 ### Q1: 执行过程中断了怎么办? - 检查错误日志 - 如果是网络问题,可以重新执行(脚本有幂等性) - 如果是数据问题,执行回滚脚本 ### Q2: 数据量很大,执行时间太长怎么办? - 考虑分批处理 - 在非业务高峰期执行 - 增加数据库配置参数(work_mem, maintenance_work_mem) ### Q3: 外键约束导致失败怎么办? - 脚本中外键约束是可选的 - 如果必须要外键,确保参照完整性 - 可以先删除外键,迁移后重新创建 ### Q4: 应用层报错怎么办? - 检查Java代码中的字段映射 - 检查API接口的字段名称 - 检查前端组件的字段绑定 ## 📈 版本管理 ### 更新版本信息 ```bash # 更新VERSION.md echo "0.1.4" > VERSION.md # 更新changelog.md cat >> changelog.md << EOF ## [0.1.4] - $(date +%Y-%m-%d) ### 重构 - 统一数据模型,vehicle_id为数字ID,license_plate为车牌号 - 消除所有字段名不一致问题 - 重构所有业务视图和索引 - 优化数据库性能 EOF ``` ## 🎯 完成检查清单 ### 数据库层面 - [ ] 所有表的vehicle_id都是BIGINT类型 - [ ] 所有表的车牌号字段都叫license_plate - [ ] 所有业务视图正常工作 - [ ] 所有索引创建成功 - [ ] 数据完整性验证通过 ### 应用层面 - [ ] Java实体类已更新 - [ ] MyBatis映射已更新 - [ ] Service层代码已更新 - [ ] API接口正常响应 - [ ] 前端页面正常显示 ### 功能层面 - [ ] 车辆管理功能正常 - [ ] 实时位置监控正常 - [ ] 轨迹查询正常 - [ ] 报表生成正常 - [ ] 数据关联查询正常 ### 性能层面 - [ ] 查询性能不降低 - [ ] 索引使用率正常 - [ ] 内存使用正常 - [ ] 并发性能正常 --- **执行建议**: 建议在测试环境先完整执行一遍,确保所有步骤都能正常工作后,再在生产环境执行。