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 数据库选型
| 选项 | 优点 | 缺点 |
|---|---|---|
| PostgreSQL | ACID事务支持,时间范围查询优化(BRIN索引)。 | 需要手动分区,扩展性依赖集群方案。 |
| TimescaleDB | 内置时间序列优化,自动分区。 | 对非时间字段查询性能一般。 |
| MongoDB | 灵活模式,水平扩展容易。 | 复杂查询(如多飞机时间范围)效率较低。 |
| 最终选择:PostgreSQL |
-
理由:
- 航班数据为强结构化(飞机ID、时间、航线)。
- 时间范围查询频繁,可通过
tsrange字段和BRIN索引优化。 - 支持事务,避免数据不一致(如航班时间冲突)。
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_id | route | departure (UTC) | arrival (UTC) |
|---|---|---|---|
| PlaneA | HKG-NRT | 2024-01-02 01:25:00 | 2024-01-02 05:55:00 |
| PlaneA | NRT-TPE | 2024-01-02 08:39:00 | 2024-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 性能保障
- 分区策略:按月份对
trips表分区,减少单表数据量。 - 缓存层:使用Redis缓存高频查询结果(如当天热门航班)。
- 批量预加载:每日凌晨预生成次日航班数据快照。
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. 讨论点
-
实时性需求:是否需要支持航班延误实时更新甘特图?
- 若需要,可引入WebSocket推送变更。
-
数据规模:预估每日新增航班量级?
- 若超百万条/日,需采用分布式数据库。
-
安全合规:是否需加密存储敏感数据(如机组信息)?
附录:
- Mermaid甘特图示例(见用户输入)。
- 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": [...]
}