본문으로 건너뛰기

TypeDB 스키마

개요

Caffeine은 TypeDB를 사용하여 제조 현장의 장비(Equipment), 태그(Tag/Sensor), 그리고 이들 간의 인과관계(Causality)를 지식 그래프(Knowledge Graph) 형태로 모델링합니다. 이를 통해 다음과 같은 기능을 제공합니다:

  • 연관 태그 추론: 특정 태그에 알람이 발생했을 때, 인과관계로 연결된 다른 태그들을 자동으로 조회
  • 장비 구성 관리: 장비와 그에 속한 태그들의 계층 구조 표현
  • 가중치 기반 관계: 태그 간 인과관계의 강도를 weight 속성으로 표현 (0.0 ~ 1.0)

TypeDB는 논리적 추론과 복잡한 관계 쿼리에 최적화된 그래프 데이터베이스로, Caffeine의 알람 전파 및 근본 원인 분석(Root Cause Analysis) 기능을 지원합니다.

스키마 정의

스키마는 deploy/typedb/schema.tql 파일에 TypeQL(TypeDB Query Language) 형식으로 정의되어 있습니다.

속성 타입 (Attributes)

속성타입설명
idstring엔티티 식별자
namestring엔티티 이름
weightdouble인과관계 가중치 (0.0 ~ 1.0)

엔티티 타입 (Entities)

equipment (장비)

제조 현장의 물리적 장비를 나타내는 엔티티입니다.

equipment sub entity,
owns id,
owns name,
plays composition:owner;

속성:

  • id: 장비 고유 식별자
  • name: 장비 이름

역할:

  • composition:owner — 태그를 소유하는 장비 역할

tag (태그/센서)

장비에서 수집되는 데이터 포인트(센서, 신호)를 나타내는 엔티티입니다.

tag sub entity,
owns id @key, # 태그 ID는 고유 키
owns name,
plays composition:part,
plays causality:cause, # 원인이 될 수 있는 태그
plays causality:effect; # 결과가 될 수 있는 태그

속성:

  • id (@key): 태그 고유 식별자 (중복 불가)
  • name: 태그 논리명

역할:

  • composition:part — 장비에 속하는 태그 역할
  • causality:cause — 다른 태그의 원인이 되는 역할
  • causality:effect — 다른 태그의 결과가 되는 역할

관계 타입 (Relations)

composition (구성 관계)

장비와 태그 간의 소유/포함 관계를 나타냅니다.

composition sub relation,
relates owner,
relates part;

역할:

  • owner: 장비 (equipment)
  • part: 태그 (tag)

의미: "장비 A는 태그 B를 포함한다"

causality (인과 관계)

태그 간의 원인-결과 관계를 나타내며, 알람 전파 및 근본 원인 분석에 사용됩니다.

causality sub relation,
owns weight,
relates cause,
relates effect;

속성:

  • weight: 인과관계 강도 (0.0 = 약한 연관성, 1.0 = 강한 연관성)

역할:

  • cause: 원인이 되는 태그
  • effect: 결과로 나타나는 태그

의미: "태그 A가 변화하면 태그 B가 영향을 받는다 (가중치 0.8)"

스키마 다이어그램

쿼리 예제

1. 스키마 초기화

define

# 속성 정의
id sub attribute, value string;
name sub attribute, value string;
weight sub attribute, value double;

# 엔티티 정의
equipment sub entity,
owns id,
owns name,
plays composition:owner;

tag sub entity,
owns id @key,
owns name,
plays composition:part,
plays causality:cause,
plays causality:effect;

# 관계 정의
composition sub relation,
relates owner,
relates part;

causality sub relation,
owns weight,
relates cause,
relates effect;

2. 장비 및 태그 삽입

insert
$eq isa equipment, has id "EQ001", has name "Furnace #1";
$tag1 isa tag, has id "TEMP_001", has name "Temperature Sensor";
$tag2 isa tag, has id "PRESSURE_001", has name "Pressure Sensor";
(owner: $eq, part: $tag1) isa composition;
(owner: $eq, part: $tag2) isa composition;

3. 인과관계 삽입

insert
$cause isa tag, has id "TEMP_001";
$effect isa tag, has id "PRESSURE_001";
(cause: $cause, effect: $effect) isa causality, has weight 0.85;

4. 연관 태그 조회 (실제 서비스 코드)

특정 태그에 알람이 발생했을 때, 인과관계로 연결된 영향받는 태그를 조회합니다.

