
SHACL-DS 완전 해부 — RDF '데이터셋' 검증의 새로운 지평 (ESWC 2026)
SHACL은 RDF 그래프 하나만 검증할 수 있었다. 그런데 현실의 데이터는 여러 개의 Named Graph로 나뉘어 있다. ESWC 2026에서 발표된 SHACL-DS는 이 gap을 메우는 최초의 체계적 확장이다.

SHACL은 RDF 그래프 하나만 검증할 수 있었다. 그런데 현실의 데이터는 여러 개의 Named Graph로 나뉘어 있다. ESWC 2026에서 발표된 SHACL-DS는 이 gap을 메우는 최초의 체계적 확장이다.
SHACL은 RDF 데이터의 품질을 검증하는 W3C 표준이다. 2017년 권고안이 된 이래, 지식 그래프 생태계의 핵심 인프라로 자리 잡았다. 그런데 SHACL에는 아무도 공식적으로 다루지 않았던 사각지대가 있었다.
SHACL은 RDF "그래프"만 검증할 수 있다. RDF "데이터셋"은 검증할 수 없다.
이게 왜 문제일까? 현실 세계의 RDF 데이터를 떠올려 보자.

기업의 지식 그래프에는 보통 여러 개의 Named Graph가 존재한다:
ex:hrGraph — 인사 데이터 (직원 정보, 부서)ex:financeGraph — 재무 데이터 (급여, 예산)ex:accessControlGraph — 접근 권한 데이터ex:provenanceGraph — 데이터 출처 메타데이터이 4개의 그래프는 각각 다른 규칙으로 검증되어야 한다. 인사 데이터에는 "모든 직원에게 이메일이 있어야 한다"는 규칙이 필요하고, 재무 데이터에는 "급여는 양수여야 한다"는 규칙이 필요하다. 그리고 때로는 그래프를 넘나드는 검증도 필요하다 — "인사 데이터의 모든 직원이 접근 권한 데이터에도 등록되어 있는가?"
기존 SHACL로는 이런 검증이 불가능하다. SHACL은 하나의 데이터 그래프와 하나의 셰이프 그래프만 받아들인다.
"SHACL은 단일 그래프의 세계에 갇혀 있었다. 현실의 데이터는 이미 다중 그래프의 세계에 살고 있는데."
2025년 5월, 벨기에 리에주 대학교 Montefiore 연구소의 Davan Chiem Dao와 Christophe Debruyne는 이 문제를 정면으로 해결하는 논문을 발표했다: "From RDF Graph Validation to RDF Dataset Validation with SHACL-DS". 이 논문은 유럽 시맨틱 웹 분야의 정상급 국제학회 ESWC 2026에 채택되었다.
특히 주목할 점은, 현재 W3C에서 개발 중인 SHACL 1.2(2025~2026)조차 데이터셋 검증을 다루지 않는다는 것이다. SHACL 1.2는 추론 규칙, RDF 1.2 구문화, Node Expressions 등을 추가하지만, 근본적인 "단일 그래프 검증" 모델은 그대로 유지한다. SHACL-DS는 이 gap을 메우는 유일한 체계적 확장이다.
이 글에서는 이 논문을 완전 해부한다 — 왜 이런 확장이 필요했고, 어떤 새로운 개념을 도입했으며, 실제로 어떻게 동작하는지.
RDF의 기본 단위는 트리플(Subject-Predicate-Object) 이다. 이 트리플들의 집합이 RDF 그래프다.
단순하다. 하지만 현실은 단순하지 않다.
RDF 데이터셋(RDF Dataset) 은 W3C가 정의한 개념으로, 하나의 기본 그래프(Default Graph) 와 0개 이상의 Named Graph로 구성된다.
Named Graph는 2005년 Jeremy Carroll, Christian Bizer, Pat Hayes, Patrick Stickler가 WWW 학회에서 발표한 논문 "Named Graphs, Provenance and Trust" 에서 처음 제안되었다. 기존 RDF의 구문화(reification)가 너무 장황하고(트리플 1개에 4개의 추가 트리플 필요) 의미론이 불명확했기 때문에, 그래프에 이름(URI)을 붙여 메타데이터를 부착하자는 아이디어였다. 2014년 RDF 1.1에서 공식 표준이 되었다.
Named Graph는 왜 필요할까? 핵심적인 이유 4가지:
Named Graph를 포함한 RDF 데이터셋은 TriG 형식으로 작성한다:
# Default Graph (이름 없음)
ex:Alice a foaf:Person ;
foaf:knows ex:Zach ;
foaf:knows ex:Yara .
ex:Bob a foaf:Person ;
foaf:knows ex:Yara .
# Named Graph: City1Graph
ex:City1Graph {
ex:Charlie a foaf:Person ;
foaf:knows ex:Zach .
ex:David a foaf:Person ;
foaf:knows ex:Yara .
}
# Named Graph: goodPersonGraph
ex:goodPersonGraph {
ex:Zach a foaf:Person .
}
중괄호 {}로 감싸진 부분이 Named Graph다. 감싸지 않은 트리플은 Default Graph에 속한다.
SHACL의 검증 모델은 이렇다:
1 대 1이다. 그런데 RDF 데이터셋을 검증하려면?
N 대 M이 필요한데, SHACL에는 이 모델이 없다.
논문의 저자들은 주요 SHACL 구현체 6개를 조사했다. 결과는 놀라웠다:
| 구현체 | 데이터 데이터셋 처리 | 셰이프 데이터셋 처리 |
|---|---|---|
| Corese | 모든 그래프를 합침 (Union) | 모든 그래프를 합침 (Union) |
| pySHACL | 모든 그래프를 합침 (Union) | 모든 그래프를 합침 (Union) |
| dotNetRDF | 데이터셋 불허 | 데이터셋 불허 |
| RDFUnit | Default Graph만 사용 | Default Graph만 사용 |
| shaclex | Default Graph만 사용 | Default Graph만 사용 |
| TopBraid | Default Graph만 사용 | 데이터셋 불허 |
어떤 구현체도 Named Graph를 개별적으로 검증하지 않는다. Union을 하면 어떤 그래프에서 오류가 발생했는지 알 수 없다. Default Graph만 보면 나머지 Named Graph의 데이터는 아예 검증되지 않는다.
"어떤 트리플이 어떤 Named Graph에서 왔는지 모르면, 검증을 우회할 수 있다." — 논문의 핵심 문제 제기
이것은 단순한 불편함이 아니라 보안 취약점이다. Named Graph별로 접근 제어를 하는 시스템에서, 검증이 그래프 경계를 무시하면 데이터 무결성이 무너진다.

