CollisionAvoidanceSystem/src/main/resources/sql/create_tables.sql
Tian jianyong 05e080cb30 1. 创建车辆位置PostGIS实体类(VehicleLocation、Aircraft、VehicleTrajectory)
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. 创建单元测试和集成测试
2025-06-10 18:45:54 +08:00

237 lines
9.4 KiB
PL/PgSQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- ============================================
-- 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"]');
-- 脚本完成
-- ============================================