데이터를 두 곳에 두지 마라 — 옵시디언 친화 설계를 폐기한 회고
"옵시디언으로도 보고 싶어서"가 시작이었습니다
지식그래프 기반 프로젝트 관리 도구를 만들면서 주간 리포트 데이터를 어떻게 저장할지 결정했습니다.
원래 정책은 명확했습니다. 그래프 노드 본문 + 별도 markdown 파일에 이중 저장. 이유는 단순했어요.
그래프 도구에서 보면 노드 관계가 잘 보임
옵시디언에서 열면 역링크·그래프 뷰가 잘 보임
외부 사람에게 공유할 때 markdown 파일 그대로 보내면 편함
"여러 곳에서 보고 싶다"는 요구가 있었고, 그래서 "여러 곳에 저장한다"로 자연스럽게 번역됐습니다. 이중 저장은 그 번역의 결과였습니다.
설계 당시에는 합리적으로 보였습니다. 두 환경 모두에서 좋은 UX를 얻을 수 있을 거라 기대했어요.
운영해보니 그림이 달랐습니다
몇 개월 운영한 결과, 분리의 이득은 약하고 동기화 부담만 커졌습니다.
분리 이득이 약했던 이유
옵시디언에서 보는 빈도가 생각보다 낮았습니다. 메인 도구가 이미 그래프 뷰를 제공하고 있어서, 굳이 옵시디언을 열지 않게 되었어요. 외부 공유도 markdown 파일을 직접 보내는 게 아니라 도구의 export 기능을 쓰는 경우가 대부분이었습니다.
동기화 비용이 컸던 이유
이중 저장의 진짜 비용은 두 곳을 같은 상태로 유지하려는 노력 그 자체였습니다.
그래프 노드 본문을 수정하면 markdown 파일도 같이 수정해야 함
둘 중 하나만 수정되면 데이터 불일치 발생
어느 쪽이 진실인지 모호해지는 순간이 생김
백엔드에서 markdown 렌더링 + 파일 쓰기 파라미터를 계속 관리해야 함
프론트엔드에서도 두 필드(docPath, body)를 다 다뤄야 함
이 비용은 한 번에 크게 드러나는 게 아니라 매일 조금씩 누적됐습니다. 가장 무서운 종류의 비용이에요. 측정도 어렵고 어느 시점에 임계점을 넘는지도 알기 어렵습니다.

정책을 뒤집었습니다 — 그래프 단일 + 단방향 거울
정책을 바꿨습니다. 그래프를 단일 진실 원천(Single Source of Truth)으로 두고, 옵시디언은 단방향 export 거울로만 사용합니다.
새 정책 (v2.0)
그래프 노드 본문이 유일한 진실
옵시디언에서 보고 싶으면 그래프에서 export (읽기 전용)
export된 markdown은 거울이지 진실이 아님
수정이 필요하면 그래프에서만
이 구조의 핵심은 방향성이에요. 양방향 동기화는 어렵고 비용이 크지만, 단방향 export는 단순합니다. "한쪽이 진실이고, 다른 쪽은 그 진실을 비추는 거울"이라는 구조가 잡히면 모호함이 사라집니다.
폐기한 것들
노드의 docPath 속성
응답 DTO의 docPath, body 필드
프론트엔드 본문 필드
백엔드 markdown 렌더링·파일 쓰기 파라미터 일체
여러 프로젝트의 weekly-reports/ 폴더에 쌓여 있던 markdown 파일
코드 정리 + 데이터 정리를 한 묶음으로 진행했습니다. 정책만 바꾸고 기존 파일을 그대로 두면 다음 사람이 혼란스러워합니다. 코드 변경과 데이터 정리는 한 묶음이라는 원칙이 여기서도 적용됐어요.
"정정 노트"를 남긴 이유
정책을 뒤집은 사실 자체를 기록으로 남겼습니다. 정책 문서 3건(도구 운영 가이드, 데이터 관리 정책, PRD)에 모두 "정정 노트" 를 명시했어요.
처음에는 단순히 새 정책으로 덮어쓰려 했습니다. 그런데 한 가지 우려가 있었어요.
6개월 뒤 누군가 "왜 그래프 단일이지? 옵시디언도 같이 쓰면 좋지 않나?" 하고 다시 이중 저장을 시도할 수 있습니다.
그래서 정정 노트로 남겼어요.
처음 정책: 이중 저장
운영 결과: 분리 이득 약함, 동기화 비용 큼
새 정책: 그래프 단일 + 단방향 거울
정정 이유: 위 운영 결과
이렇게 남기면 다음 사람이 같은 실수를 반복하지 않습니다. 정책 정정의 기록 자체가 자산이에요. "왜 뒤집었는가"가 다음 결정의 자료가 됩니다.
일반 패턴 — "보고 싶다"와 "저장한다"의 차이
이번 정정에서 얻은 가장 중요한 통찰입니다.
"여러 곳에서 보고 싶다"가 "여러 곳에 저장한다"로 자동 번역되면 안 된다.
이건 데이터 관리 전반에 적용되는 원칙이에요.
요구 | 잘못된 번역 | 올바른 번역 |
|---|---|---|
옵시디언에서도 보고 싶다 | 옵시디언에도 저장 | 옵시디언으로 export |
모바일에서도 쓰고 싶다 | 모바일 DB 별도 운영 | 단일 백엔드 + 모바일 캐시 |
외부에 공유하고 싶다 | 공유용 사본 따로 보관 | 원본에서 공유 링크 생성 |
분석팀도 보고 싶다 | 분석용 DB 복제 | read replica 또는 BI 연동 |
핵심은 "보고 싶다"를 "거울로 비춘다"로 해석하는 것입니다. 거울은 한 방향이고, 진실은 한 곳에 있습니다.
이중 저장으로 가면 두 곳이 모두 진실이 되어야 하고, 그 동기화 비용을 누군가 매일 부담해야 합니다. 거울 패턴으로 가면 한 곳만 관리하고 다른 곳은 자동으로 비춰집니다.

