-- ============================================ -- 数据模型统一重构修复脚本 -- 解决视图依赖问题,完成字段重命名 -- 创建时间:2025-01-15 -- ============================================ -- 开始事务 BEGIN; -- 设置错误处理 \set ON_ERROR_STOP on -- ============================================ -- 第一阶段:删除依赖的视图 -- ============================================ -- 删除所有依赖于vehicle_id字段的视图 DROP VIEW IF EXISTS vehicle_complete_info CASCADE; DROP VIEW IF EXISTS vehicle_status_summary CASCADE; DROP VIEW IF EXISTS vehicle_info_with_location CASCADE; DROP VIEW IF EXISTS vehicle_trajectory_view CASCADE; -- ============================================ -- 第二阶段:完成字段重命名和清理 -- ============================================ -- 1. 处理sys_vehicle_info表 - 重命名license_plate_number为license_plate ALTER TABLE sys_vehicle_info RENAME COLUMN license_plate_number TO license_plate; -- 2. 处理vehicle_locations表 - 删除旧字段,重命名新字段 ALTER TABLE vehicle_locations DROP COLUMN vehicle_id; ALTER TABLE vehicle_locations RENAME COLUMN sys_vehicle_id TO vehicle_id; -- 3. 处理vehicle_trajectories表 - 删除旧字段,重命名新字段 ALTER TABLE vehicle_trajectories DROP COLUMN vehicle_id; ALTER TABLE vehicle_trajectories RENAME COLUMN sys_vehicle_id TO vehicle_id; -- 4. 处理vehicle_commands表 - 删除旧字段,重命名新字段 ALTER TABLE vehicle_commands DROP COLUMN vehicle_id; ALTER TABLE vehicle_commands RENAME COLUMN sys_vehicle_id TO vehicle_id; -- 5. 处理rule_violation_events表 - 更新subject_id字段 -- 为subject_id字段添加新列,然后删除旧列 ALTER TABLE rule_violation_events ADD COLUMN IF NOT EXISTS subject_id_new VARCHAR(50); -- 对于车辆类型的事件,使用sys_vehicle_id的值;对于其他类型,保持原值 UPDATE rule_violation_events SET subject_id_new = CASE WHEN subject_type = 'VEHICLE' AND sys_vehicle_id IS NOT NULL THEN sys_vehicle_id::VARCHAR ELSE subject_id END; -- 删除旧列,重命名新列 ALTER TABLE rule_violation_events DROP COLUMN subject_id; ALTER TABLE rule_violation_events RENAME COLUMN subject_id_new TO subject_id; -- ============================================ -- 第三阶段:重建索引 -- ============================================ -- 重建vehicle_locations表的索引 CREATE INDEX IF NOT EXISTS idx_vehicle_locations_vehicle_id ON vehicle_locations(vehicle_id); CREATE INDEX IF NOT EXISTS idx_vehicle_locations_license_plate ON vehicle_locations(license_plate); -- 重建vehicle_trajectories表的索引 CREATE INDEX IF NOT EXISTS idx_vehicle_trajectories_vehicle_id ON vehicle_trajectories(vehicle_id); CREATE INDEX IF NOT EXISTS idx_vehicle_trajectories_license_plate ON vehicle_trajectories(license_plate); -- 重建vehicle_commands表的索引 CREATE INDEX IF NOT EXISTS idx_vehicle_commands_vehicle_id ON vehicle_commands(vehicle_id); CREATE INDEX IF NOT EXISTS idx_vehicle_commands_license_plate ON vehicle_commands(license_plate); -- 重建rule_violation_events表的索引 CREATE INDEX IF NOT EXISTS idx_rule_violations_license_plate ON rule_violation_events(license_plate) WHERE subject_type = 'VEHICLE'; -- ============================================ -- 第四阶段:重建业务视图 -- ============================================ -- 1. 重建vehicle_complete_info视图 CREATE OR REPLACE VIEW vehicle_complete_info AS SELECT vi.vehicle_id, vi.license_plate, vi.vin_number, vi.brand, vi.owning_unit, vi.contact_person, vi.phone_number, vl.location, vl.altitude, vl.heading, vl.speed, vl.timestamp as last_location_time, vl.data_quality, CASE WHEN vl.timestamp > NOW() - INTERVAL '10 minutes' THEN 'ONLINE' WHEN vl.timestamp > NOW() - INTERVAL '1 hour' THEN 'RECENT' ELSE 'OFFLINE' END as connection_status FROM sys_vehicle_info vi LEFT JOIN LATERAL ( SELECT * FROM vehicle_locations WHERE vehicle_id = vi.vehicle_id ORDER BY timestamp DESC LIMIT 1 ) vl ON true; -- 2. 重建vehicle_status_summary视图 CREATE OR REPLACE VIEW vehicle_status_summary AS SELECT COUNT(*) as total_vehicles, COUNT(CASE WHEN connection_status = 'ONLINE' THEN 1 END) as online_vehicles, COUNT(CASE WHEN connection_status = 'RECENT' THEN 1 END) as recent_vehicles, COUNT(CASE WHEN connection_status = 'OFFLINE' THEN 1 END) as offline_vehicles, AVG(CASE WHEN speed IS NOT NULL THEN speed END) as avg_speed, MAX(last_location_time) as latest_update FROM vehicle_complete_info; -- 3. 重建vehicle_info_with_location视图 CREATE OR REPLACE VIEW vehicle_info_with_location AS SELECT vi.vehicle_id as sys_vehicle_id, vi.license_plate as vehicle_plate, vi.brand, vi.owning_unit, ST_X(vl.location) as longitude, ST_Y(vl.location) as latitude, vl.altitude, vl.heading, vl.speed, vl.timestamp as location_time, CASE WHEN vl.timestamp > NOW() - INTERVAL '10 minutes' THEN 'ACTIVE' WHEN vl.timestamp > NOW() - INTERVAL '1 hour' THEN 'RECENT' ELSE 'INACTIVE' END as status FROM sys_vehicle_info vi LEFT JOIN LATERAL ( SELECT * FROM vehicle_locations WHERE vehicle_id = vi.vehicle_id ORDER BY timestamp DESC LIMIT 1 ) vl ON true; -- 4. 重建vehicle_trajectory_view视图 CREATE OR REPLACE VIEW vehicle_trajectory_view AS SELECT vi.license_plate as vehicle_plate, vi.brand, vt.trajectory_date, vt.point_count, vt.start_time, vt.end_time, vt.total_distance FROM sys_vehicle_info vi JOIN vehicle_trajectories vt ON vt.vehicle_id = vi.vehicle_id; -- ============================================ -- 第五阶段:数据完整性最终验证 -- ============================================ -- 验证表结构 DO $$ BEGIN -- 验证sys_vehicle_info表 IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'sys_vehicle_info' AND column_name = 'license_plate' ) THEN RAISE EXCEPTION 'sys_vehicle_info表的license_plate字段不存在'; END IF; -- 验证vehicle_locations表 IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'vehicle_locations' AND column_name = 'vehicle_id' AND data_type = 'bigint' ) THEN RAISE EXCEPTION 'vehicle_locations表的vehicle_id字段类型不正确'; END IF; -- 验证视图存在 IF NOT EXISTS ( SELECT 1 FROM information_schema.views WHERE table_name = 'vehicle_complete_info' ) THEN RAISE EXCEPTION 'vehicle_complete_info视图不存在'; END IF; RAISE NOTICE '数据模型统一重构完成!所有表结构和视图已成功更新。'; END $$; -- ============================================ -- 第六阶段:清理工作 -- ============================================ -- 删除临时表(如果存在) DROP TABLE IF EXISTS vehicle_id_mapping; -- 提交事务 COMMIT; -- ============================================ -- 成功提示 -- ============================================ \echo '=============================================' \echo '数据模型统一重构成功完成!' \echo '✅ 所有表的vehicle_id字段已统一为BIGINT类型' \echo '✅ 所有表的车牌号字段已统一命名为license_plate' \echo '✅ 所有业务视图已重新创建' \echo '✅ 所有索引已重新构建' \echo '============================================='