Files
HC900-Crawler/scripts/sql/p1_historian.sql
windpacer 7f67f0e54d feat(report): P1a 1초 링버퍼 히스토리안 (history_1s)
온라인 히스토리안 1계층 — 디스크 상한 고정 1초 버퍼.

- history_1s Timescale 하이퍼테이블(1h 청크) + 압축(6h) + 보존 14일(청크DROP, 디스크 상한 고정).
- Hc900FastHistoryService: 매 1초 realtime_table 큐레이션 태그 → history_1s append.
  기동 시 스키마/정책 멱등 생성. Hc900HistoryService(60s) 패턴.
- ReportColumnMap.HistorianTags(): 메트릭/마스크가 읽는 태그를 기존 config에서 유도(~105개,
  중복정의 없음) — 유량 .PV/.QV, 진공, 민감단 TC, 하부루프 .PV/.SP/.OP.
- Report:Historian config(Enabled/IntervalSeconds/RetentionDays).

검증: 라이브 초당 ~38행 append, 샘플 간격 ~1.004s, 보존/압축 정책 활성.
주의(데모): realtime 폴링이 areas 61/62/81만 커버 → 1s 버퍼도 해당 컬럼만(배포 시 전 컨트롤러).
1s 버퍼 주 가치는 .PV/.OP 동특성; .QV 적산은 60s로도 정확.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 04:56:15 +09:00

23 lines
1.1 KiB
SQL

-- P1a: 1초 링버퍼 히스토리안 (hc900.history_1s)
-- 적용: psql "host=localhost dbname=iiot_platform user=postgres" -f scripts/sql/p1_historian.sql
-- 서비스(Hc900FastHistoryService)가 기동 시 동일 DDL을 멱등 적용하므로 수동 실행은 선택.
SET search_path TO hc900;
CREATE TABLE IF NOT EXISTS hc900.history_1s (
tagname text NOT NULL,
recorded_at timestamptz NOT NULL DEFAULT now(),
value text,
controller_id text
);
-- 하이퍼테이블 (1시간 청크 — evict/압축 단위)
SELECT create_hypertable('hc900.history_1s', 'recorded_at',
chunk_time_interval => INTERVAL '1 hour', if_not_exists => TRUE);
-- 압축 (6시간 지난 청크) + 링버퍼 보존 (14일 — 청크 DROP, 비용≈0)
ALTER TABLE hc900.history_1s SET (timescaledb.compress, timescaledb.compress_segmentby = 'tagname');
SELECT add_compression_policy('hc900.history_1s', INTERVAL '6 hours', if_not_exists => TRUE);
SELECT add_retention_policy('hc900.history_1s', INTERVAL '14 days', if_not_exists => TRUE);
CREATE INDEX IF NOT EXISTS ix_h1s_tag ON hc900.history_1s (tagname, recorded_at DESC);