文档一

152 阅读4分钟

1. 需求概述

为航空公司设计一个调度系统,支持根据时间范围选定飞机ID生成甘特图,展示飞机的行程计划。
核心功能

  • 高效存储与查询航班数据。
  • 动态生成甘特图,支持分钟级时间精度。
  • 支持大规模数据(如10,000+飞机)。

2. 系统架构

flowchart TD
    A[前端] -->|HTTP请求| B(API网关)
    B --> C[查询服务]
    C --> D[(数据库)]
    D --> C
    C -->|JSON数据| E[甘特图渲染引擎]
    E --> A

3. 技术选型与权衡

3.1 数据库选型
选项优点缺点
PostgreSQLACID事务支持,时间范围查询优化(BRIN索引)。需要手动分区,扩展性依赖集群方案。
TimescaleDB内置时间序列优化,自动分区。对非时间字段查询性能一般。
MongoDB灵活模式,水平扩展容易。复杂查询(如多飞机时间范围)效率较低。
最终选择PostgreSQL
  • 理由

    1. 航班数据为强结构化(飞机ID、时间、航线)。
    2. 时间范围查询频繁,可通过tsrange字段和BRIN索引优化。
    3. 支持事务,避免数据不一致(如航班时间冲突)。

3.2 API设计
  • REST API

    • 端点GET /api/trips?plane_ids=PlaneA,PlaneB&start=2024-01-02T00:00&end=2024-01-02T23:59
    • 优点:简单易用,支持缓存。
  • GraphQL

    • 优点:灵活查询,减少冗余数据传输。
    • 缺点:需维护Schema,缓存复杂度高。

最终选择REST API

  • 理由:查询参数固定(时间范围+飞机ID),无需灵活字段选择。
  • 3.3 前端甘特图渲染
适用场景
ECharts支持复杂甘特图,内置时间轴与交互功能。
D3.js完全定制化,但开发成本高。
ApexCharts轻量级,但甘特图功能较弱。

最终选择ECharts 关键配置

javascript

复制

option = {
  xAxis: { type: 'time' },
  yAxis: { data: ['PlaneA', 'PlaneB'] },
  series: [{
    type: 'bar',
    data: [
      { name: 'HKG-NRT', start: '2024-01-02 01:25', end: '2024-01-02 05:55' }
    ]
  }]
}

4. 数据模型设计

4.1 数据库表结构
-- 飞机元数据表
CREATE TABLE planes (
    plane_id VARCHAR(10) PRIMARY KEY,
    model VARCHAR(50) NOT NULL,
    capacity INT
);

-- 航班行程表(关键表)
CREATE TABLE trips (
    trip_id BIGSERIAL PRIMARY KEY,
    plane_id VARCHAR(10) REFERENCES planes(plane_id),
    route VARCHAR(50) NOT NULL,  -- 航线(如HKG-NRT)
    departure TIMESTAMPTZ NOT NULL,  -- 起飞时间(UTC)
    arrival TIMESTAMPTZ NOT NULL     -- 到达时间(UTC)
);

-- 索引优化
CREATE INDEX idx_trips_plane_time ON trips (plane_id, departure);
CREATE INDEX idx_trips_departure_brin ON trips USING BRIN (departure);
4.2 数据示例
plane_idroutedeparture (UTC)arrival (UTC)
PlaneAHKG-NRT2024-01-02 01:25:002024-01-02 05:55:00
PlaneANRT-TPE2024-01-02 08:39:002024-01-02 12:29:00

5. 查询优化策略

5.1 高效查询SQL
SELECT plane_id, route, departure, arrival 
FROM trips 
WHERE plane_id IN ('PlaneA', 'PlaneB') 
AND departure >= '2024-01-02T00:00:00Z' 
AND arrival <= '2024-01-02T23:59:59Z'
ORDER BY departure;
5.2 性能保障
  1. 分区策略:按月份对trips表分区,减少单表数据量。
  2. 缓存层:使用Redis缓存高频查询结果(如当天热门航班)。
  3. 批量预加载:每日凌晨预生成次日航班数据快照。

6. 甘特图数据格式

{
  "PlaneA": [
    {
      "route": "HKG-NRT",
      "start": "01-02 01:25",
      "end": "01-02 05:55",
      "duration_minutes": 270
    }
  ],
  "PlaneB": [...]
}

7. 扩展性与风险控制

7.1 扩展性设计
  • 水平扩展

    • 数据库:使用Citus扩展PostgreSQL为分布式集群。
    • 服务层:无状态查询服务,支持Kubernetes动态扩缩容。
7.2 风险与应对
风险应对措施
时间范围查询慢BRIN索引 + 分区表。
前端渲染卡顿虚拟滚动 + 分页加载(如只渲染24小时)。
时区显示错误存储UTC时间,前端按用户时区转换。

8. 讨论点

  1. 实时性需求:是否需要支持航班延误实时更新甘特图?

    • 若需要,可引入WebSocket推送变更。
  2. 数据规模:预估每日新增航班量级?

    • 若超百万条/日,需采用分布式数据库。
  3. 安全合规:是否需加密存储敏感数据(如机组信息)?

附录

  1. Mermaid甘特图示例(见用户输入)。
  2. API请求/响应示例
# Request
GET /api/trips?plane_ids=PlaneA,PlaneB&start=2024-01-02T00:00Z&end=2024-01-02T23:59Z

# Response
HTTP 200 OK
{
  "PlaneA": [...],
  "PlaneB": [...]
}