2. 创建机场区域PostGIS实体类(AirportArea) 3. 创建数据库迁移脚本(表结构、索引、分区) 4. 实现车辆位置Repository接口 5. 实现机场区域Repository接口 6. 创建PostGIS车辆服务(PostGISVehicleService) 7. 创建PostGIS区域服务(PostGISAreaService) 8. 创建统一空间查询服务(SpatialQueryService) 9. 实现区域配置导入工具(YAML到数据库) 10. 重构DataCollectorService(移除内存存储) 11. 重构AirportAreaService(基于数据库查询) 12. 移除MovingObjectRepository和相关内存存储代码 13. 移除AirportAreasProperties和YAML配置加载 14. 实现Redis缓存策略 15. 数据库连接池和性能优化配置 16. 创建单元测试和集成测试
237 lines
9.4 KiB
PL/PgSQL
237 lines
9.4 KiB
PL/PgSQL
-- ============================================
|
||
-- PostGIS空间数据表结构创建脚本
|
||
-- 适用于车辆碰撞避免系统
|
||
-- PostgreSQL 17 + PostGIS扩展
|
||
-- ============================================
|
||
|
||
-- 确保PostGIS扩展已启用
|
||
CREATE EXTENSION IF NOT EXISTS postgis;
|
||
CREATE EXTENSION IF NOT EXISTS postgis_topology;
|
||
|
||
-- ============================================
|
||
-- 1. 车辆位置表 (vehicle_locations)
|
||
-- ============================================
|
||
CREATE TABLE IF NOT EXISTS vehicle_locations (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
vehicle_id VARCHAR(50) NOT NULL,
|
||
vehicle_type VARCHAR(20) NOT NULL CHECK (vehicle_type IN ('AIRCRAFT', 'SPECIAL_VEHICLE', 'UNMANNED_VEHICLE')),
|
||
|
||
-- PostGIS空间字段 (WGS84坐标系)
|
||
location GEOMETRY(POINT, 4326) NOT NULL,
|
||
|
||
-- 位置相关属性
|
||
altitude DOUBLE PRECISION,
|
||
heading DOUBLE PRECISION CHECK (heading >= 0 AND heading < 360),
|
||
speed DOUBLE PRECISION CHECK (speed >= 0),
|
||
|
||
-- 时间戳
|
||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
||
-- 数据质量指标
|
||
data_quality VARCHAR(20),
|
||
|
||
-- 审计字段
|
||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
|
||
-- 车辆位置表索引
|
||
CREATE INDEX IF NOT EXISTS idx_vehicle_locations_vehicle_id ON vehicle_locations(vehicle_id);
|
||
CREATE INDEX IF NOT EXISTS idx_vehicle_locations_vehicle_type ON vehicle_locations(vehicle_type);
|
||
CREATE INDEX IF NOT EXISTS idx_vehicle_locations_timestamp ON vehicle_locations(timestamp DESC);
|
||
CREATE INDEX IF NOT EXISTS idx_vehicle_locations_created_at ON vehicle_locations(created_at);
|
||
|
||
-- PostGIS空间索引 (GIST索引)
|
||
CREATE INDEX IF NOT EXISTS idx_vehicle_locations_location_gist ON vehicle_locations USING GIST(location);
|
||
|
||
-- 复合索引优化查询性能
|
||
CREATE INDEX IF NOT EXISTS idx_vehicle_locations_compound ON vehicle_locations(vehicle_id, timestamp DESC);
|
||
CREATE INDEX IF NOT EXISTS idx_vehicle_locations_type_time ON vehicle_locations(vehicle_type, timestamp DESC);
|
||
|
||
-- ============================================
|
||
-- 2. 机场区域表 (airport_areas)
|
||
-- ============================================
|
||
CREATE TABLE IF NOT EXISTS airport_areas (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
area_id VARCHAR(50) NOT NULL UNIQUE,
|
||
name VARCHAR(100) NOT NULL,
|
||
type VARCHAR(30) NOT NULL,
|
||
description VARCHAR(500),
|
||
|
||
-- PostGIS空间字段 (支持POLYGON/MULTIPOLYGON)
|
||
boundary GEOMETRY(POLYGON, 4326) NOT NULL,
|
||
|
||
-- 速度和限制
|
||
speed_limit_kph DOUBLE PRECISION,
|
||
restricted BOOLEAN DEFAULT false,
|
||
allowed_vehicle_types JSONB,
|
||
allowed_aircraft_types JSONB,
|
||
max_height DOUBLE PRECISION,
|
||
max_weight DOUBLE PRECISION,
|
||
|
||
-- 时间控制
|
||
active_time TIMESTAMP WITH TIME ZONE,
|
||
expiry_time TIMESTAMP WITH TIME ZONE,
|
||
|
||
-- 区域属性
|
||
enabled BOOLEAN NOT NULL DEFAULT true,
|
||
priority INTEGER NOT NULL DEFAULT 1 CHECK (priority >= 1),
|
||
|
||
-- 版本控制
|
||
version BIGINT NOT NULL DEFAULT 1,
|
||
|
||
-- 审计字段
|
||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
|
||
-- 机场区域表索引
|
||
CREATE INDEX IF NOT EXISTS idx_airport_areas_area_id ON airport_areas(area_id);
|
||
CREATE INDEX IF NOT EXISTS idx_airport_areas_name ON airport_areas(name);
|
||
CREATE INDEX IF NOT EXISTS idx_airport_areas_type ON airport_areas(type);
|
||
CREATE INDEX IF NOT EXISTS idx_airport_areas_priority ON airport_areas(priority DESC);
|
||
CREATE INDEX IF NOT EXISTS idx_airport_areas_enabled ON airport_areas(enabled);
|
||
CREATE INDEX IF NOT EXISTS idx_airport_areas_version ON airport_areas(version);
|
||
|
||
-- PostGIS空间索引
|
||
CREATE INDEX IF NOT EXISTS idx_airport_areas_boundary_gist ON airport_areas USING GIST(boundary);
|
||
|
||
-- JSONB索引 (用于车辆类型查询)
|
||
CREATE INDEX IF NOT EXISTS idx_airport_areas_allowed_vehicles_gin ON airport_areas USING GIN(allowed_vehicle_types);
|
||
CREATE INDEX IF NOT EXISTS idx_airport_areas_allowed_aircraft_gin ON airport_areas USING GIN(allowed_aircraft_types);
|
||
|
||
-- 复合索引
|
||
CREATE INDEX IF NOT EXISTS idx_airport_areas_type_enabled ON airport_areas(type, enabled);
|
||
CREATE INDEX IF NOT EXISTS idx_airport_areas_enabled_priority ON airport_areas(enabled, priority DESC);
|
||
|
||
-- ============================================
|
||
-- 3. 车辆轨迹表 (vehicle_trajectories) - 可选的历史轨迹存储
|
||
-- ============================================
|
||
CREATE TABLE IF NOT EXISTS vehicle_trajectories (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
vehicle_id VARCHAR(50) NOT NULL,
|
||
trajectory_date DATE NOT NULL,
|
||
|
||
-- PostGIS轨迹线 (LINESTRING)
|
||
trajectory_line GEOMETRY(LINESTRING, 4326),
|
||
|
||
-- 统计信息
|
||
total_distance DOUBLE PRECISION, -- 总距离 (米)
|
||
max_speed DOUBLE PRECISION, -- 最大速度
|
||
avg_speed DOUBLE PRECISION, -- 平均速度
|
||
duration_seconds INTEGER, -- 持续时间 (秒)
|
||
point_count INTEGER, -- 轨迹点数量
|
||
|
||
-- 时间范围
|
||
start_time TIMESTAMP WITH TIME ZONE NOT NULL,
|
||
end_time TIMESTAMP WITH TIME ZONE NOT NULL,
|
||
|
||
-- 审计字段
|
||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
|
||
-- 车辆轨迹表索引
|
||
CREATE INDEX IF NOT EXISTS idx_vehicle_trajectories_vehicle_id ON vehicle_trajectories(vehicle_id);
|
||
CREATE INDEX IF NOT EXISTS idx_vehicle_trajectories_date ON vehicle_trajectories(trajectory_date DESC);
|
||
CREATE INDEX IF NOT EXISTS idx_vehicle_trajectories_start_time ON vehicle_trajectories(start_time DESC);
|
||
|
||
-- PostGIS轨迹空间索引
|
||
CREATE INDEX IF NOT EXISTS idx_vehicle_trajectories_line_gist ON vehicle_trajectories USING GIST(trajectory_line);
|
||
|
||
-- 复合索引
|
||
CREATE INDEX IF NOT EXISTS idx_vehicle_trajectories_compound ON vehicle_trajectories(vehicle_id, trajectory_date DESC);
|
||
|
||
-- ============================================
|
||
-- 4. 时间分区设置 (车辆位置表按月分区)
|
||
-- ============================================
|
||
|
||
-- 为车辆位置表创建按月分区
|
||
-- 注意:这需要在数据库中手动执行,Spring Boot JPA不会自动创建分区
|
||
|
||
-- 创建分区表函数 (示例,需要根据实际需求调整)
|
||
-- CREATE OR REPLACE FUNCTION create_monthly_partitions()
|
||
-- RETURNS void AS $$
|
||
-- DECLARE
|
||
-- start_date date;
|
||
-- end_date date;
|
||
-- table_name text;
|
||
-- BEGIN
|
||
-- FOR i IN 0..12 LOOP -- 创建未来12个月的分区
|
||
-- start_date := date_trunc('month', CURRENT_DATE + (i || ' month')::interval);
|
||
-- end_date := start_date + interval '1 month';
|
||
-- table_name := 'vehicle_locations_' || to_char(start_date, 'YYYY_MM');
|
||
--
|
||
-- EXECUTE format('CREATE TABLE IF NOT EXISTS %I PARTITION OF vehicle_locations
|
||
-- FOR VALUES FROM (%L) TO (%L)',
|
||
-- table_name, start_date, end_date);
|
||
-- END LOOP;
|
||
-- END;
|
||
-- $$ LANGUAGE plpgsql;
|
||
|
||
-- ============================================
|
||
-- 5. 触发器 (自动更新updated_at字段)
|
||
-- ============================================
|
||
|
||
-- 创建更新时间戳函数
|
||
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
||
RETURNS TRIGGER AS $$
|
||
BEGIN
|
||
NEW.updated_at = CURRENT_TIMESTAMP;
|
||
RETURN NEW;
|
||
END;
|
||
$$ LANGUAGE plpgsql;
|
||
|
||
-- 为车辆位置表创建触发器
|
||
CREATE TRIGGER trigger_vehicle_locations_updated_at
|
||
BEFORE UPDATE ON vehicle_locations
|
||
FOR EACH ROW
|
||
EXECUTE FUNCTION update_updated_at_column();
|
||
|
||
-- 为机场区域表创建触发器
|
||
CREATE TRIGGER trigger_airport_areas_updated_at
|
||
BEFORE UPDATE ON airport_areas
|
||
FOR EACH ROW
|
||
EXECUTE FUNCTION update_updated_at_column();
|
||
|
||
-- ============================================
|
||
-- 6. 数据清理策略 (可选)
|
||
-- ============================================
|
||
|
||
-- 创建历史数据清理函数 (保留30天数据)
|
||
CREATE OR REPLACE FUNCTION cleanup_old_vehicle_locations()
|
||
RETURNS INTEGER AS $$
|
||
DECLARE
|
||
deleted_count INTEGER;
|
||
BEGIN
|
||
DELETE FROM vehicle_locations
|
||
WHERE created_at < CURRENT_TIMESTAMP - INTERVAL '30 days';
|
||
|
||
GET DIAGNOSTICS deleted_count = ROW_COUNT;
|
||
|
||
-- 记录清理信息
|
||
RAISE NOTICE 'Cleaned up % old vehicle location records', deleted_count;
|
||
|
||
RETURN deleted_count;
|
||
END;
|
||
$$ LANGUAGE plpgsql;
|
||
|
||
-- ============================================
|
||
-- 7. 权限设置 (根据实际需求调整)
|
||
-- ============================================
|
||
|
||
-- 为应用用户赋予必要权限
|
||
-- GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO collision_avoidance_app;
|
||
-- GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO collision_avoidance_app;
|
||
|
||
-- ============================================
|
||
-- 8. 示例数据 (可选,用于测试)
|
||
-- ============================================
|
||
|
||
-- 插入示例机场区域
|
||
-- INSERT INTO airport_areas (area_id, name, type, boundary, priority, speed_limit_kph, enabled, allowed_vehicle_types) VALUES
|
||
-- ('runway_01', 'Runway 01', 'RUNWAY', ST_GeomFromText('POLYGON((116.5 39.8, 116.52 39.8, 116.52 39.81, 116.5 39.81, 116.5 39.8))', 4326), 10, 20.0, true, '["AIRCRAFT"]'),
|
||
-- ('taxiway_a', 'Taxiway A', 'TAXIWAY', ST_GeomFromText('POLYGON((116.51 39.79, 116.515 39.79, 116.515 39.795, 116.51 39.795, 116.51 39.79))', 4326), 5, 15.0, true, '["AIRCRAFT", "SPECIAL_VEHICLE"]'),
|
||
-- ('terminal_area', 'Terminal Area', 'TERMINAL', ST_GeomFromText('POLYGON((116.48 39.78, 116.50 39.78, 116.50 39.80, 116.48 39.80, 116.48 39.78))', 4326), 3, 10.0, true, '["SPECIAL_VEHICLE", "UNMANNED_VEHICLE"]');
|
||
|
||
-- 脚本完成
|
||
-- ============================================ |