Files
lingniu-vehicle-ingest/docs/vehicle-data-platform-data-model.md

16 KiB
Raw Permalink Blame History

车辆数据中台一期数据模型

1. 数据职责原则

存储 负责 不负责
Redis DB 50 最新状态、在线 TTL、字段级当前值、热查询缓存 历史事实、告警事件、规则、导出任务
TDengine lingniu_vehicle_ts 高频 RAW 证据、位置/稳定时序历史 车辆档案、权限、工作流状态
MySQL lingniu_vehicle_data 车辆主数据、身份映射、接入配置、当前业务投影、统计、规则、事件、通知、导出任务 每帧完整历史和无限增长的遥测明细

统一业务主键为 VIN。车牌、JT808 手机号、设备号、平台标识只是可变标识,通过映射解析到 VIN无法解析 VIN 的数据仍留 RAW/接入排障,不进入正式车辆统计。

2. 当前 TDengine 模型

2.1 raw_frames stable

列:ts, frame_id, event_id, message_id, event_time, received_at, raw_size_bytes, raw_hex, raw_text, parsed_json, parse_status, parse_error, source_endpoint

Tagsprotocol, vehicle_key, vin, phone, device_id

用途:证明收到什么、何时收到、解析成什么。parsed_json 物理列保存 Gateway 已一次扁平化的 parsed_fields,是动态协议字段的历史证据。新字段默认先进入这里,不为每个厂家字段立即新增物理列。

2.2 raw_frame_payload_chunks stable

列:事件/帧、接收时间、payload 类型、分片序号/总数、分片文本Tags 与 RAW 身份类似。

用途:保存超过主表列长度的 raw/parsed payload不参与常规业务查询。

2.3 vehicle_locations stable

列:ts, event_id, received_at, longitude, latitude, altitude_m, speed_kmh, direction_deg, alarm_flag, status_flag, total_mileage_km

Tagsprotocol, vin

用途VIN 非空车辆的高频位置、速度、方向、告警/状态位、总里程历史。当前平台 DTO 尚未完整透出方向、告警和状态位,也没有 SOC 列;轨迹一期需先补 DTO/查询SOC 可从 RAW 指标取值或按验证后的需求物化。

数据库当前配置 KEEP 7300 DURATION 10 BUFFER 256。保留期和磁盘容量应纳入运维监控,不在业务页面查询时临时改变。

3. 当前 Redis 模型

Key 值/用途 约束
vehicle:latest:{vin} 跨协议最新核心字段 仅 VIN 非空;轻量快照
vehicle:latest:{vin}:{protocol} 单协议最新核心字段 可过期/重建
vehicle:realtime-raw:{protocol}:{vin} 单协议最新完整 parsed 状态 Redis 中完整协议字段唯一副本
vehicle:rt-kv:{protocol}:{vin}:values 扁平字段当前值 与类型/时间/meta 配套
...:types 字段值类型 支持动态展示和规则类型校验的实时侧依据
...:times 每字段最新归一事件时间 防止乱序旧帧覆盖
...:meta 最新事件/接收时间、映射版本 用于新鲜度和追踪
vehicle:online:{protocol}:{vin} TTL 在线状态 在线事实的快速判断,不应永久保存
vehicle:online-state:{protocol}:{vin} 可分页的 Hash 副本 用于在线列表
vehicle:protocols:{vin} 最近出现协议集合 车辆来源发现
vehicle:last_seen 最近活跃车辆 ZSET 分页/排序候选

生产只允许 nats-fast-writer 写 Redis 当前态Kafka 慢链路的 realtime writer 不应覆盖快路径。在线产品状态应由“最新时间 + 配置阈值”计算并返回阈值/依据,不能只信一个固定 Boolean。

4. 当前 MySQL 模型

4.1 身份与档案

主键/关键字段 用途
vehicle vinplate, oem, enabled, updated_at 轻量车辆主实体;当前字段不足一期完整档案
vehicle_identifier (protocol, source_code, identifier_type, identifier_value)VIN/车牌/OEM 多协议、多来源、多标识解析到 VIN
vehicle_identity_binding VIN车牌、phone、OEM 外部维护的兼容映射事实,运行期只读
jt808_registration phonedevice、plate、VIN、厂家、鉴权、来源、首次/最近注册鉴权/出现时间 JT808 注册鉴权与绑定证据

