-- ============================================ -- 修复车辆ID映射关系 -- 解决QAUP-Management和CollisionAvoidanceSystem之间的车辆标识符不一致问题 -- 创建时间: 2025-01-15 -- ============================================ -- ============================================ -- 方案一:优化表结构(推荐) -- 在vehicle_locations表中添加license_plate字段,保持vehicle_id作为车牌号 -- ============================================ -- 1. 为vehicle_locations表添加license_plate字段(明确语义) ALTER TABLE vehicle_locations ADD COLUMN IF NOT EXISTS license_plate VARCHAR(50); -- 2. 将现有的vehicle_id数据复制到license_plate字段 UPDATE vehicle_locations SET license_plate = vehicle_id WHERE license_plate IS NULL; -- 3. 添加索引优化查询性能 CREATE INDEX IF NOT EXISTS idx_vehicle_locations_license_plate ON vehicle_locations(license_plate); -- 4. 为vehicle_locations表添加数字车辆ID字段(可选,用于外键关联) ALTER TABLE vehicle_locations ADD COLUMN IF NOT EXISTS sys_vehicle_id BIGINT; -- 5. 添加外键约束(可选,确保数据完整性) -- 注意:只有在sys_vehicle_info表中存在对应车牌号的记录时,此约束才会生效 -- ALTER TABLE vehicle_locations -- ADD CONSTRAINT fk_vehicle_locations_sys_vehicle_id -- FOREIGN KEY (sys_vehicle_id) REFERENCES sys_vehicle_info(vehicle_id); -- 6. 同样处理vehicle_trajectories表 ALTER TABLE vehicle_trajectories ADD COLUMN IF NOT EXISTS license_plate VARCHAR(50); UPDATE vehicle_trajectories SET license_plate = vehicle_id WHERE license_plate IS NULL; CREATE INDEX IF NOT EXISTS idx_vehicle_trajectories_license_plate ON vehicle_trajectories(license_plate); ALTER TABLE vehicle_trajectories ADD COLUMN IF NOT EXISTS sys_vehicle_id BIGINT; -- 7. 处理vehicle_commands表 ALTER TABLE vehicle_commands ADD COLUMN IF NOT EXISTS license_plate VARCHAR(50); UPDATE vehicle_commands SET license_plate = vehicle_id WHERE license_plate IS NULL; CREATE INDEX IF NOT EXISTS idx_vehicle_commands_license_plate ON vehicle_commands(license_plate); ALTER TABLE vehicle_commands ADD COLUMN IF NOT EXISTS sys_vehicle_id BIGINT; -- 8. 处理rule_violation_events表 ALTER TABLE rule_violation_events ADD COLUMN IF NOT EXISTS license_plate VARCHAR(50); UPDATE rule_violation_events SET license_plate = subject_id WHERE license_plate IS NULL AND subject_type = 'VEHICLE'; CREATE INDEX IF NOT EXISTS idx_rule_violations_license_plate ON rule_violation_events(license_plate); ALTER TABLE rule_violation_events ADD COLUMN IF NOT EXISTS sys_vehicle_id BIGINT; -- ============================================ -- 更新业务视图 - 使用正确的关联字段 -- ============================================ -- 删除旧的视图 DROP VIEW IF EXISTS vehicle_complete_info; DROP VIEW IF EXISTS vehicle_status_summary; -- 重新创建车辆完整信息视图(修正关联逻辑) CREATE OR REPLACE VIEW vehicle_complete_info AS SELECT vi.vehicle_id as sys_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 license_plate = vi.license_plate_number ORDER BY timestamp DESC LIMIT 1 ) vl ON true; -- 重新创建车辆实时状态统计视图 CREATE OR REPLACE 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 OR REPLACE 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 license_plate = vi.license_plate_number ORDER BY timestamp DESC LIMIT 1 ) vl ON true; -- 车辆轨迹查询视图(按车牌号) CREATE OR REPLACE 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.license_plate = vi.license_plate_number LEFT JOIN sys_vehicle_type vtype ON vi.type_id = vtype.type_id; -- ============================================ -- 创建数据同步函数 -- ============================================ -- 函数:根据车牌号更新sys_vehicle_id CREATE OR REPLACE FUNCTION update_sys_vehicle_id() RETURNS void AS $$ BEGIN -- 更新vehicle_locations表 UPDATE vehicle_locations vl SET sys_vehicle_id = vi.vehicle_id FROM sys_vehicle_info vi WHERE vl.license_plate = vi.license_plate_number AND vl.sys_vehicle_id IS NULL; -- 更新vehicle_trajectories表 UPDATE vehicle_trajectories vt SET sys_vehicle_id = vi.vehicle_id FROM sys_vehicle_info vi WHERE vt.license_plate = vi.license_plate_number AND vt.sys_vehicle_id IS NULL; -- 更新vehicle_commands表 UPDATE vehicle_commands vc SET sys_vehicle_id = vi.vehicle_id FROM sys_vehicle_info vi WHERE vc.license_plate = vi.license_plate_number AND vc.sys_vehicle_id IS NULL; -- 更新rule_violation_events表 UPDATE rule_violation_events rve SET sys_vehicle_id = vi.vehicle_id FROM sys_vehicle_info vi WHERE rve.license_plate = vi.license_plate_number AND rve.sys_vehicle_id IS NULL AND rve.subject_type = 'VEHICLE'; RAISE NOTICE '车辆ID同步完成'; END; $$ LANGUAGE plpgsql; -- 执行一次数据同步 SELECT update_sys_vehicle_id(); -- ============================================ -- 添加注释说明 -- ============================================ COMMENT ON COLUMN vehicle_locations.license_plate IS '车牌号,对应sys_vehicle_info.license_plate_number'; COMMENT ON COLUMN vehicle_locations.sys_vehicle_id IS '系统车辆ID,对应sys_vehicle_info.vehicle_id'; COMMENT ON COLUMN vehicle_trajectories.license_plate IS '车牌号,对应sys_vehicle_info.license_plate_number'; COMMENT ON COLUMN vehicle_trajectories.sys_vehicle_id IS '系统车辆ID,对应sys_vehicle_info.vehicle_id'; COMMENT ON COLUMN vehicle_commands.license_plate IS '车牌号,对应sys_vehicle_info.license_plate_number'; COMMENT ON COLUMN vehicle_commands.sys_vehicle_id IS '系统车辆ID,对应sys_vehicle_info.vehicle_id'; COMMENT ON VIEW vehicle_complete_info IS '车辆完整信息视图,包含基础信息和最新位置,通过车牌号关联'; COMMENT ON VIEW vehicle_info_with_location IS '车辆信息与位置关联视图,提供完整的车辆状态'; COMMENT ON VIEW vehicle_trajectory_view IS '车辆轨迹视图,通过车牌号关联基础信息和轨迹数据'; -- ============================================ -- 验证脚本 -- ============================================ -- 检查表结构更新 SELECT column_name, data_type, is_nullable FROM information_schema.columns WHERE table_name IN ('vehicle_locations', 'vehicle_trajectories', 'vehicle_commands', 'rule_violation_events') AND column_name IN ('license_plate', 'sys_vehicle_id') ORDER BY table_name, column_name; -- 检查视图创建 SELECT viewname, viewowner FROM pg_views WHERE viewname IN ('vehicle_complete_info', 'vehicle_status_summary', 'vehicle_info_with_location', 'vehicle_trajectory_view') ORDER BY viewname; -- 检查数据同步结果(示例查询) SELECT 'vehicle_locations' as table_name, COUNT(*) as total_records, COUNT(license_plate) as has_license_plate, COUNT(sys_vehicle_id) as has_sys_vehicle_id FROM vehicle_locations UNION ALL SELECT 'vehicle_trajectories' as table_name, COUNT(*) as total_records, COUNT(license_plate) as has_license_plate, COUNT(sys_vehicle_id) as has_sys_vehicle_id FROM vehicle_trajectories; -- ============================================ -- 完成提示 -- ============================================ DO $$ BEGIN RAISE NOTICE '=============================================='; RAISE NOTICE '车辆ID映射关系修复完成!'; RAISE NOTICE '主要改进:'; RAISE NOTICE '1. 添加了license_plate字段明确语义'; RAISE NOTICE '2. 添加了sys_vehicle_id字段支持数字ID关联'; RAISE NOTICE '3. 更新了所有相关视图使用正确的关联逻辑'; RAISE NOTICE '4. 创建了数据同步函数'; RAISE NOTICE '建议:在应用代码中使用license_plate字段进行车辆关联'; RAISE NOTICE '=============================================='; END $$;