데이터베이스 모델
플랫폼이 데이터를 어디에 무슨 모양으로 담는지 정리한 문서입니다. 백업 범위를 정하거나, 직접 조회해야 하거나, 보존 기간을 조정할 때 봅니다.
플랫폼은 데이터 성격에 따라 저장소를 나눠 씁니다(polyglot persistence). 어느 데이터가 어디 있는지 모르면 백업이 반쪽이 됩니다.
| 저장소 | 담는 것 | 규모 |
|---|---|---|
| PostgreSQL | 마스터 데이터 · 설정 · 트랜잭션 | 43 테이블 |
Cassandra (pp) | 시계열 · 이벤트 · 집계 | 99 테이블 |
Iceberg (spark.plantpulse) | 장기 보관 · 분석 | 1 테이블 |
PostgreSQL — 마스터와 설정
관계형 데이터가 들어갑니다. 스키마 변경은 Flyway 가 관리하며 이력은
flyway_schema_history 에 남습니다.
테이블 이름은 mm_ 접두사(master/meta)가 36개로 대부분입니다.
| 묶음 | 테이블 |
|---|---|
| 조직·자산 | mm_company · mm_site · mm_asset_tree · mm_asset_type · mm_asset_status · mm_asset_statement · mm_asset_statement_plugin |
| 수집 정의 | mm_opc · mm_tag · mm_point · mm_scada |
| 알람 | mm_alarm · mm_alarm_config · mm_alarm_recieve_users |
| 이벤트·트리거 | mm_event · mm_event_attributes · mm_trigger · mm_trigger_attributes |
| 생산 | mm_order · mm_order_flow · mm_order_oee · mm_oee · mm_product · mm_shift · mm_calendar · mm_calendar_type |
| 사람·거래처 | mm_employee · mm_customer |
| 화면·조회 | mm_dashboard · mm_graph · mm_statement · mm_query_history |
| 보안 | mm_security · mm_token · user_login · user_login_session |
| 기타 | mm_blob · mm_metadata · metadata · version · version_history · dual |
mm_alarm_recieve_users 의 철자receive 가 아니라 recieve 입니다. 오타가 스키마에 굳은 것이라 쿼리를 쓸 때
그대로 적어야 합니다.
Cassandra — 시계열과 이벤트
키스페이스는 pp 입니다. 99개 테이블이 두 갈래로 나뉩니다.
| 접두사 | 개수 | 뜻 |
|---|---|---|
tm_ | 91 | 시계열·집계·통계 (time series measurement) |
ts_ | 8 | 범용 시계열 엔진 내부 구조 |
tm_ 은 대상별로 다시 갈립니다 — 태그 32 · 자산 22 · 시스템 6 · 모니터 6 · 옵션 5 ·
OPC 5 · 사이트 3 · blob 3 등.
핵심 테이블 — tm_tag_point
원시 수집값이 들어가는 자리입니다. 나머지 태그 테이블은 대개 이것의 파생입니다.
PRIMARY KEY (tag_id, timestamp)
WITH CLUSTERING ORDER BY (timestamp DESC)
| 성질 | 값 |
|---|---|
| 파티션 키 | tag_id — 태그 하나가 파티션 하나 |
| 클러스터링 | timestamp 내림차순 — 최신부터 읽는 것이 기본 |
| 기본 TTL | 5356800 초 = 62일 |
| Compaction | UnifiedCompactionStrategy (Cassandra 5.0+) |
| 인덱스 | asset_id · opc_id 에 SAI(Storage Attached Index) |
site_id · asset_id · line_id · area_id · opc_id · tag_name · type 은
static 입니다. 태그 하나(=파티션 하나) 안에서 값이 같으므로 파티션당 한 번만 저장합니다.
매 데이터 포인트마다 반복 저장하지 않아 용량이 크게 줄어듭니다.
파생 테이블 — 미리 계산해 둔다
Cassandra 는 조회 시점 집계가 비싸므로 쓸 때 미리 만들어 둡니다. 그래서 테이블이 많습니다.
| 갈래 | 예 |
|---|---|
| 집계 | tm_tag_point_aggregation_{1,5,10,30}_minutes · _1_hours |
| 샘플링 | tm_tag_point_sampling_{10,30}_seconds · _{1,5,10,30}_minutes · _1_hours |
| 카운트 | tm_tag_point_count · _by_date · _by_opc · _by_site |
| 품질·검증 | tm_tag_point_validation · _by_timestamp · _validation_count |
| AI 분석 | tm_tag_point_anomalies · _forecasts |
| 스냅샷·보관 | tm_tag_point_snapshot · tm_tag_point_archive |
알람도 같은 방식입니다 — tm_tag_alarm 과 _count · _count_by_date · _count_by_opc ·
_count_by_site · _duration · _on.
원시 데이터에서 다시 만들어지지 않습니다. 지우면 그 구간의 화면·리포트가 비어 버리고 복구는 백업뿐입니다.
Iceberg — 장기 보관
Cassandra 의 TTL(62일)을 넘긴 데이터를 오브젝트 스토리지에 쌓아 분석합니다.
| 항목 | 값 |
|---|---|
| 카탈로그 | spark.plantpulse |
| 테이블 | tm_tag_point_warehouse |
| 파티션 | site_id → year → month → day |
| 포맷 | Iceberg v2 (row-level delete 지원) |
| 압축 | Zstandard |
| 실행 | Spark SQL |
Cassandra 에는 없습니다. Iceberg 쪽을 조회하세요 → 분석 계층.
백업에서 놓치기 쉬운 것
세 저장소가 각각 백업 대상입니다. PostgreSQL 만 받아 두고 안심하는 경우가 있는데, 그러면 시계열이 통째로 빠집니다.
| 저장소 | 빠뜨리면 |
|---|---|
| PostgreSQL | 설비·태그 정의, 사용자, 대시보드가 사라진다 |
| Cassandra | 최근 62일 데이터가 사라진다 |
| Iceberg / 오브젝트 스토리지 | 장기 이력이 사라진다 |
절차는 백업 및 복구 를 보세요.