4.2 当前态与来源

主键/关键字段 用途
vehicle_realtime_snapshot (protocol, vin)plate、platform、peer、扁平 parsed_json、event/received time 每协议每 VIN 最新合并遥测快照
vehicle_realtime_location (protocol, vin)经纬度、速度、总里程、SOC、海拔、方向、alarm/status、event/received time 每协议每 VIN 最新位置业务缓存
vehicle_data_source 自增 ID唯一 (protocol, source_ip)source code/kind、platform、priority、enabled、first/latest seen 数据来源配置和可信源选择

4.3 日里程

主键/关键字段 用途
vehicle_daily_mileage_source (vin, stat_date, protocol, source_key);首末里程、样本、质量、是否选中 多来源日里程事实和质量解释
vehicle_daily_mileage (vin, stat_date, protocol)source ID、日里程、最新总里程 对外查询结果投影

当前明确不存在/不应恢复的旧模型包括泛化 vehicle_daily_metric、TDengine vehicle_mileage_pointsraw_frames.fields_json 重复列。

5. 一期统一领域模型

5.1 车辆标识

VehicleId          = VIN内部规范化大写、去空格
VehicleIdentifier  = protocol + sourceCode + type + value -> VIN
Plate              = 可变展示标识,不作为跨表唯一主键
Source             = protocol + sourceCode/sourceId + endpoint

所有 API 都以 VIN 作为详情路径主键搜索接口可接受车牌、VIN、车辆编号/手机号并返回解析结果。多协议数据保留 protocolsourceId 做归因,不能在合并时丢失来源。

5.2 时间模型

  • eventTime:车端/协议事件时间,是轨迹、曲线和告警判断的主要时间。
  • receivedAt:平台接收时间,用于延迟、迟到数据和链路健康。
  • storedAt/updatedAt:投影或业务记录更新时间,不冒充车辆上报时间。
  • dataDelaySec = receivedAt - eventTimesilenceSec = now - max(receivedAt/eventTime 的已确认口径)

5.3 在线状态

never_reported: 无任何 latestReceivedAt
online:         silenceSec <= thresholdSec
offline:        silenceSec > thresholdSec
unknown:        时间非法、未来时间过大或来源状态无法判断

行驶/静止是独立 motion 状态,建议以速度阈值 + 最近更新时间判断;告警也是独立状态。不要把 online/running/alarm 压成一个互斥枚举UI 可基于多维状态决定主色和徽标。

5.4 指标值

MetricValue {
  vehicleId, metricKey, value, valueType, unit,
  eventTime, receivedAt, protocol, sourceId,
  quality, mappingVersion
}

metricKey 是协议无关的规范键;协议原字段通过映射表关联。厂家扩展字段允许命名空间,但必须有显示名、类型、分类和单位后才可进入图表/告警。

6. 建议新增 MySQL 模型

6.1 档案与组织

建议优先用关联表而非不断扩宽 vehicle

  • vehicle_profile(vin PK, vehicle_no, model_id, vehicle_type, company_id, operation_status, access_vendor_id, first_access_at, ...)
  • vehicle_model(id, oem_id, code, name, vehicle_type, ...)
  • organization(id, parent_id, type, code, name, enabled, ...)
  • access_vendor(id, code, name, enabled, ...)

外部主数据通过受控同步写入 source_system/source_version/synced_at。默认策略保护 manual 和其他外部来源;只有管理员显式选择 takeover 才能改变所有权。同一来源版本相同载荷幂等,不同载荷冲突,避免上游版本不可变性被破坏;每次创建/更新都进入 vehicle_profile_audit

6.2 指标目录

  • metric_definition(metric_key PK, display_name, category, value_type, unit, precision, chartable, alertable, enabled, sort_order, version)
  • metric_protocol_mapping(metric_key, protocol, source_field, transform, mapping_version, enabled)