match
$x isa tag, has id "TEMP_001";
$rel (cause: $x, effect: $y) isa causality;
$y isa tag, has id $rid;
get $rid;

설명:

  • $x: 원인 태그 (id = "TEMP_001")
  • $y: 결과 태그 (영향을 받는 태그)
  • $rid: 결과 태그의 ID 반환

C# 구현 예시 (TypeDbRealClient.cs):

public virtual Task<List<string>> GetRelatedTagsAsync(string triggerTagId)
{
string query = $@"
match
$x isa tag, has id ""{triggerTagId}"";
$rel (cause: $x, effect: $y) isa causality;
$y isa tag, has id $rid;
get $rid;
";

var queryResult = tx.Query.Get(query);
var results = queryResult
.Select(cm => cm.Get("rid")?.AsAttribute()?.Value?.AsString())
.Where(id => !string.IsNullOrEmpty(id))
.ToList();

return Task.FromResult(results);
}

5. 특정 장비의 모든 태그 조회

match
$eq isa equipment, has id "EQ001";
$rel (owner: $eq, part: $tag) isa composition;
$tag has id $tid, has name $tname;
get $tid, $tname;

6. 가중치가 높은 인과관계 조회

match
$rel (cause: $c, effect: $e) isa causality, has weight $w;
$c has id $cid;
$e has id $eid;
$w > 0.8;
get $cid, $eid, $w;

데이터베이스 설정

연결 정보

TypeDB 연결 문자열은 appsettings.jsonConnectionStrings:TypeDB에 정의됩니다.

{
"ConnectionStrings": {
"TypeDB": "localhost:1729"
}
}

기본값:

  • Host: localhost (Docker 배포 시 typedb)
  • Port: 1729 (TypeDB Core 기본 포트)
  • Database: caffeine_db (Infrastructure), caffeine_kb (Engine)

서비스 등록

InfrastructureExtensions.cs에서 DI 컨테이너에 등록됩니다:

services.AddSingleton<ITypeDbService, TypeDbRealClient>();

초기화 플로우

  1. 스키마 초기화: InitializeSchemaAsync(schemaTql) 호출

    • deploy/typedb/schema.tql 파일 내용을 전달
    • TypeDB 세션 타입: SessionType.Schema
    • 트랜잭션 타입: TransactionType.Write
  2. 매니페스트 데이터 삽입: InsertManifestDataAsync(query)

    • EquipmentManifest를 TypeQL INSERT 쿼리로 변환 (TypeDbMapper.cs)
    • TypeDB 세션 타입: SessionType.Data
    • 트랜잭션 타입: TransactionType.Write
  3. 쿼리 실행: GetRelatedTagsAsync(triggerTagId)

    • TypeDB 세션 타입: SessionType.Data
    • 트랜잭션 타입: TransactionType.Read

활용 사례

알람 전파 (Alarm Propagation)

특정 태그에서 알람이 발생했을 때, causality 관계를 따라 연관된 태그들을 조회하여 연쇄 알람 발생 여부를 예측합니다.

// "TEMP_001" 태그 알람 발생 시
var relatedTags = await typeDbService.GetRelatedTagsAsync("TEMP_001");
// 결과: ["PRESSURE_001", "FLOW_002"] 등

근본 원인 분석 (Root Cause Analysis)

여러 알람이 동시에 발생했을 때, causality 관계의 방향(cause → effect)을 역추적하여 근본 원인 태그를 식별합니다.

match
$effect isa tag, has id "ALARM_TAG_ID";
$rel (cause: $root, effect: $effect) isa causality;
$root isa tag, has id $rid;
get $rid;

장비 토폴로지 시각화

composition 관계를 통해 장비와 태그의 계층 구조를 조회하여 UI에 트리뷰 형태로 표시합니다.

성능 및 장애 복구

Fail-Safe 설계

TypeDB 연결 실패 시, Caffeine 서비스는 중단되지 않고 로그 기록 후 빈 결과 반환으로 처리됩니다.

catch (Exception ex)
{
_logger.LogError(ex, "Error querying related tags for {TriggerId}", triggerTagId);
// 빈 리스트 반환 (Fail-Safe)
}

Health Check

TypeDB 연결 상태는 TypeDbHealthCheck.cs를 통해 모니터링됩니다.

services.AddHealthChecks()
.AddCheck<TypeDbHealthCheck>("typedb");

관련 문서

참고 자료