같은 사실, 다른 출처: Named Graph로 신뢰의 경계를 긋다
by Justin Kim
1. 김철수의 상충하는 프로필
이번에는 유사한 상황에서 Reification이 답이 아닌 상황, 그래서 Named Graph를 사용해야 하는 상황이 있다는 것을 이야기해보려고 합니다.
Knowledge Graph를 구축하다 보면, 서로 다른 출처에서 가져온 데이터가 충돌하는 상황을 자주 만납니다. 앞의 Reification에서 다룬 예시와 유사하지만, 이번에는 Reification이 답이 아닌 상황을 다룹니다.
헤드헌터가 김철수의 인재 데이터베이스를 조회하니 다음과 같은 정보가 나옵니다.
HR 시스템: 김철수는 네이버 재직 중 LinkedIn 프로필: 김철수는 삼성전자 Senior Engineer
두 출처가 서로 다른 이야기를 합니다. LinkedIn 프로필은 이직 후 업데이트되지 않았을 가능성이 높지만, 데이터만 보면 구분이 안 됩니다. 어느 쪽을 믿어야 할까요?
기본 RDF 트리플로 표현하면 이렇게 됩니다.
ex:김철수 ex:worksAt ex:네이버 .
ex:김철수 ex:worksAt ex:삼성전자 .
Reification을 사용하면 각 트리플에 ex:source "HR 시스템", ex:source "LinkedIn" 같은 메타데이터를 붙일 수 있습니다. 하지만 현실의 Knowledge Graph에는 수만, 수억 개의 트리플이 있고, 하나하나 Reify하면 트리플 수가 4~7배로 폭발합니다.
더 중요한 문제는, 출처는 개별 트리플이 아니라 데이터셋 단위의 속성이라는 점입니다. HR 시스템에서 가져온 1만 개의 트리플은 모두 “HR 시스템에서 2026년 2월 20일에 수집”이라는 출처 정보를 공유합니다. 각 트리플마다 같은 출처 정보를 중복해서 붙일 필요가 없습니다. 즉, 이러한 경우에는 Reification은 적절한 해결책이라고 할 수 없습니다.
여기서 Named Graph가 등장합니다. 트리플을 개별적으로 관리하는 대신, 관련된 트리플들을 하나의 그래프로 묶고, 그 그래프에 출처 정보를 부여하는 방식입니다.
2. Named Graph란 무엇인가
RDF의 기본 단위는 트리플(Triple): 주어(Subject) – 술어(Predicate) – 목적어(Object)입니다. Named Graph는 여기에 네 번째 요소를 추가합니다. 바로 그래프 이름(Graph Name)입니다.
트리플 하나에 그래프 이름을 더하면 쿼드(Quad, S-P-O-G)가 됩니다. 같은 그래프 이름을 가진 쿼드들을 모으면 하나의 Named Graph가 됩니다. 그리고 이 Named Graph는 IRI로 식별되는 자원이므로, 그래프 자체에 대해 “출처는 어디인가”, “언제 수집했는가”, “신뢰도는 얼마인가” 같은 메타데이터를 붙일 수 있습니다.
RDF 1.1[1]에서는 이를 RDF Dataset이라는 구조로 정의합니다. RDF Dataset은 하나의 Default Graph(이름이 없는 기본 그래프)와 0개 이상의 Named Graph로 구성됩니다.
| 요소 | 설명 |
|---|---|
| Triple (S-P-O) | 주어-술어-목적어, RDF의 기본 단위 |
| Quad (S-P-O-G) | 트리플 + 그래프 이름, Named Graph의 단위 |
| Default Graph | 이름이 없는 기본 그래프 (메타데이터 기록 용도) |
| Named Graph | IRI로 이름이 붙은 그래프, 메타데이터 부여 가능 |
| RDF Dataset | Default Graph + Named Graph들의 집합 |
비유하자면, 개별 서류(트리플)에 하나하나 도장을 찍는 것(Reification)이 아니라, 서류를 폴더(Named Graph)에 넣고 폴더 겉표지에 “출처: HR팀, 수집일: 2026-02-20, 신뢰도: 높음”이라고 적는 것입니다. 폴더 안의 모든 서류는 자동으로 같은 출처 정보를 공유합니다.
3. TriG 문법으로 표현하기
Named Graph를 표현하는 표준 문법이 TriG[2]입니다. TriG는 Turtle의 확장으로, GRAPH_IRI { ... } 블록으로 트리플을 그래프에 묶을 수 있습니다.
김철수 시나리오를 TriG로 표현해 보겠습니다.
@prefix ex: <http://example.org/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
# ── HR 시스템에서 가져온 데이터 (Named Graph 1) ──
ex:graph/hr {
ex:김철수 a ex:Person ;
ex:name "김철수" ;
ex:worksAt ex:네이버 .
ex:네이버 a ex:Company ;
ex:name "네이버" .
}
# ── LinkedIn에서 크롤링한 데이터 (Named Graph 2) ──
ex:graph/linkedin {
ex:김철수 ex:worksAt ex:삼성전자 ;
ex:jobTitle "Senior Engineer" .
ex:삼성전자 a ex:Company ;
ex:name "삼성전자" .
}
# ── 그래프 메타데이터 (Default Graph에 기록) ──
ex:graph/hr
ex:source "사내 HR 시스템" ;
ex:retrievedAt "2026-02-20"^^xsd:date ;
ex:trustLevel 3 .
ex:graph/linkedin
ex:source "LinkedIn 크롤링" ;
ex:retrievedAt "2026-01-15"^^xsd:date ;
ex:trustLevel 2 .
핵심을 정리하면 이렇습니다.
ex:graph/hr { ... }블록 안의 모든 트리플은ex:graph/hr라는 Named Graph에 속합니다.- 그래프 이름(
ex:graph/hr,ex:graph/linkedin) 자체도 IRI이므로, Default Graph에서 이들에 대한 메타데이터를 기술할 수 있습니다. trustLevel을 숫자로 표현하여, 신뢰도 순서를 명확히 할 수 있습니다. 3(높음), 2(중간)처럼 숫자가 클수록 신뢰도가 높습니다.
TriG는 Turtle을 아는 사람이라면 쉽게 배울 수 있습니다. Turtle 문법에 { } 블록만 추가하면 됩니다.
4. 시각화: Named Graph가 만드는 구조
아래 다이어그램은 Named Graph가 적용된 김철수의 프로필 데이터를 시각화한 것입니다. 두 개의 독립된 그래프가 각각의 출처 정보와 함께 관리되는 구조를 보여줍니다.
두 개의 Named Graph(ex:graph/hr, ex:graph/linkedin)가 점선 경계로 구분되어 있습니다. 각 그래프는 독립된 트리플 집합이며, Default Graph에 기록된 메타데이터를 통해 출처, 수집 시점, 신뢰도 정보를 가집니다. 이 구조 덕분에 같은 개체(김철수)에 대한 서로 다른 정보를 출처별로 분리하여 관리할 수 있습니다.
5. SPARQL로 질의하기: GRAPH의 힘
Named Graph의 진가는 SPARQL[3]에서 정의하는 GRAPH 키워드를 사용할 때 드러납니다. GRAPH 패턴을 사용하면 “어느 Named Graph 안에서” 트리플을 매칭할지 지정할 수 있습니다.
쿼리 1: 신뢰도 높은 출처에서 김철수의 현재 직장 찾기
PREFIX ex: <http://example.org/>
SELECT ?company ?source ?trust WHERE {
GRAPH ?g {
ex:김철수 ex:worksAt ?company .
}
?g ex:trustLevel ?trust .
?g ex:source ?source .
}
ORDER BY DESC(?trust)
결과:
| ?company | ?source | ?trust |
|---|---|---|
| ex:네이버 | “사내 HR 시스템” | 3 |
| ex:삼성전자 | “LinkedIn 크롤링” | 2 |
GRAPH ?g { ... } 패턴은 “어떤 Named Graph 안에서든” 패턴에 매칭되는 트리플을 찾습니다. 그래프 변수 ?g를 통해 그래프의 메타데이터(trustLevel, source)에 접근할 수 있습니다. ORDER BY DESC(?trust)로 신뢰도가 높은 순서로 정렬하면, 가장 믿을 만한 정보가 먼저 나옵니다. 이제 헤드헌터는 “네이버”를 김철수의 현재 직장으로 판단할 수 있습니다.
쿼리 2: 특정 출처의 데이터만 조회
PREFIX ex: <http://example.org/>
SELECT ?s ?p ?o WHERE {
GRAPH ex:graph/hr {
?s ?p ?o .
}
}
그래프 IRI를 직접 지정하면, 해당 출처의 데이터만 필터링할 수 있습니다. 수억 개의 트리플이 있어도 그래프 단위로 범위를 좁힐 수 있으므로, 쿼리 성능에도 유리합니다. “HR 시스템이 말하는 정보만 보고 싶다”는 요구사항을 단 한 줄의 GRAPH 절로 해결할 수 있습니다.
쿼리 3: 오래된 출처 데이터 탐지
PREFIX ex: <http://example.org/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT DISTINCT ?g ?source ?date WHERE {
GRAPH ?g { ?s ?p ?o . }
?g ex:retrievedAt ?date ;
ex:source ?source .
FILTER (?date < "2026-02-01"^^xsd:date)
}
이 쿼리는 2월 1일 이전에 수집된 그래프를 찾습니다. LinkedIn 그래프(2026-01-15 수집)가 결과에 나타나므로, “이 데이터는 오래되었으니 재수집이 필요하다”는 판단을 내릴 수 있습니다. Named Graph는 단순히 출처를 기록하는 것을 넘어, 데이터의 신선도(freshness)를 관리하는 도구가 됩니다.
6. Reification과 Named Graph: 언제 무엇을
이전 글에서 배운 Reification과 Named Graph는 경쟁이 아니라 보완 관계입니다. 두 기법이 해결하는 문제가 다르기 때문입니다.
| 기준 | Reification | Named Graph |
|---|---|---|
| 메타데이터 대상 | 개별 트리플 | 트리플 묶음(그래프) |
| 추가 트리플 수 | 트리플당 4~7개 | 그래프당 수 개 (내부 트리플 수에 무관) |
| 출처 관리 | 트리플마다 ex:source 부착 |
그래프에 한 번만 ex:source |
| 시간 맥락 | 트리플마다 시간 메타데이터 | 그래프 단위 시점 기록 (스냅샷) |
| SPARQL 패턴 | ?stmt a rdf:Statement |
GRAPH ?g { ... } |
| 적합한 용도 | 특정 트리플에 세밀한 메타데이터 | 데이터셋 단위 출처/버전/접근 관리 |
| 확장성 | 대규모에서 트리플 폭발 | 대규모에서 효율적 |
| 표준 | RDF 1.1 (rdf:Statement) | RDF 1.1 (RDF Dataset) |
언제 무엇을 사용할 것인가?
- 특정 트리플 하나에 세밀한 시간 정보나 확신도를 붙여야 한다면 → Reification (또는 RDF-star)
- 데이터셋 전체 또는 일부를 출처, 버전, 접근 권한 단위로 관리해야 한다면 → Named Graph
- 실무에서는 두 기법을 함께 사용하는 것이 일반적입니다. 예를 들어, Named Graph로 출처를 관리하면서, 그 안의 특정 트리플에만 Reification을 적용하여 추가 맥락을 기록할 수 있습니다.
7. 실전 활용: 버전, 접근 제어, 신뢰
Named Graph는 실무 Knowledge Graph에서 다양한 방식으로 활용됩니다. 대표적인 세 가지 사례를 소개합니다.
7.1 데이터 버전 관리 (Temporal Snapshots)
시점마다 Named Graph를 만들어 스냅샷을 관리할 수 있습니다. 예를 들어 ex:graph/employees/2026-Q1, ex:graph/employees/2025-Q4처럼 분기별 그래프를 두면, 특정 시점의 조직도를 통째로 조회하거나, 시점 간 변화를 비교할 수 있습니다. 이는 “이번 분기에 누가 입사했는가”나 “작년 대비 팀 구성이 어떻게 변했는가” 같은 질문에 답하는 데 유용합니다.
7.2 접근 제어 (Access Control)
Named Graph 단위로 읽기/쓰기 권한을 설정할 수 있습니다. 예를 들어 ex:graph/public은 누구나 조회 가능, ex:graph/internal은 사내 직원만, ex:graph/hr-confidential은 HR팀만 접근 가능하도록 설정합니다. GraphDB나 Stardog 같은 트리플스토어에서는 그래프 단위 ACL(Access Control List)을 지원하므로, 민감한 데이터를 별도 그래프로 분리하여 보호할 수 있습니다.
다만 주의할 점이 있습니다. 모든 트리플스토어가 Named Graph를 물리적으로 분리하여 저장하는 것은 아닙니다. 예를 들어 Apache Jena의 TDB 엔진은 모든 그래프의 트리플을 동일한 인덱스에 저장하므로, Named Graph 이름만으로는 물리적 접근 제어가 보장되지 않습니다. Named Graph 기반 접근 제어를 도입할 때는 사용하는 트리플스토어의 구현 방식을 반드시 확인해야 합니다.
7.3 신뢰 점수 기반 추론 (Trust-aware Reasoning)
앞의 김철수 시나리오가 정확히 이 패턴입니다. 여러 출처가 상충하는 정보를 제공할 때, 각 그래프에 trustLevel을 부여하고, 추론 엔진이나 쿼리 로직이 신뢰도가 높은 쪽을 우선하도록 설계할 수 있습니다. 이는 외부 크롤링 데이터, 사용자 입력, 자동 추론 결과 등 신뢰도가 다른 데이터 소스를 통합할 때 필수적입니다.
8. 마치며
Reification이 “트리플에 대해 말하기”였다면, Named Graph는 “트리플 묶음에 이름을 붙이기”입니다. 현실 세계의 데이터는 항상 어딘가에서 옵니다. 누가 만들었는지, 언제 수집했는지, 얼마나 믿을 수 있는지. Named Graph는 이 질문들에 답할 수 있는 구조를 RDF에 부여합니다.
하지만 기법을 아는 것보다 더 중요한 것은, 어디에 온톨로지를 적용할 것인가를 결정하는 일입니다. Reification이든 Named Graph든, 결국 도메인 지식을 바탕으로 “이 데이터에서 무엇이 중요한가”, “어떤 맥락을 보존해야 하는가”를 판단하는 것이 온톨로지 설계의 핵심입니다. 기법은 도구일 뿐, 도메인에 대한 깊은 이해 없이는 어떤 도구도 올바르게 쓸 수 없습니다.
서로 다른 출처의 정보를 통합할 때, “어느 쪽을 믿어야 하는가”라는 질문에 부딪혔다면 Named Graph를 떠올려 보세요. 트리플을 그래프 단위로 묶는 순간, Knowledge Graph는 비로소 신뢰의 경계를 그을 수 있게 됩니다.
관련 글
- 시간이 흐르면 사실도 변한다: RDF Reification으로 맥락 기록하기
- S-P-O 분해 연습문제 풀이: 전력 모듈-센서 노이즈 간섭
- iCalendar의 진화: 텍스트에서 의미론적 웹으로
참고 문헌
- R. Cyganiak, D. Wood, and M. Lanthaler, “RDF 1.1 Concepts and Abstract Syntax,” W3C, W3C Recommendation, Feb. 2014. Available at: https://www.w3.org/TR/rdf11-concepts/
- G. Carothers and A. Seaborne, “RDF 1.1 TriG: RDF Dataset Language,” W3C, W3C Recommendation, Feb. 2014. Available at: https://www.w3.org/TR/trig/
- S. Harris and A. Seaborne, “SPARQL 1.1 Query Language,” W3C, W3C Recommendation, Mar. 2013. Available at: https://www.w3.org/TR/sparql11-query/
Subscribe via RSS
Comments