스마트 HACCP CCP 기록, MySQL 이력과 MQTT를 나누는 설계

왜 두 갈래로 나눌까요
중요관리점(CCP)의 상태가 바뀌면 지금 어느 지점이 어떤 상태인지 바로 알아야 해요. 며칠 뒤에는 특정 시각의 기록을 다시 찾을 수 있어야 하고요.
MySQL은 기간·지점별로 찾는 이력에, MQTT는 현재 상태를 여러 구독자에게 전달하는 흐름에 맞춰 나누는 편이 이해하기 쉬워요. 한국식품안전관리인증원 공식 자료는 스마트 HACCP을 IoT로 CCP 모니터링을 실시간 자동 기록·관리하는 구조로 설명해요. 이 글은 그 기록을 운영 화면과 상위 시스템에 잇는 데이터 설계 기준을 다뤄요.
CCP 데이터가 가는 길
포장 공정의 CCP 판정 상태가 LS PLC의 한 주소에 들어온다고 해볼게요. 식품공장 모니터링에서 주소 맵은 설비 데이터 수집의 기준이에요. 필드 이름, PLC 주소, 데이터 타입, 상태의 의미, 수집 주기와 변경 시각을 함께 적어요.
산업용 IoT 게이트웨이인 EASY-LINK는 LS XGT 데이터를 읽어 MQTT나 MySQL 같은 목적지로 전달하는 연결 계층을 맡을 수 있어요. 한 지점의 값을 외부 목적지로 보내는 정도라면 EASY-LINK 중심으로 시작해도 충분해요. 여러 CCP의 수집 주기, 저장 이력, 전달 상태와 대시보드를 한곳에서 운영하려면 EASY LOGGER는 이를 관리하는 수집·저장·전달 운영 계층을 맡아요. 두 제품 모두 HACCP 판정이나 현장 안전 로직을 대신하지는 않아요.

CCP 상태가 PLC 주소를 거쳐 검색용 MySQL 이력과 실시간 MQTT 흐름으로 갈라지는 구조예요.
MySQL은 기간 조회에, MQTT는 여러 화면이 같은 현재 상태를 받아야 할 때 잘 맞아요. 요청과 응답 결과가 중요하면 HTTP API를, 모바일 중심 동기화가 목적이면 Firebase를 비교할 수 있어요. 조회 방식, 재전송, 중복 처리와 운영 권한을 기준으로 골라야 해요.
EASY LOGGER MySQL 예제
아래 SQL은 EASY LOGGER 내부 구조가 아니에요. 상위 시스템이나 고객이 소유한 외부 MySQL에 만드는 예시 스키마예요. 예시 주소 맵에서 D0100은 CCP 판정 상태와 대응하고 event_value에 저장돼요. line_id와 ccp_point는 외부 시스템의 검색용 메타데이터이며, 실제 이름과 값은 현장 필드 주소 맵과 대조해야 해요.
CREATE TABLE ccp_event_history (
event_id BIGINT PRIMARY KEY AUTO_INCREMENT,
line_id VARCHAR(32) NOT NULL,
ccp_point VARCHAR(32) NOT NULL,
plc_address VARCHAR(16) NOT NULL,
event_value INT NOT NULL,
recorded_at DATETIME(3) NOT NULL,
INDEX idx_ccp_search (ccp_point, recorded_at)
);
SELECT ccp_point, plc_address, event_value, recorded_at
FROM ccp_event_history
WHERE ccp_point = 'CCP-01'
AND recorded_at >= '2026-07-31 09:00:00'
ORDER BY recorded_at;
이 데이터베이스 설계는 외부 조회용이에요. DB History Logs에서 예시 설정 D100_WORD의 저장 성공 여부와 시각 범위를 확인하고, 외부 테이블에서는 plc_address=D0100과 상태 시각이 이어지는지 비교해요. 보존 기간은 확인되지 않은 법정 기간을 단정하지 말고 현장 기록 정책에 따라 검색 구간, 백업과 삭제 절차를 정해요.
EASY LOGGER MQTT 예제
여기서 XBMPLC, D100_WORD, D0100은 모두 예시예요. D100_WORD 설정이 LS PLC의 D0100 한 WORD를 읽고, 그 값이 CCP 상태 필드와 대응한다고 가정했어요. 실제 Topic을 쓰기 전 Automatic Topic Preview에서 현장 PLC명·설정명과 주소 맵을 대조해요.
READ TOPIC: XBMPLC/D100_WORD/READ
WRITE TOPIC: XBMPLC/D100_WORD/WRITE
READ payload의 values.D0100은 같은 주소 맵의 CCP 상태 값이에요. plc_name, config_name, data_type까지 함께 보면 어느 설정에서 나온 값인지 구분할 수 있어요.
{
"plc_name": "XBMPLC",
"config_name": "D100_WORD",
"data_type": "word",
"values": {"D0100": 123}
}
WRITE payload도 D0100에 대응하는 테스트 필드만 사용해요. 123은 형식을 설명하는 예시 값이며, 실제 허용값은 PLC 주소 맵과 인터록 조건을 확인한 뒤 정해요.
{"values":{"D0100":123}}
Subscribe to the WRITE Topic.
- 테스트 주소만 사용합니다.
- 최소 권한만 부여합니다.
- 허용 주소 범위를 제한합니다.
- PLC 인터록을 확인합니다.
- 수동 복구 절차를 준비합니다.
Automatic Topic Preview로 Topic을 확인한 뒤 Runtime Status에서 연결·전달 상태를 보고, Payload Log와 Subscribed Payload Log에서 마지막 시각, Topic, payload가 함께 남는지 확인해요. MQTT 수신 성공을 PLC 동작 성공으로 단정하지 않고 현장 상태와 별도 승인 절차로 확인해야 해요.
화면과 상위 시스템을 연결해요
HACCP인증원의 선도모델 자료는 스마트 HACCP과 생산관리시스템(MES)을 결합하고 실시간 데이터를 연동하는 구성을 소개해요. MES나 CIM은 합의한 MQTT Topic, HTTP API 또는 외부 DB 인터페이스를 통한 데이터 연동 구조로만 연결해요.
대시보드에는 현재 상태, 마지막 수신 시각, DB 저장 상태처럼 운영 질문에 답하는 항목을 먼저 둬요. 조회 권한과 PLC 연동의 쓰기 권한도 분리해요. 화면, DB 이력, MQTT 구독은 각각 끊길 수 있으므로 Runtime Status, Payload Log, DB History를 한 순서로 확인해요.

한 CCP의 이력과 실시간 상태를 검증한 뒤 여러 지점과 상위 시스템 인터페이스로 넓혀 가는 단계예요.
한 지점부터 확인해요
처음에는 한 공정의 CCP 한 지점, PLC 주소 한 개, 외부 MySQL 테이블 한 개와 MQTT 구독자 한 개로 작게 시작해요. 정상 상태, 상태 변경, 통신 단절과 재연결을 기록하면 이력 누락과 실시간 전달 지연을 다른 문제로 볼 수 있어요. 첫 지점이 안정되면 같은 검증 순서를 다른 CCP에 적용해요.
온도 기록을 설계하고 있다면 스마트 HACCP 온도 기록 글도 비교해 보세요. 다른 글은 기술 블로그에서 볼 수 있고, PLC 모델·주소 맵·전달 목적지만 정리해도 HT Automation에서 현장 연결 가능 여부를 부담 없이 확인할 수 있어요.