SHACL-DS는 기존 SHACL 위에 새로운 어휘를 추가한다:
기존 SHACL에서는 Shapes Graph(셰이프 그래프)가 검증 규칙을 담는다. SHACL-DS에서는 이를 Shapes Dataset(셰이프 데이터셋)으로 확장한다.
| 개념 | 기존 SHACL | SHACL-DS |
|---|---|---|
| 검증 대상 | Data Graph (1개) | Data Dataset (N개 그래프) |
| 검증 규칙 | Shapes Graph (1개) | Shapes Dataset (M개 셰이프 그래프) |
| 타겟 지정 | 노드/클래스/속성 단위 | 그래프 단위 + 노드/클래스/속성 단위 |
| 결과 리포트 | focusNode, resultPath | + focusGraph, sourceShapeGraph |
Shapes Dataset은 여러 셰이프 그래프를 담는 RDF 데이터셋이다. 그리고 각 셰이프 그래프가 어떤 데이터 그래프를 검증할지 선언적으로 지정한다.
SHACL-DS의 가장 핵심적인 새 기능이다. 셰이프 그래프가 검증할 대상 그래프를 지정한다.
# "이 셰이프 그래프는 모든 Named Graph를 검증한다"
ex:shapeGraph1 shds:targetGraph shds:named .
ex:shapeGraph1 {
ex:PersonMustHaveName
a sh:NodeShape ;
sh:targetClass foaf:Person ;
sh:property [
sh:path foaf:name ;
sh:minCount 1 ;
] .
}
SHACL-DS가 제공하는 미리 정의된 타겟 IRI 3가지:
특정 Named Graph의 IRI를 직접 지정할 수도 있다:
# "이 규칙은 City1Graph만 검증한다"
ex:shapeGraph2 shds:targetGraph ex:City1Graph .
"모든 그래프를 검증하되, 특정 그래프는 빼고 싶다"는 상황을 위한 메커니즘:
# 모든 그래프를 검증하되, goodPersonGraph는 제외
ex:shapeGraph1 shds:targetGraph shds:all .
ex:shapeGraph1 shds:targetGraphExclude ex:goodPersonGraph .
규칙: 포함(inclusion)이 먼저 적용되고, 그 다음 제외(exclusion)가 적용된다.
가장 강력한 기능이다. 집합 연산으로 여러 그래프를 조합하여 검증 대상으로 삼는다.
예를 들어, "Graph1과 Graph2의 합집합에서 Graph3의 데이터를 뺀 것"을 검증 대상으로 지정할 수 있다:
ex:shapeGraph1 shds:targetGraphCombination
[ shds:minus (
[ shds:or ( ex:g1 ex:g2 ) ]
ex:g3
) ] .
이 조합 기능 덕분에, 복잡한 다중 그래프 시나리오에서도 정확한 검증 범위를 선언적으로 지정할 수 있다.
기존 SHACL의 Focus Node(검증 대상 노드)에 대응하는 개념이다. SHACL-DS에서는 검증 대상 그래프를 Focus Graph라 부른다.
| SHACL 개념 | 기존 SHACL | SHACL-DS 대응 |
|---|---|---|
| 검증 대상 | Focus Node | Focus Graph |
| 규칙 출처 | sh:sourceShape | shds:sourceShapeGraph |
| 대상 지정 | sh:targetNode/Class | shds:targetGraph |
| 오류 위치 | sh:focusNode + sh:resultPath | shds:focusGraph + sh:focusNode |
아래 시뮬레이터에서 타겟 그래프를 바꿔가며 데이터셋 검증이 어떻게 동작하는지 직접 확인해 보자:
SHACL-SPARQL 확장에서는 SPARQL 쿼리를 제약 조건으로 사용할 수 있다. 그런데 Named Graph 환경에서 이 쿼리의 실행 맥락(context) 은 어떻게 되어야 할까?
논문에서 제시한 예시를 보자:
SELECT DISTINCT $this WHERE {
$this a foaf:Person .
FILTER NOT EXISTS {
GRAPH ex:goodPersonGraph { ?goodPerson a foaf:Person . }
$this foaf:knows ?goodPerson .
}
}
이 쿼리는 GRAPH 키워드로 다른 Named Graph를 참조한다. 기존 SHACL에서는 이 동작이 정의되지 않았다.
논문은 명확한 규칙 2가지를 제시한다:
규칙 2의 변환 로직이 논문의 기술적 핵심이다:
이 변환 덕분에, 기존 SHACL용으로 작성된 SPARQL 쿼리를 수정 없이 재사용할 수 있다. 쿼리 입장에서 타겟 그래프는 항상 Default Graph처럼 보이기 때문이다.
논문의 데이터와 규칙을 사용하여 검증 과정을 추적해 보자.
데이터셋:
| 그래프 | 데이터 |
|---|---|
| Default Graph | Alice → knows Zach, Yara / Bob → knows Yara |
| ex:City1Graph | Charlie → knows Zach / David → knows Yara |
| ex:goodPersonGraph | Zach는 Person |
셰이프: "모든 Person은 goodPerson을 최소 1명 알아야 한다"
타겟: shds:all (goodPersonGraph 제외)
검증 과정:
핵심은 focusGraph 필드다. 기존 SHACL 리포트에서는 Bob과 David의 오류가 어떤 그래프에서 발생했는지 알 수 없었다. SHACL-DS에서는 이 정보가 리포트에 명시된다.
SHACL-DS는 검증 리포트에 두 가지 새로운 필드를 추가한다:
| 필드 | 의미 | 기존 SHACL 대응 |
|---|---|---|
shds:focusGraph | 오류가 발생한 데이터 그래프 | (없었음) |
shds:sourceShapeGraph | 규칙이 정의된 셰이프 그래프 | sh:sourceShape (노드 단위) |
이 두 필드 덕분에, 대규모 RDF 데이터셋에서 오류가 발생했을 때 "어떤 그래프의 어떤 노드가 어떤 셰이프의 어떤 규칙을 위반했는지" 완벽하게 추적할 수 있다.
SHACL-DS의 아이디어가 완전히 새로운 것은 아니다. 2021년, Apache Jena의 핵심 개발자 Andy Seaborne이 SHACL-X를 제안한 바 있다. SHACL-DS는 이를 기반으로 더 발전시킨 것이다.
| 측면 | SHACL-X (2021) | SHACL-DS (2025) |
|---|---|---|
| 구현체 | 없음 (이론만) | 있음 (dotNetRDF 기반 프로토타입) |
| 타겟 그래프 조합 | shx:union만 지원 | or, and, minus 전체 집합 연산 |
| 그래프 패턴 | targetGraphPattern 지원 | 미포함 (향후 연구) |
| 셰이프 공유 | shx:include 지원 | 미포함 (향후 연구) |
| SPARQL 맥락 | 정의 불명확 | 데이터셋 뷰 변환 규칙 명확화 |
| 학술 검증 | 제안서 수준 | ESWC 2026 채택 |
SHACL-DS의 가장 큰 차별점은 구현체가 존재한다는 것이다. 이론과 실제를 함께 검증했다.
SHACL-DS는 dotNetRDF의 SHACL 모듈을 확장하여 구현되었다:
# 빌드
dotnet build src/SHACL-DS.cli/SHACL-DS.cli.csproj
# 검증 실행
dotnet run --project src/SHACL-DS.cli \
--data test-cases/data.trig \
--shapes test-cases/shapes.trig \
--report
핵심 설계 원칙: 기존 SHACL 엔진을 수정 없이 재사용한다. SHACL-DS는 표준 SHACL 검증을 "감싸는" 레이어로 동작하여, 어떤 SHACL 엔진 위에도 올릴 수 있다.
SaaS 플랫폼에서 각 고객사의 데이터를 Named Graph로 분리하는 경우. 고객사 A의 데이터에는 엄격한 검증 규칙을, 고객사 B에는 완화된 규칙을 적용해야 한다.
# Shapes Dataset
ex:strictShapes shds:targetGraph ex:customerA .
ex:relaxedShapes shds:targetGraph ex:customerB .
외부에서 수집한 데이터와 내부에서 생성한 데이터를 다른 강도로 검증:
# 외부 데이터는 엄격하게
ex:externalValidation shds:targetGraph ex:externalData .
ex:externalValidation shds:targetGraph ex:crawledData .
# 내부 데이터는 기본 규칙만
ex:internalValidation shds:targetGraph ex:internalData .
주간 스냅샷이 각각 Named Graph로 저장된 경우, 최신 2주 데이터만 검증:
ex:recentValidation shds:targetGraphCombination
[ shds:or ( ex:week2026_14 ex:week2026_15 ) ] .
LLM이 추출한 트리플을 Named Graph로 격리하고, SHACL-DS로 그래프 단위 품질 검증:
shx:include로 여러 Shapes Dataset 간 셰이프 재사용SHACL은 2017년 탄생 이래, 의도적으로 단일 그래프 검증에 초점을 맞췄다. 단순함이 강점이었다. 하지만 9년이 지난 2026년, 현실의 지식 그래프는 이미 다중 그래프 세계에 살고 있다.
SHACL-DS는 이 gap을 메우는 첫 번째 체계적 시도다. 기존 SHACL을 깨뜨리지 않으면서, 데이터셋 레벨의 검증을 가능하게 한다. 셰이프 데이터셋, 타겟 그래프 선언, 집합 연산 기반 그래프 조합, 확장된 검증 리포트 — 모두 기존 SHACL의 철학을 존중하면서 확장한 것이다.
"SHACL이 단일 그래프의 면역 체계였다면, SHACL-DS는 전체 데이터셋의 면역 체계다."