313 lines
11 KiB
PL/PgSQL
313 lines
11 KiB
PL/PgSQL
-- ============================================
|
||
-- 数据模型统一重构回滚脚本
|
||
-- 用于撤销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 '已恢复到原始数据模型状态。' |