

你好！面对这么多专业的数据库表、代码和复杂的触发器，刚开始觉得像看天书一样是再正常不过的了。千万别有压力！

如果我们把这段干巴巴的代码世界，想象成一个井然有序的**“现代数据加工厂”** ，一切就会变得异常清晰。作为菜鸟小白，我们今天不钻代码牛角尖，而是换上厂长的视角，去巡视一下这个工厂的“完整流水线”。

我帮你把这份长篇大论重新“嚼碎”，梳理成一份**最全面、最易懂、最接地气**的全流程大白话指南！

---

### 第一阶段：建厂初衷 —— 为什么要搞这么复杂？

以前咱们查机器的产量，简单粗暴：直接去数据库翻“最新的一条记录”。但随着工厂里设备越来越多，这招彻底不灵了，遇到了两个致命痛点：

1. **“机器会撒谎”：** 工厂的机器计数器很不听话。有时候跨天了它不清零，有时候工人不小心按错了或者断电，它又突然清零了。这导致产量算得乱七八糟。
2. **“大屏被挤爆”：** Board4 是一个需要高频刷新的大屏。如果你每次刷新，都让数据库去海量的原始数据里现做加减法，数据库的 CPU 会直接拉满，甚至死机卡瘫痪。

为了彻底解决“算不准”和“查得慢”的问题，咱们把系统进行了全面升级，划分出了 **“四大仓库”**。

---

### 第二阶段：工厂基建 —— 四大核心数据仓库

整个系统的运转，就是数据在这四个仓库里流转的过程 ：

1. **人工录入层（`BASE_DEVICE_PARAM_VAL`）：**
   这是给车间里那 5 台不支持自动联网的“老古董设备（OLD设备）”准备的。工人拿着 PDA 扫码录入的数据，全都堆在这一个大仓库里。
2. **自动采集层（`BASE_DEVICE_PARAM_VAL_YYYYMM`）：**
   这是给新一代自动设备准备的。因为它们每时每刻都在发数据，数据量极其庞大，所以采用了**“按月建表（分表）”**的策略（比如 3 月的数据存在 202603 表里）。
    * **✨ 自动化黑科技：** 咱们不需要人工去建表。每个月的 **26 号凌晨 2:00**，数据库会自动派出机器人（定时任务），把下个月的空表和配套设施提前建好，铺好路等着数据进来。
3. **实时累计层（`RT_DAILY_PROD_STATE`）：**
   这是咱们的**“今日计分板”**。它不关心明细，只记录每台设备**今天此时此刻**的总产量是多少。
4. **日汇总层（`DEVICE_DAILY_PRODUCTION`）：**
   这是咱们的**“历史档案馆”**。它保存过去每一天已经盖棺定论的权威总产量。

---

### 第三阶段：数据入库 —— 两种设备的“计分”路线

数据是怎么流向“今日计分板”的呢？新老设备有两套不同的流水线：

#### 路线 A：老设备（人工录入）
老设备的流程很简单。工人用 PDA 录入数据后，后端的 **Java 程序**就像个贴心的记账员，在把数据存进老表的同时，会顺手算出最新产量，直接写在“今日计分板”（RT 表）上。

#### 路线 B：新设备（全自动采集）—— 核心性能护城河！
自动设备的数据像洪水一样涌来，这里的架构设计堪称精妙：
1. **C# 程序的“10 分钟拦截”：**
   C# 采集程序并没有傻乎乎地收到一条数据就往数据库写一条。它采用了**“节流”**策略，在内存里把数据攒够 **10 分钟**，然后再打包一次性发给数据库。这完美避开了高频写入导致的数据库锁死问题，性能拉满！然后，C# 只需要根据采集时间，将数据精准投递到对应的“当月分表”里即可。
2. **数据库触发器的“安检与计分”：**
   当月分表里装了一个叫“触发器”的暗哨（比如 `TRG_BDPV_202603_RT`）。新数据一落库，触发器就开始干活。
    * **严查通行证：** 它首先化身“保安”，只对名为 `机台状态-实际产出数量` 的参数放行，温度、压力等无关数据一律无视，避免浪费计算资源。同时，它也会过滤掉以 `OLD-` 开头的老设备数据（因为 Java 已经算过了，防止重复算）。
    * **自动算分：** 安检通过后，它会自动用一套叫做 `delta-sum` 的算法，算出这 10 分钟内真实增加了多少产量，并写到“今日计分板”上。

---

### 第四阶段：防错黑科技 —— Delta-Sum 算法到底是个啥？

机器抽风清零了怎么办？这就是触发器里 `delta-sum`（差值求和）算法大显身手的时候了 。

