214 lines
7.4 KiB
PL/PgSQL
214 lines
7.4 KiB
PL/PgSQL
-- ============================================
|
||
-- 数据模型统一重构修复脚本
|
||
-- 解决视图依赖问题,完成字段重命名
|
||
-- 创建时间: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 '=============================================' |