2.1 데이터 모델 개념
데이터 모델은 무엇을 한 건으로 저장하고, 어떤 값으로 구분하며, 어떻게 변경하고 조회할지를 정한 규칙입니다. 시계열 모델에서는 측정 대상과 시각, 값의 의미를 함께 정해야 합니다. 컬럼 이름을 정하기 전에 이 규칙부터 확인하면 입력과 분석 결과의 해석이 일관됩니다.
시계열 데이터 이해하기
시계열 데이터는 시간에 따른 관측이나 사건의 기록입니다. 온도 측정, 체결 이력, 서비스 오류 기록이 대표적입니다. 일정 간격으로 수집할 수도 있고 사건이 발생할 때만 기록할 수도 있습니다. 저장 순서가 발생 순서와 같다는 보장은 없습니다.
한 행의 의미와 식별자
온도 이력의 한 행을 “센서 한 개가 특정 시각에 측정한 값”으로 정했다면 센서 식별자, 측정 시각과 값이 필요합니다. 식별자는 데이터가 어느 대상에서 나온 것인지 구분하고, 시각은 대상의 변화 순서를 해석하는 기준입니다.
여러 센서가 같은 시각에 측정할 수 있으므로 시각만으로 행을 유일하게 구분할 수는
없습니다. 같은 센서의 같은 시각 데이터도 재전송으로 반복될 수 있습니다.
중복을 허용할지, 제거할지, 별도 이벤트 번호가 필요한지를 결정해야 합니다.
TAG의 PRIMARY KEY는 태그를 식별하는 역할이며 일반 관계형 테이블처럼 각 측정 행의
이름이 유일하다는 뜻은 아닙니다. TAG 데이터 중복 처리는
TAG 테이블 운영에서 확인합니다.
값, 단위와 품질
숫자만 저장하면 단위와 의미를 알 수 없습니다. 같은 23.5라도 온도, 압력과 전압은
서로 다른 데이터입니다. 태그 정의나 기준 정보에 단위와 측정 위치를 관리하고, 하나의
시계열에서 값의 의미가 바뀌지 않게 합니다.
NULL과 0도 구분합니다. 장비가 0을 측정한 것과 측정에 실패해 값을 알 수 없는 것은
다릅니다. 필요하면 품질이나 상태를 별도 컬럼으로 기록합니다. 수집되지 않은 구간에는
행 자체가 없을 수 있으므로, NULL 행이 있는 경우와도 구분해야 합니다.
일반적인 AVG 같은 집계는 NULL을 제외한 값에 적용됩니다. 누락된 값을 무조건 0으로
채우거나 서로 다른 단위를 함께 집계하면 분석 결과가 달라집니다. 지원 집계 함수의
정확한 NULL 처리는 함수 레퍼런스를
참고하십시오.
시계열 워크로드의 특성
많은 시계열 시스템은 새 행을 지속적으로 입력하고, 특정 대상의 시간 범위를 조회합니다. 최신 값을 확인하는 모니터링과 장기간 통계를 계산하는 분석을 함께 수행하기도 합니다. 이런 패턴이 추가 중심 입력, 구간 조회와 ROLLUP을 사용하는 이유입니다.
그러나 과거 데이터가 항상 불변인 것은 아닙니다. 장비 시각의 오류, 센서 보정이나 중복 수집으로 정정이 필요할 수 있습니다. 최근 데이터보다 오래된 데이터를 자주 읽는 업무도 있습니다. 실제 입력·조회·정정 패턴을 측정해 설계하십시오.
테이블 타입의 역할
| 테이블 타입 | 개념적 역할 |
|---|---|
| TAG | 이름과 시간·거리 축을 가진 계측 이력 |
| LOG | 새 기록을 계속 추가하는 이벤트와 로그 |
| TRANSACTION | 트랜잭션과 행 단위 변경이 필요한 업무 데이터 |
| LOOKUP | 메모리에 적재해 참조하는 영속 기준 정보 |
| VOLATILE | 재시작 후 다시 만들 수 있는 공유 메모리 상태 |
이력과 기준 정보를 분리하면 장비 이름이나 위치를 모든 측정 행에 반복 저장할 필요가 줄어듭니다. 다만 최신 기준 정보와 과거 이력을 조인하면 결과에도 최신 이름이나 위치가 표시됩니다. 발생 당시의 정보가 필요하면 해당 값을 이력에 남기거나 기준 정보의 변경 이력을 별도로 설계해야 합니다.
관계형 업무 모델과 시계열 모델
관계형 모델과 시계열 모델은 서로 배타적인 개념이 아닙니다. 관계형 DBMS에서도 시계열을 저장하고 인덱스·파티션·집계를 사용할 수 있으며, Machbase도 테이블과 SQL, 조인과 관계형 변경 기능을 제공합니다. 비교할 때는 제품 이름보다 주된 작업을 기준으로 판단합니다.
| 관점 | 관계형 업무 데이터의 예 | 시계열 이력의 예 |
|---|---|---|
| 행의 의미 | 주문 한 건의 현재 상태 | 센서 측정 한 건 또는 이벤트 한 건 |
| 변경 패턴 | 키로 찾은 행의 수정·삭제 | 새 기록 추가, 필요한 범위의 정정·정리 |
| 조회 패턴 | 키 조회, 조건 검색, 업무 테이블 조인 | 대상·시간 범위 조회, 추이와 구간 통계 |
| 일관성 요구 | 여러 변경을 함께 확정하거나 취소 | 수집 누락·중복·지연과 조회 가능 시점 관리 |
| 보관 설계 | 업무 수명과 변경 이력 | 원본 해상도, 집계 주기와 보관 기간 |
Machbase의 LOG·TAG 저장과 입력 특성을 TRANSACTION·LOOKUP·VOLATILE에 그대로 적용하지 마십시오. 최종 선택은 테이블 타입 선택과 데이터 변경 정책에서 확인합니다.
쓰기 중심 워크로드와 append-only 모델
append는 기존 값의 덮어쓰기 대신 새 행을 추가하는 방식입니다. 예를 들어 설비 상태가
RUNNING에서 STOPPED로 바뀔 때 새 이벤트를 기록하면 이전 상태와 전환 시점을
보존할 수 있습니다. 현재 상태를 바로 찾는 테이블과 상태 변화 이력을 저장하는 테이블을
별도로 운영할 수도 있습니다.
테이블 타입과 변경 모델
LOG는 추가 중심 이력 테이블이며 일반적인 행 UPDATE를 지원하지 않습니다. TAG는
계측 이력을 추가하고, 지원되는 조건과 Edition 범위에서 DATA 값을 보정할 수 있습니다.
태그 이름이나 시간축까지 임의로 수정하는 일반 행 변경과는 다릅니다.
TRANSACTION은 관계형 DML과 명시적 트랜잭션을 제공하고, LOOKUP·VOLATILE은 기준 정보나 상태 변경에 사용합니다. 한 테이블의 변경 기능이 다른 유형에서도 같다고 가정하지 말고 데이터 변경 정책을 확인합니다.
추가 중심 설계는 반복 입력과 과거 행의 임의 갱신을 함께 처리할 때의 경합을 줄이는 데 도움이 됩니다. 그렇다고 DBMS 내부의 동기화나 장애 복구 처리가 모두 없어지는 것은 아닙니다. 저장 구조만으로 잠금 없음이나 특정 처리량을 보장할 수는 없습니다.
SQL 입력과 SDK Append
SQL INSERT는 SQL 문장으로 값을 입력하고 실행 결과를 확인하는 경로입니다.
SDK Append는 연속 수집을 위해 여러 행을 전송하는 입력 API입니다. 버퍼링, 전송, 오류
확인과 종료 절차를 해당 SDK의 계약에 맞게 처리해야 합니다.
데이터를 애플리케이션 버퍼에 넣은 시점, 서버가 처리한 시점과 장애 뒤에도 복구할 수 있는
시점을 같은 것으로 취급하지 마십시오. LOG·TAG의 Append는 TRANSACTION 테이블의 명시적
트랜잭션에서 ROLLBACK할 대상이 아닙니다. TRANSACTION 테이블에 대한 Append의
트랜잭션 참여와 오류 처리는 사용하는 SDK의 계약을 확인합니다. 입력 확인과 재시도 방법은
데이터 입력과 반출을
참고하십시오.
정정, 스키마 변경과 보관
잘못된 LOG 이벤트는 보정 이벤트를 추가하는 방식으로 이력을 남길 수 있습니다. 삭제 후 다시 입력할 때는 LOG에서 허용하는 시간 기반 삭제 범위와 입력 순서를 먼저 확인해야 합니다. 특정 행 하나만 임의로 지울 수 있다고 가정하지 마십시오. TAG 값 보정은 TAG 데이터 보정 설계를 따릅니다.
컬럼 추가·삭제와 타입 변경도 별개의 기능입니다. LOG나 TAG의 모든 스키마 변경이 금지된 것은 아니며, 유형과 DATA·METADATA 영역에 따라 지원 범위가 다릅니다. DDL 문법을 확인한 뒤 적용합니다.
원본을 계속 추가하면 저장 공간이 증가합니다. 원본 보관 기간과 ROLLUP 통계의 사용 목적을 별도로 정하십시오. 집계 생성만으로 원본이 삭제되지는 않습니다.
시간 모델과 _arrival_time
발생 시각과 수신 시각
발생 시각은 장비에서 측정하거나 사건이 발생한 시각이고, 수신 시각은 DBMS가 기록을 받은 시각입니다. 09:00에 측정한 값을 네트워크 복구 후 09:05에 받았다면 두 시각의 차이는 5분입니다. 측정 추이를 보려면 발생 시각이, 수집 지연을 보려면 두 시각의 비교가 필요합니다.
시간 데이터에는 정밀도, 시간대와 시계 정확도도 구분해야 합니다. 나노초 단위로 표현할 수 있다는 사실이 센서 시계도 나노초 단위로 정확하다는 뜻은 아닙니다. 문자열을 DATETIME으로 해석하거나 표시할 때의 시간대는 시간대 설정을 참고하십시오.
LOG 테이블의 _arrival_time
LOG에는 _arrival_time DATETIME 컬럼이 자동으로 추가됩니다. 값을 생략하는 일반적인
입력에서는 서버 입력 시각을 기록합니다. 별도의 발생 시각이 필요하면 일반 DATETIME
컬럼을 정의합니다.
CREATE LOG TABLE device_events (
device_id VARCHAR(20),
event_time DATETIME,
status VARCHAR(20)
);_arrival_time을 명시하는 입력 경로도 있으므로 이 컬럼이 언제나 실제 수신 시각이라고
단정할 수는 없습니다. 명시 입력의 시간 순서와 제약은
LOG 시간 모델을 확인합니다.
SELECT device_id, event_time, status
FROM device_events
WHERE _arrival_time >= TO_DATE('2026-07-03 09:00:00', 'YYYY-MM-DD HH24:MI:SS')
AND _arrival_time < TO_DATE('2026-07-03 10:00:00', 'YYYY-MM-DD HH24:MI:SS')
ORDER BY _arrival_time;시작 시각은 포함하고 끝 시각은 제외하는 [시작, 끝) 범위를 사용하면 이어지는 구간의
경계값을 두 번 집계하는 실수를 줄일 수 있습니다. BETWEEN은 양쪽 경계를 모두
포함하므로 목적에 맞게 선택합니다. LOG의 DURATION은 _arrival_time을 기준으로
구간을 제한합니다.
TAG 테이블의 BASETIME 컬럼
시간축 TAG 테이블은 BASETIME 속성의 DATETIME 컬럼에 애플리케이션이 시각을
입력합니다. LOG의 자동 _arrival_time 컬럼을 사용하지 않습니다.
CREATE TAG TABLE sensor_values (
name VARCHAR(128) PRIMARY KEY,
time DATETIME BASETIME,
value DOUBLE SUMMARIZED
);
INSERT INTO sensor_values
VALUES ('temp_sensor_01',
TO_DATE('2026-07-03 08:55:00', 'YYYY-MM-DD HH24:MI:SS'),
23.1);이 예에서 name은 센서를, time은 측정 시각을, value는 측정값을 나타냅니다.
SUMMARIZED는 ROLLUP 등 관련 통계 기능이 사용할 대표 숫자 컬럼을 지정합니다.
테이블을 생성한 것만으로 원하는 모든 주기의 집계가 생기는 것은 아닙니다.
TAG에는 시간 대신 수치 축을 사용하는 BASE DISTANCE 모델도 있습니다. 거리·위치에 따른 계측에는 이 모델을 검토하되 시간축 전용 함수와 정책을 그대로 적용하지 마십시오. TAG 스키마에서 축별 규칙을 설명합니다.
두 시간 모델의 비교
| 항목 | LOG | 시간축 TAG |
|---|---|---|
| 특수 시간 컬럼 | 자동 생성되는 _arrival_time | 선언한 BASETIME 컬럼 |
| 입력 시각의 의미 | 기본 입력에서는 서버 시각, 명시 입력은 해당 값 | 애플리케이션이 지정한 시각 |
| 별도 발생 시각 | 일반 DATETIME 컬럼에 저장 가능 | BASETIME을 발생 시각으로 사용 가능 |
| 주요 설계 질문 | 어떤 이벤트와 필드를 검색할 것인가 | 어떤 태그의 어느 구간을 분석할 것인가 |
발생 시각이 필요하다는 이유만으로 LOG를 배제할 필요는 없습니다. 시간 의미와 함께 태그 구조, 검색·집계, 수정·삭제 조건으로 테이블을 선택하십시오. LOOKUP·VOLATILE·TRANSACTION의 DATETIME은 일반 컬럼이며 LOG·TAG의 특수 시간축 기능이 자동으로 부여되지 않습니다.
행이 저장된 순서와 결과를 보여 줄 순서도 구분합니다. 결과 순서가 중요하면
ORDER BY를 명시하고, 동일 시각의 행까지 구분해야 하면 추가 정렬 기준을 정합니다.