2、报警历史记录数据结构设计

在 SECS/GEM 协议体系中,报警(Alarm)是设备向主机报告异常状态的核心机制。一个健壮的报警历史记录存储系统,其数据结构设计直接决定了查询效率、存储开销以及后续分析的准确性。本节将详细定义报警历史记录的六个核心字段,并给出标准化的数据表结构与实体关系。

2.1 核心字段定义

报警历史记录由以下六个必选字段构成,每个字段在 SECS/GEM 标准中均有对应的数据项(SVID 或 Collection Event)映射:

字段名称 数据类型 长度/精度 SECS/GEM 映射 说明
报警ID 字符串 (String) 32 字符 SVID 或 ALID 设备定义的唯一报警编号,如 "ALM-101"
报警文本 字符串 (String) 256 字符 ALCD / ALTX 人类可读的报警描述,如 "冷却水流量过低"
报警级别 整数 (Integer) 1 字节 ALCD 中的级别位 1~255,数值越大严重程度越高
发生时间 时间戳 (Timestamp) 毫秒精度 CE 时间戳 报警首次被触发的设备时间
清除时间 时间戳 (Timestamp) 毫秒精度 CE 时间戳 报警被手动或自动清除的时间,可为空
状态 枚举 (Enum) 1 字节 ALST 0=已清除, 1=激活, 2=已确认
设计要点: 报警ID 在设备生命周期内应保持唯一且不变。即使报警被清除后再次发生,也应使用相同的报警ID,以便进行历史趋势分析。

2.2 状态机与生命周期

报警记录的状态并非静态,而是遵循一个有限状态机模型。理解状态转换对于数据结构的完整性至关重要。

报警状态转换图 激活 (Active) 已确认 (Ack) 已清除 (Clear) 操作员确认 条件恢复 同一报警再次触发 说明:状态字段存储当前最新状态,历史记录中每次状态变更都会产生一条新记录。
状态转换规则:
  • 激活 → 已确认: 操作员在 HMI 上确认报警,表示已知晓。
  • 已确认 → 已清除: 设备故障排除,报警条件消失。
  • 激活 → 已清除: 某些自恢复报警可直接跳转。
  • 已清除 → 激活: 同一报警再次发生,开始新的生命周期。

2.3 数据库表结构设计

基于上述字段定义,推荐使用关系型数据库(如 PostgreSQL 或 MySQL)存储报警历史。以下为建表 SQL 示例:

CREATE TABLE alarm_history (
    id              BIGSERIAL       PRIMARY KEY,
    alarm_id        VARCHAR(32)     NOT NULL,
    alarm_text      VARCHAR(256)    NOT NULL,
    alarm_level     SMALLINT        NOT NULL CHECK (alarm_level BETWEEN 1 AND 255),
    occur_time      TIMESTAMPTZ     NOT NULL,
    clear_time      TIMESTAMPTZ,
    status          SMALLINT        NOT NULL CHECK (status IN (0, 1, 2)),
    created_at      TIMESTAMPTZ     NOT NULL DEFAULT NOW(),
    
    -- 索引优化
    INDEX idx_alarm_id (alarm_id),
    INDEX idx_occur_time (occur_time),
    INDEX idx_status (status),
    INDEX idx_alarm_level (alarm_level)
);

COMMENT ON TABLE alarm_history IS '报警历史记录表';
COMMENT ON COLUMN alarm_history.status IS '0=已清除, 1=激活, 2=已确认';
性能注意事项: 报警历史表数据量增长极快(大型半导体工厂每天可能产生数十万条记录)。必须对 occur_time 和 alarm_id 建立联合索引,并定期进行分区归档(如按月分区)。

2.4 数据结构实体关系图

以下 SVG 图展示了报警记录与设备、报警定义表之间的逻辑关系,帮助理解数据在系统中的流转:

报警数据实体关系图 设备 (Equipment) 设备ID (PK) 设备名称, 型号 报警定义 (AlarmDef) 报警ID (PK) 报警文本, 默认级别 报警历史 (AlarmHist) 记录ID (PK) 报警ID (FK), 状态, 时间 1:N 1:N 关系说明: 1. 一台设备可以定义多个报警(报警定义表)。 2. 每个报警定义可以产生多条历史记录(报警历史表)。 3. 报警历史表通过 alarm_id 外键关联报警定义表。 4. 报警文本在历史表中冗余存储,防止报警定义变更后历史记录描述不一致。 5. 查询时优先使用报警历史表的时间索引,避免全表扫描。

2.5 字段设计最佳实践

  • 报警ID 命名规范: 建议采用 "模块_序号" 格式,如 "CHAMBER_01_TEMP_HIGH",便于分类检索。
  • 时间字段处理: 统一使用 UTC 时间存储,前端展示时转换为本地时区。清除时间允许为 NULL,表示报警尚未清除。
  • 报警级别映射: 建议将 SECS/GEM 的 1~255 级别映射为业务含义:1~50=提示, 51~100=警告, 101~200=错误, 201~255=紧急。
  • 数据归档策略: 超过 6 个月的历史数据迁移至归档表或冷存储,主表只保留活跃报警和近期历史。
扩展思考: 在实际项目中,报警历史表通常还会增加 equipment_id 字段(冗余存储)以加速跨设备查询,以及 ack_user 字段记录确认报警的操作员账号,用于审计追踪。