假设机器就像个一直往上涨的**水表**，触发器每次都会拿“新数字”和计分板上的“老数字”做对比：

1. **水表正常涨（比如 100 变成 120）：**
   说明一切正常，**真实增量就是差值**（120 - 100 = 20），把这 20 加到总数里。
2. **水表突然变小了（比如 120 突然变成 5）：**
   机器清零了！此时触发器极其聪明，它绝不扣减产量，而是**直接把清零后的新数字（5）当作实打实的新增产量**加进去，并且在后台拿小本本记下：这台机器今天又清零重置了 1 次。
3. **水表没动静（比如还是 120）：**
   说明停机没干活，增量记为 0。

**一句话总结算法：涨了就算差值，跌了就把跌完的新值当增量，最后统统累加到总数上！** 这样算，不管机器怎么清零抽风，产量绝对一分不少！

---

### 第五阶段：夜间大扫除 —— 午夜搬运工

“今日计分板”（RT 表）每天被更新无数次，但它只管今天的事。到了明天怎么办？

每天夜里 **00:10**，系统会自动派出一个定时搬运工（`JOB_FLUSH_RT_TO_DAY`）。
他会把“今日计分板”里属于**昨天**的最终比分，郑重其事地抄写到“历史档案馆”（DAY 汇总表）中，永久保存。抄写完毕后，他会把计分板里昨天的数据擦得干干净净，迎接新一天的产量计分。

---

### 第六阶段：终端展现 —— 大屏快如闪电

经历过前面如此严密的流水线加工，现在 Board4 大屏想要展示数据，那简直是探囊取物：

* **看今日实时产量：** 别去明细表里费劲扒拉了，直接看那张“今日计分板”（RT 表），要多快有多快。
* **看本月总产量：** 去“历史档案馆”（DAY 表）把本月之前的汇总拿出来，加上“今日计分板”里今天的临时数据，两者一合并，瞬间出结果。

---

### 🌟 终极一句话总复习

**数据库月底自动盖好新仓库 ➡️ C# 收集好数据每 10 分钟存一次 ➡️ 触发器负责过滤和防错计算 ➡️ 算出今日产量存入计分板 ➡️ 每天半夜存入历史档案库 ➡️ 大屏直接拿结果展示！**

怎么样，是不是感觉原本杂乱无章的代码瞬间变成了一个井然有序的工厂？如果你对这里面的某个环节感兴趣，你想让我给你展开讲讲**如何应对前端 trace/SPC 历史追溯页面的查询**，还是想看看**如果系统崩溃了，实施人员照着文档重装数据库的 7 个步骤**呢？

**是的，“实时累计层”（`RT_DAILY_PROD_STATE` 表）每天都会被清理，它永远只保留“今天”的数据。**

在你的数据库里，这个清理动作设计得非常有仪式感。我们来看看每天夜里到底发生了什么：

### 1. 什么时候清理？由谁来清理？
每天夜里 **00:10**，数据库会准时唤醒一个自动化的“定时搬运工”（名叫 `JOB_FLUSH_RT_TO_DAY`）。

### 2. 具体是怎么清理的？（先存后删）
这个搬运工并不是一上来就野蛮删除，而是分两步走，非常有条理：
* **第一步（存档）：** 它会先去“今日计分板”（RT 表）里，把属于**昨天**的最终总成绩拿出来，安安稳稳地存进“历史档案馆”（日汇总层 `DEVICE_DAILY_PRODUCTION` 表）里。
* **第二步（销毁）：** 存档一旦成功，它会立刻执行一条 `DELETE` 语句，把 RT 表里属于昨天的数据**彻底删除**。

### 3. 为什么要每天把它删掉？
这里藏着架构设计上的两个极大智慧：
* **防止“算重复了”：** 前面我们聊过，大屏查“本月总产量”时，是用 **“历史档案馆（DAY表）里的数据 + 今日计分板（RT表）里的数据”** 相加。如果搬运完不把 RT 表里的昨天数据删掉，那昨天的数据就会被加两遍（DAY 表里加了一次，RT 表里又加了一次）！代码里的注释也明确写了：“避免月累计在窗口期之外重复计入”。
* **保证“快如闪电”：** 如果只存不删，RT 表就会越来越大。每天清理，能保证这张负责高频计算和高频查询的表永远保持极其轻量的状态，不管工厂运行多少年，大屏查询今日产量的速度永远是一瞬间！

简而言之，RT 表就像是一块黑板，每天夜里 00:10，系统会把黑板上的最终比分抄到日记本（DAY表）上，然后把黑板擦得干干净净，准备迎接新一天的计分。

