历史数据存储原理:实时数据库与历史数据库的区别、数据压缩算法

大家好,我是老张。做SCADA系统这么多年,我见过太多人栽在历史数据这块。说实话,很多人觉得数据存进去就完事了,结果一查历史趋势,要么卡死,要么数据对不上。今天咱们就聊聊这个核心问题——历史数据到底是怎么存的。

实时数据库 vs 历史数据库:别搞混了

先问个问题:你打开SCADA画面,看到那个实时跳动的数字,和查历史报表时看到的曲线,它们来自同一个地方吗?

答案是否定的。

实时数据库和历史数据库,虽然名字像,但完全是两码事。我刚开始做项目时也犯过糊涂,以为就是一个库的不同视图。后来被现场数据搞崩过一次,才彻底搞明白。

实时数据库:快,但记性差

实时数据库,说白了就是内存里的一个快照。它只关心当前值。比如你看到一个压力值12.5MPa,那就是实时数据库里最新的那个数。

  • 存储位置:内存(RAM)
  • 读写速度:毫秒级,甚至微秒级
  • 数据量:只存当前值,极小
  • 断电后:数据丢失(除非有后备电池)
  • 典型用途:画面显示、报警判断、控制逻辑

我习惯把实时数据库比作一个白板。你写上去,大家看,但擦掉就没了。它不负责记历史账。

历史数据库:慢,但记性好

历史数据库就不一样了。它存的是时间序列数据——每个值都带着时间戳。你查昨天下午3点的温度,它就能给你翻出来。

  • 存储位置:硬盘(SSD/HDD)
  • 读写速度:秒级到分钟级(取决于查询范围)
  • 数据量:巨大,几年甚至几十年的数据
  • 断电后:数据永久保存
  • 典型用途:趋势分析、报表生成、审计追溯

你想想看,一个工厂几千个测点,每秒采一次,一天就是几亿条记录。如果不做压缩,硬盘再大也扛不住。

核心区别一句话总结:实时数据库管「现在是什么」,历史数据库管「刚才是什么、昨天是什么、去年是什么」。

数据压缩算法:为什么必须压缩?

好,问题来了。历史数据那么多,怎么存得下?

答案就是压缩。但SCADA系统的压缩和你在电脑上压缩图片、视频不一样。它要保证精度,还要保证查询速度。

我个人最常用的两种算法:旋转门压缩死区压缩。下面一个一个说。

死区压缩:最简单的办法

死区压缩,名字听着玄乎,其实道理特别简单。

你设定一个阈值,比如±0.5%。只有当当前值和上次记录的值之差超过这个阈值时,才记录新数据。否则就忽略。

举个例子:

设定死区:±0.5%
上次记录值:100.0

新采集值:100.2 → 变化0.2%,小于0.5% → 不记录
新采集值:100.6 → 变化0.6%,大于0.5% → 记录100.6
新采集值:100.3 → 变化-0.3%,绝对值小于0.5% → 不记录

我在一个水处理项目里用过这个。那个液位计波动特别小,一天下来变化不到1%。用死区压缩后,一天只存了不到100条记录,而原始数据是86400条。压缩比接近1000:1。

小技巧:死区设置要合理。太小了压缩效果差,太大了会丢失重要变化。我一般建议先看历史波动范围,取波动幅度的5%-10%作为死区。

旋转门压缩:更聪明的算法

死区压缩有个问题——它只关心数值变化,不关心变化趋势。比如一个值缓慢上升,每次变化都小于死区,那它就不记录。但等你想看趋势时,发现中间全是平的,其实数据一直在变。

旋转门压缩就是来解决这个问题的。

它的核心思想是:用一条直线来拟合一段时间内的数据点。只要所有点都在直线上下某个范围内(这个范围叫「门宽」),就只记录起点和终点,中间的点全部丢掉。

我画个图帮你理解:

旋转门压缩原理示意图 t₀ t₁ t₂ t₃ t₄ 时间 100 150 200 门宽 原始数据点 压缩后保留点 拟合直线

你看这个图。原始数据有15个点,但旋转门压缩后只保留了4个点。中间那些点虽然被丢了,但用直线插值回去,误差在门宽范围内。这就是它的高明之处。

旋转门的优势:它保留了趋势信息。即使数值变化很小,只要趋势在变,它就会记录关键转折点。这对于分析过程变化特别有用。

两种算法怎么选?

我做了个对比表,你一看就明白:

对比项 死区压缩 旋转门压缩
核心逻辑 数值变化超过阈值才记录 用直线拟合,误差在门宽内就丢弃中间点
压缩比 高(尤其对稳定信号) 较高(取决于门宽设置)
趋势保留 差(可能丢失缓慢变化) 好(保留趋势转折点)
计算复杂度 低(简单比较) 中(需要计算直线拟合误差)
适用场景 开关量、稳定模拟量 变化缓慢但有趋势的模拟量
典型压缩比 10:1 ~ 1000:1 5:1 ~ 100:1

我个人习惯是:开关量和稳定不变的模拟量用死区压缩,有趋势变化的模拟量用旋转门压缩。比如一个储罐液位,平时稳定,但进料时会缓慢上升,这种用旋转门最合适。

注意:压缩不是万能的。我曾经在一个项目里把门宽设得太大,结果压缩比是高了,但查历史趋势时发现曲线全是锯齿。后来重新调整参数才解决。记住:压缩是为了节省空间,但不能牺牲可用性。

实际项目中的配置建议

说了这么多理论,来点实际的。我一般这样配置:

  1. 先分析信号特性:看看这个测点平时波动多大,变化快不快。
  2. 死区设置:取量程的0.5%-2%。比如一个0-100℃的温度,死区设1℃就差不多了。
  3. 旋转门门宽:取量程的1%-3%。还是那个温度,门宽设2℃。
  4. 采样频率:别采太密。1秒采一次和10秒采一次,对压缩效果影响很大。我一般建议模拟量5-10秒采一次就够了。
  5. 定期检查:每季度看看压缩比和查询速度,参数不是一成不变的。

嗯,今天就聊到这儿。历史数据存储这块,说白了就是平衡的艺术——存得多了占空间,存得少了丢信息。找到那个平衡点,才是真本事。


公众号:蓝海资料掘金营,微信deep3321