transform 不能存任意可执行代码;使用有限转换类型或由版本化 Go 映射实现。目录服务可缓存,变更有版本和审计。

6.3 告警域

  • alert_rule(id, name, description, metric_key, operator, threshold_json, severity, duration_sec, recovery_json, repeat_interval_sec, enabled, version, created_by, updated_by, timestamps)
  • alert_rule_scope(rule_id, scope_type, scope_value)vehicle/model/oem/protocol/company一期可限制组合复杂度。
  • alert_event(id, rule_id, rule_version, vin, protocol, source_id, status, trigger_value_json, threshold_json, first_triggered_at, last_triggered_at, recovered_at, closed_at, location_json, dedupe_key, assignee, timestamps)
  • alert_event_action(id, event_id, action, from_status, to_status, operator_id, note, created_at)
  • notification(id, user_id, event_id, title, body, read_at, created_at)

alert_event.dedupe_key 建唯一约束或等价幂等机制;阈值快照和 rule version 必须保存在事件上,避免规则修改后历史无法解释。

当前实现使用带业务前缀的实体表,完整 DDL 位于 vehicle-data-platform/deploy/migrations/002_alert_center.sql

  • vehicle_alert_rule + vehicle_alert_rule_audit:当前规则与每版本不可变快照。
  • vehicle_alert_candidate(rule_id, vin, protocol) 持续命中计时,避免单帧达到阈值就误开事件。
  • vehicle_alert_stream_checkpoint(consumer_group, topic, partition_id) 保存数据库权威 next_offset、Kafka high watermark、处理/非法/迟到/回放计数、最近事件证据以及最近非法代码/时间。流 worker 先提交该事务,再提交 Kafka group offset崩溃后重复抓取的 offset 会被数据库 checkpoint 跳过。累计非法数用于审计,健康状态只对五分钟内仍在发生的非法消息告警。
  • vehicle_alert_event:保存规则名/版本、触发阈值快照、证据时间、位置和乐观锁版本;fingerprint + active status 用于评估器幂等检查。
  • vehicle_alert_event_action:触发、恢复和人工处置的不可变时间线。
  • vehicle_alert_notification:站内通知真实已读状态;外部通道只有 reserved,没有配置供应商时绝不标记 sent
  • vehicle_alert_rule_state:为 Boolean changed 规则保存每个 rule/VIN/protocol 的最近观测值;003 同时增加区间上限和 OEM 范围,004 为 fingerprint 重复间隔查询增加索引。

一期 evaluator 读取 vehicle_realtime_location 的当前快照并用 candidate 表证明持续时长。除 freshness_sec 明确按平台墙钟增长外,候选只允许由不同 source_event_id 且事件时间不回退的新观测推进;重复快照不能制造持续时长,迟到观测不能回退 candidate 或 Boolean 状态。规则行会在评估事务内加锁,停用规则、清理 candidate/Boolean 状态和写版本审计在同一事务提交,从而避免 evaluator 与管理员停用并发后留下幽灵候选。它仍不是 Kafka event-time 可重放评估器,因此跨当前快照的迟到数据重算、历史窗口规则和消费 offset 仍是阶段 8 的后续能力。

alert-stream-evaluator 已以 active 模式消费三类 canonical fields topic。它复用 Kafka consumer group 的分区顺序,校验 event_kind/field_mapping/protocol/VIN/source_event_id/字段命名空间,用接收时间识别超过可配置窗口的迟到观测。动态规则锁、当前批次范围内的 candidate/Boolean/活跃事件/重复窗口、事件/动作/通知副作用和 checkpoint 在同一个 MySQL 事务内完成,成功后才 commit Kafka数据库 ahead 时的重复 offset 由 checkpoint 跳过。超过迟到窗口的观测只允许驱动 data_delay_sec,不能开关速度/SOC/告警位事件。快照 evaluator 在 active 模式只负责按墙钟增长的 freshness_sec,不再读取动态规则。

6.4 导出域

  • export_job(id, user_id, type, format, query_json, status, progress, estimated_rows, exported_rows, file_uri, file_size, checksum, error_code, error_message, started_at, completed_at, expires_at, created_at)

