QDAirPortBackend0122/doc/work/车辆ID映射解决方案_20250115.md
2026-01-22 13:19:47 +08:00

222 lines
5.8 KiB
Markdown
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.

# 车辆ID映射问题解决方案
## 问题描述
在数据库合并过程中发现了车辆标识符不一致的问题:
- **QAUP-Management**: `sys_vehicle_info.vehicle_id` = 自增数字ID主键
- **CollisionAvoidanceSystem**: `vehicle_locations.vehicle_id` = 车牌号(字符串)
这导致两个系统的车辆数据无法正确关联。
## 解决方案对比
### 🥇 方案一:优化表结构(推荐)
**特点**
- ✅ 保持数据完整性
- ✅ 支持双重关联方式
- ✅ 语义清晰,便于维护
- ⚠️ 需要修改表结构
**实施**
```bash
# 执行修复脚本
psql -h localhost -U postgres -d qaup -f sql/fix_vehicle_id_mapping.sql
```
**优势**
- 添加`license_plate`字段明确语义
- 添加`sys_vehicle_id`字段支持数字ID关联
- 更新所有相关视图使用正确的关联逻辑
- 提供数据同步函数
### 🥈 方案二:视图层解决(简单)
**特点**
- ✅ 不修改表结构
- ✅ 实施简单快速
- ⚠️ 依赖视图查询,性能稍逊
- ⚠️ 需要确保车牌号唯一性
**关联逻辑**
```sql
-- 通过车牌号关联
SELECT vi.*, vl.location, vl.speed
FROM sys_vehicle_info vi
LEFT JOIN vehicle_locations vl ON vl.vehicle_id = vi.license_plate_number;
```
### 🥉 方案三:应用层处理(灵活)
**特点**
- ✅ 数据库保持原样
- ✅ 灵活的映射逻辑
- ⚠️ 增加应用复杂性
- ⚠️ 性能开销相对较大
**实现方式**
- 在应用层维护车牌号到数字ID的映射关系
- 通过缓存提高查询性能
## 推荐方案详解
### 方案一实施后的效果
#### 1. 表结构变化
```sql
-- vehicle_locations表新增字段
ALTER TABLE vehicle_locations ADD COLUMN license_plate VARCHAR(50); -- 车牌号
ALTER TABLE vehicle_locations ADD COLUMN sys_vehicle_id BIGINT; -- 系统车辆ID
```
#### 2. 数据关联方式
```sql
-- 方式1通过车牌号关联主要方式
SELECT * FROM vehicle_complete_info WHERE license_plate_number = '京A12345';
-- 方式2通过数字ID关联可选
SELECT * FROM sys_vehicle_info vi
JOIN vehicle_locations vl ON vl.sys_vehicle_id = vi.vehicle_id;
```
#### 3. 新增业务视图
**vehicle_info_with_location**:车辆信息与位置
```sql
SELECT sys_vehicle_id, vehicle_plate, brand, longitude, latitude, status
FROM vehicle_info_with_location
WHERE vehicle_plate = '京A12345';
```
**vehicle_trajectory_view**:车辆轨迹
```sql
SELECT vehicle_plate, trajectory_date, total_distance
FROM vehicle_trajectory_view
WHERE vehicle_plate = '京A12345';
```
## 执行步骤
### 立即执行(推荐)
1. **备份数据**(重要)
```bash
pg_dump -h localhost -U postgres -d qaup > backup_before_fix_$(date +%Y%m%d_%H%M%S).sql
```
2. **执行修复脚本**
```bash
psql -h localhost -U postgres -d qaup -f sql/fix_vehicle_id_mapping.sql
```
3. **验证结果**
```sql
-- 检查新字段
\d vehicle_locations
-- 测试视图
SELECT * FROM vehicle_complete_info LIMIT 5;
-- 检查数据同步
SELECT COUNT(*) as total, COUNT(license_plate) as has_plate
FROM vehicle_locations;
```
### 如果选择其他方案
#### 方案二:仅更新视图
```sql
-- 只更新现有视图的关联逻辑
DROP VIEW IF EXISTS vehicle_complete_info;
CREATE OR REPLACE VIEW vehicle_complete_info AS
SELECT vi.*, vl.location, vl.speed, vl.timestamp
FROM sys_vehicle_info vi
LEFT JOIN LATERAL (
SELECT * FROM vehicle_locations
WHERE vehicle_id = vi.license_plate_number
ORDER BY timestamp DESC LIMIT 1
) vl ON true;
```
#### 方案三:应用层映射
```java
// 在应用代码中处理映射
@Service
public class VehicleMappingService {
public String getPlateById(Long vehicleId) {
// 从sys_vehicle_info查询车牌号
}
public Long getIdByPlate(String licensePlate) {
// 从sys_vehicle_info查询车辆ID
}
}
```
## 使用建议
### 开发中的最佳实践
1. **统一使用车牌号作为业务标识符**
```sql
-- 推荐:使用车牌号查询
SELECT * FROM vehicle_info_with_location WHERE vehicle_plate = '京A12345';
```
2. **数据插入时同时设置两个字段**
```sql
INSERT INTO vehicle_locations (vehicle_id, license_plate, sys_vehicle_id, ...)
VALUES ('京A12345', '京A12345', 1001, ...);
```
3. **定期执行数据同步**
```sql
-- 如果有新的车辆信息录入,执行同步
SELECT update_sys_vehicle_id();
```
### 查询性能优化
```sql
-- 利用新建的索引
CREATE INDEX idx_vehicle_locations_license_plate ON vehicle_locations(license_plate);
CREATE INDEX idx_vehicle_locations_sys_vehicle_id ON vehicle_locations(sys_vehicle_id);
```
## 常见问题解答
### Q1: 为什么推荐方案一?
- **数据完整性**:支持严格的外键约束
- **查询性能**:专用索引优化
- **语义清晰**:字段名明确表达用途
- **向后兼容**保留原有的vehicle_id字段
### Q2: 原有代码需要修改吗?
- **CollisionAvoidanceSystem**不需要修改继续使用vehicle_id字段
- **QAUP-Management**:建议使用新的视图进行查询
- **新功能开发**推荐使用license_plate字段
### Q3: 如果车牌号有重复怎么办?
- 在sys_vehicle_info表上添加唯一约束
```sql
ALTER TABLE sys_vehicle_info ADD CONSTRAINT uk_license_plate
UNIQUE (license_plate_number);
```
### Q4: 数据迁移会丢失吗?
- 不会脚本使用ADD COLUMN IF NOT EXISTS确保安全
- 现有数据会自动复制到新字段
- 建议执行前先备份
## 总结
推荐立即执行**方案一**的修复脚本,这将:
- ✅ 彻底解决车辆ID映射问题
- ✅ 提供多种查询方式
- ✅ 保持系统兼容性
- ✅ 优化查询性能
执行命令:
```bash
psql -h localhost -U postgres -d qaup -f sql/fix_vehicle_id_mapping.sql
```