의사결정자가 점검할 4가지
데이터 저장 정책을 결정하실 때 점검할 일반 체크리스트입니다.
1. "보고 싶다"가 "저장한다"로 번역되고 있지 않은지 확인합니다
"여러 환경에서 사용한다"는 요구가 자동으로 "여러 곳에 저장한다"로 이어지면 위험합니다. 거울 패턴(단방향 export, read replica, 공유 링크)으로 풀 수 있는지 먼저 검토합니다.
2. 동기화 비용의 누적 효과를 측정합니다
이중 저장의 비용은 한 번에 크게 드러나지 않습니다. 매일 조금씩 누적되다가 어느 순간 데이터 불일치 사고로 폭발합니다. "지금은 동기화가 잘 되고 있어"로 안심하면 안 됩니다.
3. 단일 진실 원천(SOT)을 명시합니다
여러 곳에 데이터가 있다면 어느 곳이 진실인지 명시해야 합니다. "둘 다 진실"은 결국 모호함을 만들고 분쟁을 만듭니다. SOT가 명확하면 다른 곳은 자동으로 거울이 됩니다.
4. 정책 정정의 기록을 남깁니다
정책이 바뀌면 "왜 바뀌었는지"를 기록으로 남기는 게 다음 결정의 자산입니다. 단순히 새 정책으로 덮어쓰면 6개월 뒤 누군가 같은 실수를 반복합니다.
비슷한 발상이 다른 운영 결정에서도 흐릅니다. 데이터 관리는 깔끔함이 아니라 단일성에서 출발해야 한다는 시야. 거울은 진실을 비추지만, 사본은 또 다른 진실을 만들려 합니다.
마무리
지식그래프 기반 도구의 주간 리포트 데이터를 그래프 노드 + markdown 파일에 이중 저장하던 정책을 그래프 단일 + 단방향 export 거울 구조로 정정했습니다. 분리의 이득은 약하고, 동기화 비용이 매일 누적되어 더 컸기 때문입니다.
핵심 교훈은 세 가지입니다.
"보고 싶다"가 "저장한다"로 자동 번역되면 안 된다 — 거울 패턴으로 충분한 경우가 많음
이중 저장의 비용은 매일 조금씩 누적된다 — 측정 어렵지만 결국 분쟁을 만듦
정책 정정의 기록 자체가 자산이다 — "왜 뒤집었는가"가 다음 결정의 자료
데이터 저장 정책·시스템 통합·도구 간 연동을 검토하신다면, 이번 글의 4가지 체크리스트(자동 번역 점검 / 동기화 비용 측정 / SOT 명시 / 정정 기록)를 한 번 살펴보시길 추천합니다. 단일성으로 시작하면 깔끔함은 자연스럽게 따라옵니다.