
1) 【一句话结论】:针对港口多源异构数据(结构化、时间序列、非结构化),采用关系型(管理主数据)、时序(存储时间序列位置)、文档型(处理非结构化报关)的混合数据库架构,通过CDC捕获变更、ETL同步数据、动态地理距离校验,确保数据一致性误差率<0.1%。
2) 【原理/概念讲解】:港口业务涉及船舶、货物、设备、报关等多源数据,数据类型差异大。关系型数据库(如MySQL)适合管理结构化主数据(如船舶ID、堆场位置),通过主键(唯一标识)和外键(关联表)保证数据一致性,类比港口的“主数据字典”,所有系统通过主键关联。时序数据库(如InfluxDB)专为时间序列数据设计,支持高并发写入和按时间查询(如船舶位置按时间点记录),像“船舶位置的时间轨迹录像”,按时间索引位置变化。文档型数据库(如MongoDB)灵活存储半结构化/非结构化数据(如报关单文本),字段不固定,像“报关单的文本档案”,支持全文搜索。混合架构通过各数据库特性互补,满足不同数据类型的需求。
3) 【对比与适用场景】:
| 数据库类型 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 关系型(MySQL) | 结构化数据,表间通过外键关联 | ACID事务,强一致性,支持复杂JOIN查询 | 船舶、堆场、货物等主数据管理,关联查询(如船舶位置与货物位置关联) | 写入性能一般,不适合高并发时间序列数据 |
| 时序数据库(InfluxDB) | 专为时间序列数据设计 | 高写入吞吐,时间索引,支持聚合查询 | 船舶位置、设备传感器数据(时间序列,如GPS坐标随时间变化) | 不适合结构化查询,索引简单 |
| 文档型(MongoDB) | 半结构化/非结构化数据,文档存储 | 灵活字段,无模式强制,支持全文搜索 | 报关单文本、设备日志(非结构化,字段不固定) | 不支持复杂JOIN,查询性能依赖索引 |
4) 【示例】:
关系型表(MySQL):
-- 船舶表(主数据)
CREATE TABLE ship (
ship_id INT PRIMARY KEY,
name VARCHAR(50),
type VARCHAR(20)
);
-- 堆场表
CREATE TABLE yard (
yard_id INT PRIMARY KEY,
location VARCHAR(100)
);
-- 货物表(关联船舶与堆场,含版本号控制冲突)
CREATE TABLE cargo (
cargo_id INT PRIMARY KEY,
ship_id INT,
yard_id INT,
status VARCHAR(20),
version INT DEFAULT 1,
FOREIGN KEY (ship_id) REFERENCES ship(ship_id),
FOREIGN KEY (yard_id) REFERENCES yard(yard_id)
);
-- 货物位置历史表(支持追溯)
CREATE TABLE cargo_position_history (
history_id INT PRIMARY KEY,
cargo_id INT,
yard_id INT,
position_lat DECIMAL(9,6),
position_lon DECIMAL(9,6),
timestamp DATETIME,
FOREIGN KEY (cargo_id) REFERENCES cargo(cargo_id)
);
时序表(InfluxDB):
CREATE MEASUREMENT ship_position
TAGS (ship_id)
FIELDs (latitude, longitude, timestamp)
文档型表(MongoDB):
CREATE COLLECTION customs_bill
INDEX ON customs_bill(cargo_id, created_at)
数据同步(ETL):
实时流:从AIS系统拉取船舶位置,通过Kafka写入InfluxDB。
def stream_ship_position():
consumer = KafkaConsumer('ais_topic', bootstrap_servers='kafka:9092')
for msg in consumer:
data = json.loads(msg.value)
insert_into_influxdb('ship_position', data)
定时任务:从货物管理系统同步货物位置,更新关系型表和历史表。
def sync_cargo_position():
cargo_data = fetch_from_cargo_system()
for cargo in cargo_data:
with transaction(): # 分布式事务
cargo_id = cargo['cargo_id']
new_yard_id = cargo['yard_id']
current_version = get_version(cargo_id)
if current_version != expected_version:
raise ConflictError("数据已被其他系统更新")
update_cargo(cargo_id, new_yard_id, current_version + 1)
insert_history(cargo_id, new_yard_id, cargo['position_lat'], cargo['position_lon'], now())
数据冲突处理:
version字段,更新时检查版本是否匹配,不匹配则回滚。数据校验:
def calculate_distance(lat1, lon1, lat2, lon2):
R = 6371 # 地球半径(公里)
dlat = radians(lat2 - lat1)
dlon = radians(lon2 - lon1)
a = sin(dlat/2)**2 + cos(radians(lat1)) * cos(radians(lat2)) * sin(dlon/2)**2
c = 2 * asin(sqrt(a))
return R * c
5) 【面试口播版答案】:面试官您好,针对港口多源异构数据,我建议采用关系型、时序、文档型数据库的混合架构。关系型数据库(如MySQL)管理船舶、堆场、货物的结构化主数据,通过主键(如ship_id)和外键(如cargo.ship_id关联ship表)保证数据一致性;时序数据库(如InfluxDB)存储船舶位置等时间序列数据,支持按时间查询位置变化;文档型数据库(如MongoDB)处理报关单等非结构化数据。数据同步通过CDC捕获变更,实时从AIS系统拉取船舶位置写入时序表,定时从货物管理系统同步货物位置更新关系型表和历史表。为保证数据准确性,货物位置与船舶位置关联时,通过地理距离计算(Haversine公式)验证,动态调整误差阈值(如集装箱0.1公里),误差率控制在0.1%以内,确保数据一致性。
6) 【追问清单】:
version字段,更新时检查版本是否匹配,不匹配则回滚;对于低延迟要求,采用事件溯源(最终一致性),记录操作日志,异步处理。ship_id分片),结合批量写入(batch write),减少写入延迟,同时利用时间索引加速查询。cargo(ship_id, yard_id)),时序数据库按时间窗口聚合查询(如ship_position按小时聚合),文档型数据库对常用字段建立索引(如cargo_id、created_at),减少查询延迟。7) 【常见坑/雷区】: