1. 연구 배경: 관계형 모델이 부적합한 도메인
한국 주식시장의 신호는 관계형이 아니라 의미 기반(semantic) 으로 연결됩니다. 하나의 DART 공시가 해당 기업뿐 아니라 자회사, 모회사, 같은 테마·공급망에 속한 기업까지 영향을 미치며, 이 연결은 외래 키가 아니라 의미로 규정됩니다. "모회사의 주요주주가 지분변동을 공시한 섹터에서 이상 징후를 찾아라" 같은 질의는 SQL에서는 다중 조인의 중첩이지만 그래프 순회에서는 자연스럽습니다.
여기에 두 가지 성질이 더해집니다. 자본시장법은 수 년 주기로 공시 유형을 추가하므로 스키마가 법령과 함께 진화해야 하고, 섹터 계층을 따라 맥락이 인접 영역으로 전파되는 추론이 필요합니다. 그래서 저장소로 관계형 DB 대신 Neo4j 지식그래프를 선택하고, 공시·뉴스·수급·매크로·테마·공급망·임원 네트워크를 하나의 그래프로 융합하는 시스템을 만들기 시작했습니다.
2. 문제 정의: 틱을 그래프에 넣은 첫 구현의 실패
첫 구현은 증권사 WebSocket에서 받은 실시간 체결 틱을 전부 Neo4j에 (:PriceTick) 노드로 적재했습니다. 며칠 만에 세 가지 문제가 실측으로 드러났습니다.
저장 비용. KOSPI·KOSDAQ 합산 체결 틱은 하루 약 500만~1,500만 건입니다. 노드·관계·인덱스 속성을 합쳐 틱당 약 200바이트로 잡아도 1년이면 인덱스 오버헤드를 제외하고 약 250GB — 노드 수로는 연 12억 개 이상입니다. 문제는 용량 자체가 아니라, 이 노드들이 Neo4j 페이지 캐시를 점유하는 한 틱과 무관한 모든 그래프 질의가 그 비용을 함께 지불한다는 점입니다.
질의 패턴 불일치. 이 그래프에 던지는 질문은 "공시 직후 이상 징후를 보인 종목" 같은 엔티티·이벤트 추론입니다. "지난 화요일의 439만 번째 틱"을 조회할 일은 없습니다. 그래프 인덱싱 비용을 지불하면서 컬럼형 시계열 워크로드를 감당하는 구조였습니다.
쓰기 처리량. 배치를 걸어도 장중 내내 초당 수백 건의 쓰기가 Neo4j 커넥션을 점유해, 정작 필요한 엔티티·이벤트 갱신 여력을 잠식했습니다.
3. 기술적 난점: 배제만으로는 끝나지 않는 문제들
틱을 그래프에서 빼기로 하면 후속 문제가 생깁니다.
첫째, 틱은 버릴 수 없습니다. 분 단위 집계(OHLCV)와 이상탐지의 원천이므로, 그래프 밖 어딘가에는 유실 없이 남아야 하고, 장애 시 재집계가 가능해야 합니다.
둘째, 저지연 소비와 영구 보관의 요구가 충돌합니다. 이상탐지는 최근 수 분의 틱을 메모리 속도로 요구하고, 백테스트는 수년치를 컬럼 단위로 스캔하길 요구합니다. 단일 저장소로는 어느 한쪽을 희생하게 됩니다.
셋째, 그래프에 남는 데이터의 무결성입니다. OWL은 개방세계 가정(open-world assumption)이라 "명시되지 않은 것은 미지"로 해석합니다. 추론에는 적합하지만 "종목 코드는 반드시 6자리" 같은 폐쇄세계 제약을 위반으로 판정하지 못해, 불량 데이터가 검증을 통과한 채 추론에 섞일 위험이 있습니다.
4. 대안 검토
1안. Neo4j 단일 통합 저장소 유지
- 장점: 저장소 하나, 운영 단순. 모든 데이터가 한 곳에.
- 단점: 위 실측 문제 그대로. 데이터가 늘수록 그래프 본연의 질의가 느려지는 구조적 결함.
2안. 그래프 포기, RDB + 시계열 DB 구성
- 장점: 시계열 처리에는 검증된 구성.
- 단점: 1절의 선택 이유가 사라집니다. 다중 홉 관계 질의와 법령 따라 진화하는 스키마를 다시 조인과 마이그레이션으로 감당해야 합니다.
3안. 그래프는 유지하되, 시계열을 계층화해 분리
- 장점: 그래프는 추론에, 시계열은 각 소비 패턴에 맞는 저장소에. 장애 격리도 확보됩니다.
- 단점: 저장 기술이 셋으로 늘고, 계층 간 이동(장 마감 롤오버)을 관리해야 합니다.
5. 설계 결정 및 근거: 4단계 티어링과 검증 체계
3안을 채택했습니다(ADR-001). 원칙은 하나입니다 — 그래프에는 "우리가 질문하는 대상"만 남긴다. 엔티티·관계·집계·이벤트는 그래프에, 원시 틱은 시계열 계층에.
| 계층 | 저장소 | 보존 기간 | 목적 |
|---|---|---|---|
| Hot | 인메모리 링버퍼 | 종목당 약 5분 | 집계 윈도우, 저지연 이상탐지 |
| Warm | SQLite (WAL) | 당일 | 장중 조회, 지연 틱 정합, 재시작 리플레이 |
| Cold | Parquet (일자 파티션) | 영구 | 과거 분석, 재집계 리플레이 |
| KG | Neo4j | 영구 | 엔티티·관계·집계(1분 OHLCV)·이벤트 |
틱은 라우터를 거쳐 Hot(동기)과 Warm(비동기)에 쓰이고, 집계기가 Hot을 소비해 분 경계마다 OHLCV 바를 만들어 그래프에 승격합니다. 장 마감 시 당일 SQLite가 Parquet으로 롤오버됩니다. 도구 선택에도 근거를 남겼습니다 — Warm은 WAL 모드로 쓰기 중 동시 읽기가 되는 SQLite(추가 의존성 없음), Cold는 행 저장 대비 약 10배 압축되고 서버 없이 pandas·DuckDB로 질의 가능한 Parquet, 그리고 단일 호스트 연구 환경이므로 Redis 같은 외부 큐는 두지 않았습니다.
그래프에 남는 데이터에는 검증 체계를 강제했습니다(ADR-002, 003). 의미는 OWL, 무결성은 SHACL로 책임을 분리해 "티커 6자리" 같은 폐쇄세계 규칙은 적재 시점에 실제로 실패하게 했고, 도메인 클래스는 owl:equivalentClass로 FIBO 표준에 정렬해 상호운용성을 확보했습니다. 외부 소스에서 온 모든 노드에는 PROV-O 세 필드(원천 ID, 수집 시각, 수집 주체)를 의무화해 계보를 추적합니다.
마지막으로, 이런 결정 자체를 코드처럼 버전 관리하기로 했습니다. 맥락·결정·트레이드오프를 담은 ADR을 결정마다 남기고, 이후 결정이 이전 결정을 개정하면 그 사실도 기록합니다. 실제로 초기의 "ML 라이브러리 금지" 조항은 데이터가 3년치로 늘어난 시점에 검증 원칙과 함께 개정됐고(ADR-022), LSTM 도입과 옵션 IV 데이터는 "아직 하지 않는다"는 결정으로 보류를 명시했습니다(ADR-027, 028). 하기로 한 것만큼 하지 않기로 한 것을 남기는 것이 이 체계의 핵심입니다.
6. 실험 결과
이 골격 위에서 시스템은 현재 다음 규모로 운영되고 있습니다(2026-08 실측).
| 항목 | 값 |
|---|---|
| 그래프 규모 | 노드 약 524만 — 수급 257만 · 외인보유 84만 · 뉴스 55.7만 · 공시 29.5만 · 기업 2,701 |
| 원시 틱 | Neo4j 적재 0건 — 전량 Hot/Warm/Cold 계층에서 처리 |
| 아키텍처 결정 기록 | 31건 (ADR-001 ~ ADR-031), 개정·보류·기각 이력 포함 |
| ML 학습 feature | 134개 — 이 중 그래프 파생(테마·공급망·임원 네트워크) 13개 |
| 온톨로지 | FIBO 정렬 · SHACL 적재 시점 검증 · PROV-O 계보 |
수급·보유율 같은 일별 시계열만으로 이미 340만 노드입니다. 틱까지 그래프에 넣었다면 연 12억 개 이상이 더해져 지금의 엔티티·이벤트 질의는 성립하지 않았을 것입니다. 배제 결정이 이후 모든 파이프라인 설계의 전제가 됐습니다.
이 그래프는 조회용 저장소가 아니라 feature 팩토리로 쓰입니다. 임원 겸직 네트워크·공급망 2-hop처럼 그래프여야만 계산 가능한 신호를 ML 스코어링에 공급하는 과정은 그래프 피처 의무화에, 그 위에서 가설 검증이 어떻게 무너지고 재건됐는지는 홀드아웃 검증 기록에, 수집 계층의 장애 대응은 소스 이중화 설계에 따로 기록했습니다.

7. 결론 및 시사점
저장소 선택보다 중요한 것은 "무엇을 넣지 않을 것인가"였습니다. 그래프는 이종 관계 추론이라는 명확한 강점이 있지만, 그 강점은 그래프를 가볍게 유지할 때만 성립합니다. 첫 구현의 실패가 이 원칙을 실측으로 가르쳐 줬습니다.
검증은 표현과 분리해야 합니다. OWL로 의미를 표현하고 SHACL로 무결성을 강제하는 분리 덕에, 공시 유형이 법령과 함께 늘어나도 스키마는 서브클래스로 흡수하고 불량 데이터는 적재 전에 차단됩니다.
가장 오래 남는 자산은 결정 기록입니다. 그래프 데이터는 매일 갱신되고 모델은 재학습되지만, "왜 틱을 넣지 않았는가", "왜 ML 금지를 풀었는가"라는 31건의 기록은 같은 검토를 반복하지 않게 하는 유일한 수단입니다. 특히 어떤 대안을 검토했고 왜 기각했는지를 함께 남길 때에만 그렇습니다.
전체 ADR과 온톨로지 설계는 GitHub 저장소에, 그래프에서 도출된 추천과 성과 추적은 데모 대시보드에 공개되어 있습니다.
