
1) 【一句话结论】
针对船舶实时位置追踪系统,采用时间分片+多源数据一致性方案,设计主表(按船舶ID+时间复合主键)与按天分片表,结合复合索引(支持范围查询)和覆盖索引(减少回表I/O),通过乐观锁(版本号字段)实现并发控制,确保秒级写入与实时查询性能,同时保证多源数据最终一致性。
2) 【原理/概念讲解】
老师现在解释核心设计思路:首先,高并发写入(秒级更新)需要解决单表锁竞争问题,因此采用时间分片(按时间区间拆分表,如按天分片),将写入分散到多个分片,避免单表压力过大。实时查询需要快速定位数据,因此设计复合索引(如ship_id, position_time)支持范围查询,并使用覆盖索引(包含查询所需所有字段),减少回表I/O。多源数据(如GPS、北斗)的一致性处理,通过时间戳+版本号标记数据版本,先在临时表合并多源数据(解决冲突,如按时间戳最新优先),再同步到主表。并发控制采用乐观锁(版本号字段),写时检查版本,减少锁竞争,适合高并发读多写少场景。类比:时间分片像图书馆按年份分书架,避免所有书都在一个书架上找;覆盖索引像给书架贴标签,标签上有书名、作者,直接找到书,不用再翻书;乐观锁像假设书不会被别人动,先拿书,再检查是否被修改,没被修改就更新,否则重试。
3) 【对比与适用场景】
| 策略/方案 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 时间分片 | 按时间区间(如天/小时)拆分表 | 分散写入压力,提高并发写入性能 | 高频秒级更新场景(如船舶位置) | 需维护多个分片,查询时需路由匹配分片;分片过多可能导致查询时扫描大量分片 |
| 多源数据合并 | 多传感器数据(GPS、北斗等)先合并再写入 | 解决数据冲突(如时间戳、优先级),保证数据一致性 | 多源数据融合场景 | 需定义冲突处理规则(如时间戳最新优先、优先级机制),合并流程复杂 |
| 乐观锁(版本号) | 写时检查数据版本,假设无冲突 | 读写冲突少,性能高,减少锁竞争 | 高并发读多写少场景 | 需维护版本字段,写冲突时重试,版本字段需自增 |
| 悲观锁(行级锁) | 写时加锁,假设数据有冲突 | 写冲突少,但读锁影响读性能 | 写冲突频繁场景 | 需要锁资源,高并发下锁竞争严重,可能导致死锁 |
4) 【示例】
CREATE TABLE ship_position_main (
ship_id INT PRIMARY KEY,
position_time TIMESTAMP NOT NULL,
latitude DECIMAL(9,6),
longitude DECIMAL(9,6),
speed DECIMAL(5,2),
source_id INT,
version INT DEFAULT 1
);
分片表(按天分片,如20240501):
CREATE TABLE ship_position_20240501 (
ship_id INT,
position_time TIMESTAMP,
latitude DECIMAL(9,6),
longitude DECIMAL(9,6),
speed DECIMAL(5,2),
source_id INT,
version INT
);
def merge_multi_source(data_list):
# data_list: [(ship_id, time, lat, lon, speed, source_id), ...]
# 按ship_id和time排序,按时间戳最新优先合并
merged = sorted(data_list, key=lambda x: x[1], reverse=True)
# 去重,保留最新数据
result = []
seen = set()
for item in merged:
key = (item[0], item[1])
if key not in seen:
seen.add(key)
result.append(item)
return result
INSERT INTO ship_position_main (ship_id, position_time, latitude, longitude, speed, source_id, version)
VALUES ( ?, ?, ?, ?, ?, ?, ? )
ON DUPLICATE KEY UPDATE
latitude = VALUES(latitude),
longitude = VALUES(longitude),
speed = VALUES(speed),
source_id = VALUES(source_id),
version = version + 1;
UPDATE ship_position_main
SET latitude = ?, longitude = ?, speed = ?, source_id = ?, version = version + 1
WHERE ship_id = ? AND position_time = ? AND version = ?;
若更新行数为0,说明版本冲突,需重试。5) 【面试口播版答案】
“面试官您好,针对船舶实时位置追踪系统,我设计的核心方案是时间分片+多源数据一致性,具体来说:首先表结构上,主表按船舶ID+时间做复合主键,按天分片(如ship_position_20240501),避免单表秒级写入压力;然后索引用复合索引(ship_id, position_time)+ 覆盖索引(包含所有字段),确保实时查询秒级响应;并发控制用乐观锁(版本号字段),写时检查版本,减少锁竞争;多源数据一致性通过时间戳标记版本,先合并再同步主表,保证最终一致性。这样既能应对高并发写入,又能支持实时查询。”(约80秒)
6) 【追问清单】
7) 【常见坑/雷区】