索引至少覆盖 (user_id, created_at)(status, created_at) 和过期清理。query_json 保存规范化查询快照,不保存数据库密码或签名下载 URL。

6.5 在线阈值与审计

  • online_threshold(scope_type, scope_value, threshold_sec, version, updated_by, updated_at),一期建议 scope 仅 global/protocol。
  • audit_log(id, actor, action, resource_type, resource_id, before_json, after_json, trace_id, created_at)

当前 V2 接入管理已先落地等价的窄表:

  • vehicle_access_threshold_config(id=1, version, default_threshold_sec, delay_threshold_sec, long_offline_sec, protocol_overrides_json, updated_by, updated_at)
  • vehicle_access_threshold_audit(id, version, actor, summary, config_json, changed_at)

表仅向前新增,不改变 gateway 的 vehicle_realtime_snapshot(protocol, vin) 主键与写入语义。后续统一审计域上线时可迁移到通用 audit_log,但必须保留版本历史。

7. 查询与物化策略

  1. 实时页面优先 RedisMySQL realtime 作为业务查询/降级投影;返回值统一由 BFF 归一化。
  2. 轨迹只查 TDengine vehicle_locations,必要的 SOC/告警补充应避免对每个点逐条回查 RAW先验证是否需要将 SOC 提升为位置列或建立专用指标 stable。
  3. 通用历史指标首版可从 raw_frames.parsed_json 按白名单提取,但必须限制车辆数、指标数、时间范围并做基准;高频稳定指标按实际查询热度物化为专用时序模型。
  4. 档案和字典在 BFF/Redis 做版本化短缓存,避免每次实时请求重复查不变数据。
  5. 地图聚合可从 MySQL realtime/Redis 快照构建短周期服务端缓存;不要把地理历史查询压到实时表,也不要把全量点放浏览器聚合。
  6. 告警 worker 使用 Kafka 可重放流和 eventTimeMySQL 保存工作流事实Redis 可保存短期去重/规则缓存但不是唯一事实。

8. 数据质量与治理要求

  • 数值同时记录单位和精度;未知单位不得参与跨协议比较或规则判断。
  • 原始值、规范值和转换版本可追踪;异常值标记不直接篡改 RAW。
  • 未来时间、经纬度越界、速度突变、里程回退、重复事件均定义质量码。
  • 轨迹过滤返回算法版本、原始/过滤/抽稀数量,可选择查看未过滤证据。
  • 协议新增字段先进入扁平 RAW + Redis KV经目录登记后才进入 UI形成稳定高频查询后再物化。
  • 所有新增表、字段、索引、保留期和清理任务随 migration 与数据字典发布。

9. 容量和保留

  • 约 1,000 到 10,000 车辆、530 秒上报意味着时序写入持续增长TDengine 查询必须带 VIN/时间,禁止开放无界扫描。
  • RAW 保留期、位置保留期、导出文件保留期和告警/审计保留期分别配置,不能共用一个默认值。
  • MySQL 告警事件和审计按时间索引并规划归档;导出任务定时过期,文件删除和 DB 状态更新需幂等。
  • 单 ECS 上告警和导出 worker 设置独立并发、内存、CPU 和 systemd 限制,避免影响接入写链路。

10. 仍需确认的数据问题

  1. vehicle_identity_binding 的实际 DDL、权威维护方和未来是否继续兼容。
  2. 车型、车辆类型、运营公司、车辆编号、运营状态、接入厂家的权威来源与更新频率。
  3. 各协议 SOC、方向、启动、告警等级、电机/燃料电池等规范字段映射和单位。
  4. “累计运行时长”是已有车端字段、由状态积分计算,还是一期可不提供。
  5. 在线时间基准使用 eventTime 还是 receivedAt以及不同协议的默认阈值。
  6. 轨迹停车阈值、漂移判定、迟到点容忍和跨协议主轨迹选择规则。
  7. 导出存储与保留期、单用户并发/最大行数。
  8. 告警规则适用范围组合、迟到窗口、重复/恢复语义和事件归属人规则。