他的回复:
这类数据适合用 ClickHouse 做“明细日志 + 聚合分析”,但不建议把实时在场状态和频繁更新/删除也交给它。比较稳妥的拆分是:ClickHouse 存进出明细、Redis 或业务库存当前在场状态、物化视图存分钟/小时统计。1)明细表设计CREATE TABLE parking_gate_events( event_id UUID, event_time DateTime64(3, 'Asia/Shanghai'), lot_id UInt32, gate_id LowCardinality(String), lane_id UInt16, plate_hash FixedString(16), event_type LowCardinality(String), confidence Float32, source LowCardinality(String), version UInt64 DEFAULT toUnixTimestamp64Milli(event_time), INDEX idx_plate_hash plate_hash TYPE bloom_filter(0.01) GRANULARITY 4)ENGINE = ReplacingMergeTree(version)PARTITION BY toYYYYMM(event_time)ORDER BY (lot_id, event_time, gate_id, plate_hash)TTL event_time + INTERVAL 24 MONTH;设计要点:- 车辆进出是典型的追加型事件,MergeTree 比行式数据库更适合;按车场和时间做排序键,能直接服务“某车场某时间段”的主查询。- 车牌号不要明文入库。建议统一车牌格式后做加盐 HMAC,取前 16 字节存成 plate_hash;需要展示原车牌时单独做加密、权限隔离和审计。- 月分区通常够用,不要按车牌分片或建过细分区,否则小 part 过多会拖慢合并和查询。数据量特别大时再评估按日分区。- 设备重试会产生重复事件。上游尽量生成唯一 event_id 并保证幂等;ReplacingMergeTree 只能做最终去重,不是强事务,关键去重仍要在接入层完成。2)写入- 单条 INSERT 的成本很高,建议按 5000~50000 行或每 1~2 秒攒批写入。- 可以用 Kafka/数据接入服务批量写 ClickHouse;HTTP 写入时开启 async_insert=1、wait_for_async_insert=0,并限制单批大小。- 入口道闸离线缓存的数据要按事件时间补写,同时监控设备时钟漂移,否则分区裁剪和轨迹顺序都会出错。3)常用查询查询某车在某车场的时间范围轨迹:SELECT event_time, gate_id, lane_id, event_typeFROM parking_gate_eventsWHERE lot_id = {lot_id:UInt32} AND plate_hash = {plate_hash:FixedString(16)} AND event_time >= {start:DateTime64(3)} AND event_time {end:DateTime64(3)}ORDER BY event_time;查询每小时进出量:SELECT toStartOfHour(event_time) AS hour, countIf(event_type = 'enter') AS enters, countIf(event_type = 'exit') AS exitsFROM parking_gate_eventsWHERE lot_id = {lot_id:UInt32} AND event_time >= now() - INTERVAL 24 HOURGROUP BY hourORDER BY hour;做小时级看板时,建议再建 AggregatingMergeTree 物化视图预聚合 enters/exits 和 uniqExactState(plate_hash),看板只查聚合表,不要每次扫原始明细。4)当前在场数不是 ClickHouse 的强项直接对全量进出记录做 enter-exit 相减,遇到跨天停车会算错,而且成本随历史数据增长。应在 Redis/业务库维护以车场+plate_hash 为键的会话状态,入场置为 in、出场置为 out;ClickHouse 只保存会话快照和明细,用于事后审计与统计。5)性能与运维- 查询必须带 lot_id 和时间范围,避免 SELECT * 和全表扫描。- 车牌精确检索依赖 plate_hash 的 bloom filter;跨车场统计可加按 plate_hash、event_time 排序的 projection 或单独汇总表。- 开启 TTL,并定期检查 system.parts;历史明细转低频或冷存储。- 若要求“入场即查、出场即结算”的强一致状态,请放在 OLTP/Redis,ClickHouse 负责分析和追溯,不要让它承担高并发单行更新。