-- ============================================ -- 数据模型统一重构回滚脚本 -- 用于撤销data_model_unification.sql的所有变更 -- 创建时间:2025-01-15 -- 注意:执行前请确保有完整的数据备份! -- ============================================ -- 开始事务 BEGIN; -- 设置错误处理 \set ON_ERROR_STOP on -- ============================================ -- 第一阶段:创建映射表(用于回滚) -- ============================================ -- 创建回滚映射表 CREATE TABLE IF NOT EXISTS rollback_vehicle_mapping ( vehicle_id BIGINT PRIMARY KEY, license_plate VARCHAR(50), old_vehicle_id VARCHAR(50) ); -- 填充映射表数据 INSERT INTO rollback_vehicle_mapping (vehicle_id, license_plate, old_vehicle_id) SELECT vi.vehicle_id, vi.license_plate, vi.license_plate as old_vehicle_id FROM sys_vehicle_info vi ON CONFLICT (vehicle_id) DO NOTHING; -- ============================================ -- 第二阶段:恢复CollisionAvoidanceSystem表结构 -- ============================================ -- 1. 恢复vehicle_locations表 -- 添加临时字段 ALTER TABLE vehicle_locations ADD COLUMN IF NOT EXISTS vehicle_id_old VARCHAR(50); -- 填充旧字段数据 UPDATE vehicle_locations vl SET vehicle_id_old = rvm.old_vehicle_id FROM rollback_vehicle_mapping rvm WHERE vl.vehicle_id = rvm.vehicle_id; -- 删除新字段,重命名旧字段 ALTER TABLE vehicle_locations DROP COLUMN IF EXISTS vehicle_id; ALTER TABLE vehicle_locations DROP COLUMN IF EXISTS license_plate; ALTER TABLE vehicle_locations RENAME COLUMN vehicle_id_old TO vehicle_id; -- 2. 恢复vehicle_trajectories表 -- 添加临时字段 ALTER TABLE vehicle_trajectories ADD COLUMN IF NOT EXISTS vehicle_id_old VARCHAR(50); -- 填充旧字段数据 UPDATE vehicle_trajectories vt SET vehicle_id_old = rvm.old_vehicle_id FROM rollback_vehicle_mapping rvm WHERE vt.vehicle_id = rvm.vehicle_id; -- 删除新字段,重命名旧字段 ALTER TABLE vehicle_trajectories DROP COLUMN IF EXISTS vehicle_id; ALTER TABLE vehicle_trajectories DROP COLUMN IF EXISTS license_plate; ALTER TABLE vehicle_trajectories RENAME COLUMN vehicle_id_old TO vehicle_id; -- 3. 恢复vehicle_commands表 -- 添加临时字段 ALTER TABLE vehicle_commands ADD COLUMN IF NOT EXISTS vehicle_id_old VARCHAR(50); -- 填充旧字段数据 UPDATE vehicle_commands vc SET vehicle_id_old = rvm.old_vehicle_id FROM rollback_vehicle_mapping rvm WHERE vc.vehicle_id = rvm.vehicle_id; -- 删除新字段,重命名旧字段 ALTER TABLE vehicle_commands DROP COLUMN IF EXISTS vehicle_id; ALTER TABLE vehicle_commands DROP COLUMN IF EXISTS license_plate; ALTER TABLE vehicle_commands RENAME COLUMN vehicle_id_old TO vehicle_id; -- 4. 恢复rule_violation_events表 -- 添加临时字段 ALTER TABLE rule_violation_events ADD COLUMN IF NOT EXISTS subject_id_old VARCHAR(50); -- 填充旧字段数据 UPDATE rule_violation_events rve SET subject_id_old = CASE WHEN rve.subject_type = 'VEHICLE' THEN rvm.old_vehicle_id ELSE rve.subject_id END FROM rollback_vehicle_mapping rvm WHERE rve.subject_type = 'VEHICLE' AND rve.subject_id = rvm.vehicle_id::VARCHAR; -- 删除新字段,重命名旧字段 ALTER TABLE rule_violation_events DROP COLUMN IF EXISTS subject_id; ALTER TABLE rule_violation_events DROP COLUMN IF EXISTS license_plate; ALTER TABLE rule_violation_events DROP COLUMN IF EXISTS vehicle_id_new; ALTER TABLE rule_violation_events RENAME COLUMN subject_id_old TO subject_id; -- ============================================ -- 第三阶段:恢复QAUP-Management表结构 -- ============================================ -- 1. 恢复sys_vehicle_info表字段名 ALTER TABLE sys_vehicle_info RENAME COLUMN license_plate TO license_plate_number; -- 2. 删除自动创建的车辆记录 DELETE FROM sys_vehicle_info WHERE create_by = 'system' AND remark = '数据模型统一时自动创建'; -- ============================================ -- 第四阶段:恢复索引 -- ============================================ -- 1. 恢复vehicle_locations表索引 DROP INDEX IF EXISTS idx_vehicle_locations_vehicle_id; DROP INDEX IF EXISTS idx_vehicle_locations_license_plate; CREATE INDEX idx_vehicle_locations_vehicle_id ON vehicle_locations(vehicle_id); -- 2. 恢复vehicle_trajectories表索引 DROP INDEX IF EXISTS idx_vehicle_trajectories_vehicle_id; DROP INDEX IF EXISTS idx_vehicle_trajectories_license_plate; CREATE INDEX idx_vehicle_trajectories_vehicle_id ON vehicle_trajectories(vehicle_id); -- 3. 恢复vehicle_commands表索引 DROP INDEX IF EXISTS idx_vehicle_commands_vehicle_id; DROP INDEX IF EXISTS idx_vehicle_commands_license_plate; CREATE INDEX idx_vehicle_commands_vehicle_id ON vehicle_commands(vehicle_id); -- 4. 恢复rule_violation_events表索引 DROP INDEX IF EXISTS idx_rule_violations_license_plate; -- ============================================ -- 第五阶段:删除外键约束(如果存在) -- ============================================ -- 删除外键约束 ALTER TABLE vehicle_locations DROP CONSTRAINT IF EXISTS fk_vehicle_locations_vehicle_id; ALTER TABLE vehicle_trajectories DROP CONSTRAINT IF EXISTS fk_vehicle_trajectories_vehicle_id; ALTER TABLE vehicle_commands DROP CONSTRAINT IF EXISTS fk_vehicle_commands_vehicle_id; -- ============================================ -- 第六阶段:恢复业务视图 -- ============================================ -- 删除新视图 DROP VIEW IF EXISTS vehicle_complete_info; DROP VIEW IF EXISTS vehicle_status_summary; DROP VIEW IF EXISTS vehicle_info_with_location; DROP VIEW IF EXISTS vehicle_trajectory_view; -- 重新创建原始视图(基于原始字段结构) CREATE VIEW vehicle_complete_info AS SELECT vi.vehicle_id, vi.license_plate_number, vi.vin_number, vi.type_id, vt.type_name, vi.brand, vi.owning_unit, vi.contact_person, vi.phone_number, vi.image_url, vl.location, vl.altitude, vl.heading, vl.speed, vl.timestamp as last_location_time, vl.data_quality, vi.create_time, vi.update_time FROM sys_vehicle_info vi LEFT JOIN sys_vehicle_type vt ON vi.type_id = vt.type_id LEFT JOIN LATERAL ( SELECT * FROM vehicle_locations WHERE vehicle_id = vi.license_plate_number ORDER BY timestamp DESC LIMIT 1 ) vl ON true; -- 车辆状态统计视图 CREATE VIEW vehicle_status_summary AS SELECT vehicle_type, COUNT(*) as total_vehicles, COUNT(CASE WHEN timestamp > NOW() - INTERVAL '5 minutes' THEN 1 END) as active_vehicles, COUNT(CASE WHEN timestamp <= NOW() - INTERVAL '5 minutes' THEN 1 END) as inactive_vehicles, AVG(speed) as avg_speed, MAX(speed) as max_speed FROM vehicle_locations vl WHERE timestamp > NOW() - INTERVAL '24 hours' GROUP BY vehicle_type; -- 车辆信息与位置关联视图 CREATE VIEW vehicle_info_with_location AS SELECT vi.vehicle_id as sys_vehicle_id, vi.license_plate_number as vehicle_plate, vi.brand, vi.owning_unit, vt.type_name as vehicle_type_name, vl.vehicle_type as location_vehicle_type, vl.location, ST_X(vl.location) as longitude, ST_Y(vl.location) as latitude, vl.altitude, vl.heading, vl.speed, vl.timestamp as last_update_time, CASE WHEN vl.timestamp > NOW() - INTERVAL '5 minutes' THEN 'ACTIVE' WHEN vl.timestamp > NOW() - INTERVAL '30 minutes' THEN 'INACTIVE' ELSE 'OFFLINE' END as status FROM sys_vehicle_info vi LEFT JOIN sys_vehicle_type vt ON vi.type_id = vt.type_id LEFT JOIN LATERAL ( SELECT * FROM vehicle_locations WHERE vehicle_id = vi.license_plate_number ORDER BY timestamp DESC LIMIT 1 ) vl ON true; -- 车辆轨迹查询视图 CREATE VIEW vehicle_trajectory_view AS SELECT vi.vehicle_id as sys_vehicle_id, vi.license_plate_number as vehicle_plate, vi.brand, vt.trajectory_date, vt.trajectory_line, vt.total_distance, vt.max_speed, vt.avg_speed, vt.duration_seconds, vt.start_time, vt.end_time FROM sys_vehicle_info vi INNER JOIN vehicle_trajectories vt ON vt.vehicle_id = vi.license_plate_number LEFT JOIN sys_vehicle_type vtype ON vi.type_id = vtype.type_id; -- ============================================ -- 第七阶段:恢复字段注释 -- ============================================ -- 恢复sys_vehicle_info表字段注释 COMMENT ON COLUMN sys_vehicle_info.license_plate_number IS '车牌号'; -- 恢复vehicle_locations表字段注释 COMMENT ON COLUMN vehicle_locations.vehicle_id IS '车辆标识符(车牌号、航班号等)'; -- 恢复vehicle_trajectories表字段注释 COMMENT ON COLUMN vehicle_trajectories.vehicle_id IS '车辆标识符(车牌号、航班号等)'; -- 恢复vehicle_commands表字段注释 COMMENT ON COLUMN vehicle_commands.vehicle_id IS '车辆ID'; -- ============================================ -- 第八阶段:清理临时数据 -- ============================================ -- 删除回滚映射表 DROP TABLE IF EXISTS rollback_vehicle_mapping; -- ============================================ -- 最终验证 -- ============================================ DO $$ DECLARE qaup_count INTEGER; locations_count INTEGER; trajectories_count INTEGER; commands_count INTEGER; violations_count INTEGER; BEGIN -- 统计各表记录数 SELECT COUNT(*) INTO qaup_count FROM sys_vehicle_info; SELECT COUNT(*) INTO locations_count FROM vehicle_locations; SELECT COUNT(*) INTO trajectories_count FROM vehicle_trajectories; SELECT COUNT(*) INTO commands_count FROM vehicle_commands; SELECT COUNT(*) INTO violations_count FROM rule_violation_events WHERE subject_type = 'VEHICLE'; -- 输出统计信息 RAISE NOTICE '=============================================='; RAISE NOTICE '数据模型统一重构回滚完成!'; RAISE NOTICE '=============================================='; RAISE NOTICE '车辆信息记录: %', qaup_count; RAISE NOTICE '位置记录: %', locations_count; RAISE NOTICE '轨迹记录: %', trajectories_count; RAISE NOTICE '指令记录: %', commands_count; RAISE NOTICE '违规事件记录: %', violations_count; RAISE NOTICE '=============================================='; RAISE NOTICE '已恢复到原始数据模型:'; RAISE NOTICE '1. vehicle_id恢复为字符串类型(车牌号)'; RAISE NOTICE '2. license_plate_number恢复为原始字段名'; RAISE NOTICE '3. 删除了所有新增字段'; RAISE NOTICE '4. 恢复了原始业务视图'; RAISE NOTICE '5. 恢复了原始索引结构'; RAISE NOTICE '=============================================='; END $$; -- 提交事务 COMMIT; -- 显示完成消息 \echo '数据模型统一重构回滚脚本执行完成!' \echo '已恢复到原始数据模型状态。'