프로퍼티 그래프와 RDF의 차이, 노드/엣지/속성 설계 원칙, 온톨로지 설계부터 실전 도메인 모델링까지 지식 그래프의 데이터 모델링 기초를 다룹니다.
지식 그래프를 구현할 때 선택해야 하는 첫 번째 결정은 데이터 모델입니다. 현재 업계에서 널리 사용되는 모델은 두 가지입니다.
프로퍼티 그래프는 노드와 관계 모두에 **속성(key-value 쌍)**을 직접 부착할 수 있는 모델입니다. Neo4j, Amazon Neptune(openCypher 모드), Memgraph 등이 이 모델을 사용합니다.
// 노드 생성 - 속성을 직접 부착
CREATE (p:Person {name: "김개발", role: "Backend Engineer", experience: 5})
CREATE (t:Technology {name: "Neo4j", category: "Database", version: "5.x"})
// 관계 생성 - 관계에도 속성 부착 가능
CREATE (p)-[:USES {since: 2023, proficiency: "advanced"}]->(t)프로퍼티 그래프의 특징을 정리하면 다음과 같습니다.
RDF는 W3C 표준으로, 모든 정보를 (주어, 술어, 목적어) 형태의 트리플로 표현합니다. Amazon Neptune(SPARQL 모드), Apache Jena, Stardog 등이 RDF를 지원합니다.
@prefix ex: <http://example.org/> .
@prefix schema: <http://schema.org/> .
ex:김개발 a schema:Person ;
schema:name "김개발" ;
schema:jobTitle "Backend Engineer" ;
ex:uses ex:Neo4j .
ex:Neo4j a schema:SoftwareApplication ;
schema:name "Neo4j" ;
schema:applicationCategory "Database" .RDF의 핵심 특징은 다음과 같습니다.
| 기준 | 프로퍼티 그래프 | RDF |
|---|---|---|
| 속성 저장 | 노드/관계에 직접 부착 | 별도 트리플로 표현 |
| 쿼리 언어 | Cypher, Gremlin | SPARQL |
| 표준화 | 사실상 표준 (de facto) | W3C 공식 표준 |
| 스키마 | 유연 (스키마리스 가능) | 온톨로지 기반 (엄격) |
| 주요 용도 | 애플리케이션 개발, AI/ML | 데이터 통합, 시맨틱 웹 |
| 학습 곡선 | 낮음 | 높음 |
AI/ML 파이프라인과 GraphRAG 구현에는 프로퍼티 그래프가 주로 사용됩니다. 이 시리즈에서도 프로퍼티 그래프 모델을 중심으로 진행합니다. RDF는 의료, 공공 데이터 등 표준 온톨로지가 중요한 도메인에서 강점을 발휘합니다.
노드로 만들 대상을 결정하는 것이 모델링의 첫 단계입니다. 일반적인 기준은 다음과 같습니다.
레이블은 노드의 타입을 나타냅니다. 효과적인 레이블 설계 규칙은 다음과 같습니다.
// 좋은 예: 구체적이고 단수형
CREATE (p:Person {name: "김개발"})
CREATE (t:Technology {name: "Neo4j"})
CREATE (c:Company {name: "Kreath Lab"})
// 나쁜 예: 너무 일반적이거나 복수형
CREATE (n:Node {name: "김개발"}) // 너무 일반적
CREATE (p:People {name: "김개발"}) // 복수형 사용
CREATE (t:Thing {name: "Neo4j"}) // 의미 없는 레이블레이블 설계의 핵심 원칙을 정리합니다.
Person, Technology, CompanyPerson (People 아님)(:Person:Author), (:Technology:Database)관계 타입은 두 노드 간의 연결 의미를 명확히 전달해야 합니다.
// 좋은 예: 동사형, 구체적, 방향 명확
(person)-[:WORKS_AT]->(company)
(person)-[:AUTHORED]->(article)
(article)-[:REFERENCES]->(technology)
(technology)-[:DEPENDS_ON]->(technology)
// 나쁜 예: 모호하거나 너무 일반적
(person)-[:RELATED_TO]->(company) // 어떤 관계인지 불명확
(person)-[:HAS]->(article) // 소유? 작성? 읽음?WORKS_AT, AUTHORED, DEPENDS_ONRELATED_TO 대신 WORKS_AT, AUTHORED 등 구체적 이름 사용관계 자체에 메타데이터를 저장하면 풍부한 표현이 가능합니다.
// 관계에 시간, 강도, 출처 등의 속성 부여
(person)-[:USES {
since: 2023,
proficiency: "advanced",
context: "production"
}]->(technology)
(article)-[:CITES {
section: "methodology",
confidence: 0.95
}]->(paper)**Ontology(온톨로지)**는 특정 도메인에서 사용되는 개념과 관계의 형식적 정의입니다. 지식 그래프의 "스키마"에 해당하며, 데이터의 일관성과 품질을 보장합니다.
| 구성 요소 | 설명 | 예시 |
|---|---|---|
| Class(클래스) | 엔티티의 타입 정의 | Person, Technology, Document |
| Property(속성) | 클래스가 가질 수 있는 속성 | name, version, createdAt |
| Relation(관계) | 클래스 간 허용되는 관계 | Person -AUTHORED-> Document |
| Constraint(제약) | 유효성 규칙 | name은 필수, version은 문자열 |
Neo4j에서는 명시적 스키마 대신 제약 조건과 인덱스로 데이터 품질을 관리합니다.
// 유일성 제약 - 중복 방지
CREATE CONSTRAINT person_name_unique
FOR (p:Person) REQUIRE p.name IS UNIQUE;
CREATE CONSTRAINT technology_name_unique
FOR (t:Technology) REQUIRE t.name IS UNIQUE;
// 존재 제약 - 필수 속성 보장
CREATE CONSTRAINT person_name_exists
FOR (p:Person) REQUIRE p.name IS NOT NULL;
// 인덱스 - 검색 성능 최적화
CREATE INDEX person_role_index
FOR (p:Person) ON (p.role);온톨로지 설계는 처음부터 완벽하게 만들 필요가 없습니다. 반복적으로 개선하는 접근이 실전에서 더 효과적입니다. 다만, 엔티티 이름의 네이밍 규칙과 관계 방향만큼은 초기에 일관성을 확보해야 나중에 혼란을 줄일 수 있습니다.
일관된 네이밍은 지식 그래프의 품질에 직접적인 영향을 미칩니다.
| 대상 | 규칙 | 예시 |
|---|---|---|
| 노드 레이블 | PascalCase, 단수형 | Person, TechArticle |
| 관계 타입 | UPPER_SNAKE_CASE, 동사형 | AUTHORED, DEPENDS_ON |
| 속성 키 | camelCase | firstName, createdAt |
| 열거형 값 | UPPER_SNAKE_CASE | ACTIVE, DEPRECATED |
관계형 데이터베이스에서는 정규화가 기본 원칙이지만, 그래프에서는 쿼리 패턴에 맞춘 반정규화가 성능을 크게 좌우합니다.
자주 조회되는 값은 관계를 순회하지 않아도 되도록 노드에 직접 저장합니다.
// 정규화된 모델: 회사 이름을 얻으려면 순회 필요
(person)-[:WORKS_AT]->(company {name: "Kreath Lab"})
// 반정규화: 자주 조회되는 회사명을 사람 노드에도 저장
(person {name: "김개발", companyName: "Kreath Lab"})
-[:WORKS_AT]->(company {name: "Kreath Lab"})N:M 관계에 추가 속성이 필요할 때는 중간 노드를 도입합니다.
// 중간 노드를 사용한 풍부한 관계 표현
CREATE (p:Person {name: "김개발"})
CREATE (e:Experience {years: 3, level: "advanced", context: "production"})
CREATE (t:Technology {name: "Neo4j"})
CREATE (p)-[:HAS_EXPERIENCE]->(e)
CREATE (e)-[:WITH_TECHNOLOGY]->(t)실제 기술 문서를 지식 그래프로 모델링하는 예제를 통해 지금까지 배운 원칙을 적용해 보겠습니다.
// 카테고리 생성
CREATE (cat1:Category {name: "Database", description: "데이터베이스 기술"})
CREATE (cat2:Category {name: "AI", description: "인공지능 기술"})
// 기술 생성
CREATE (neo4j:Technology {name: "Neo4j", version: "5.x", type: "Graph Database"})
CREATE (graphrag:Technology {name: "GraphRAG", version: "1.0", type: "Framework"})
CREATE (python:Technology {name: "Python", version: "3.12", type: "Language"})
// 관계 설정
CREATE (neo4j)-[:BELONGS_TO]->(cat1)
CREATE (graphrag)-[:BELONGS_TO]->(cat2)
CREATE (graphrag)-[:DEPENDS_ON]->(neo4j)
CREATE (graphrag)-[:DEPENDS_ON]->(python)
// 문서와 저자
CREATE (author:Author {name: "김개발", affiliation: "Kreath Lab"})
CREATE (doc:Document {
title: "GraphRAG 실전 가이드",
publishedAt: date("2026-03-19"),
wordCount: 5000
})
CREATE (author)-[:AUTHORED]->(doc)
CREATE (doc)-[:COVERS]->(graphrag)
CREATE (doc)-[:COVERS]->(neo4j)
CREATE (author)-[:EXPERT_IN]->(graphrag)모델이 올바르게 구성되었는지 확인하는 쿼리들입니다.
// 특정 기술을 다루는 모든 문서 조회
MATCH (d:Document)-[:COVERS]->(t:Technology {name: "GraphRAG"})
RETURN d.title, t.name
// 저자의 전문 분야와 관련 문서
MATCH (a:Author {name: "김개발"})-[:EXPERT_IN]->(t:Technology)
OPTIONAL MATCH (a)-[:AUTHORED]->(d:Document)-[:COVERS]->(t)
RETURN a.name, t.name, collect(d.title) AS documents
// 기술 간 의존성 경로 탐색
MATCH path = (t1:Technology {name: "GraphRAG"})-[:DEPENDS_ON*]->(t2:Technology)
RETURN path이번 장에서는 지식 그래프의 데이터 모델링 기초를 다루었습니다.
다음 장 미리보기: 3장에서는 가장 널리 사용되는 프로퍼티 그래프 데이터베이스인 Neo4j를 본격적으로 다룹니다. 아키텍처, Cypher 쿼리 언어, 벡터 인덱스, GDS 라이브러리까지 실전에 필요한 모든 것을 살펴봅니다.
이 글이 도움이 되셨나요?
관련 주제 더 보기
Neo4j의 아키텍처, Cypher 쿼리 언어, 벡터 인덱스, GDS 라이브러리, Python 드라이버까지 지식 그래프 구축에 필요한 Neo4j의 핵심 기능을 다룹니다.
지식 그래프의 정의와 역사, 벡터 검색의 한계를 그래프가 어떻게 보완하는지, GraphRAG의 35% 정확도 향상 사례까지 Knowledge Graph와 AI 결합의 전체 그림을 소개합니다.
Amazon Neptune의 아키텍처와 Bedrock 통합, 그리고 TigerGraph, JanusGraph, Memgraph 등 주요 그래프 데이터베이스를 비교하며 프로젝트에 맞는 선택 가이드를 제공합니다.