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)
| 속성 | 타입 | 설명 |
|---|---|---|
id | string | 엔티티 식별자 |
name | string | 엔티티 이름 |
weight | double | 인과관계 가중치 (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.json의 ConnectionStrings: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>();
초기화 플로우
-
스키마 초기화:
InitializeSchemaAsync(schemaTql)호출deploy/typedb/schema.tql파일 내용을 전달- TypeDB 세션 타입:
SessionType.Schema - 트랜잭션 타입:
TransactionType.Write
-
매니페스트 데이터 삽입:
InsertManifestDataAsync(query)EquipmentManifest를 TypeQL INSERT 쿼리로 변환 (TypeDbMapper.cs)- TypeDB 세션 타입:
SessionType.Data - 트랜잭션 타입:
TransactionType.Write
-
쿼리 실행:
GetRelatedTagsAsync(triggerTagId)- TypeDB 세션 타입:
SessionType.Data - 트랜잭션 타입:
TransactionType.Read
- TypeDB 세션 타입:
활용 사례
알람 전파 (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");
관련 문서
- Configuration 가이드 — TypeDB 연결 설정