Datalog에 대한 글을 몇 편 써오면서, 스스로에게 계속 되묻게 되는 질문이 하나 있습니다. “Datalog는 일상적으로 쓸 수 있는 도구인가?”라는 것입니다.

특수한 도메인에서는 빛나지만

Datalog의 활용 사례를 찾으면 대부분 ‘특수한 도메인’에 집중되어 있습니다.

  • 정적 프로그램 분석: 포인터 분석이나 데이터 흐름 분석에서 Datalog는 이미 검증된 도구입니다. Soufflé 같은 고성능 Datalog 엔진은 아예 이 용도에 최적화되어 있습니다.
  • 보안 정책 검증: 접근 제어 규칙을 사실과 규칙으로 표현하고, 의도하지 않은 권한 경로가 존재하는지 추론하는 데 탁월합니다.
  • 네트워크 구성 분석: 라우팅 테이블의 도달가능성을 재귀적으로 계산하는 것은 Datalog의 전형적인 적용 사례입니다.
  • 온톨로지 추론: 지식 그래프 위에서 RDFS/OWL 규칙을 적용하여 암묵적 관계를 도출하는 데 사용됩니다.

이런 예제들은 만들기 어렵지 않습니다. 도메인 자체가 “사실과 규칙으로부터 새로운 사실을 도출한다”는 Datalog의 본질과 정확히 맞아떨어지기 때문입니다. 문제는 이런 사례들을 보여주면 돌아오는 반응이 늘 비슷하다는 점입니다.

“저는 컴파일러도 안 만들고, 보안 정책도 안 다루는데, 이걸 언제 쓰나요?”

이 질문에 선뜻 대답하기가 어렵습니다.

일상적 유즈케이스가 떠오르지 않는 이유

곰곰이 생각해보면, Datalog의 일상적 유즈케이스를 만들기 어려운 데는 구조적인 이유가 있습니다.

첫째, 일상의 데이터 문제는 대부분 SQL로 충분합니다. 테이블에서 조건에 맞는 행을 필터링하고, 집계하고, 조인하는 것이 우리가 매일 하는 데이터 작업의 대부분이고, SQL은 이 영역에서 반세기 넘게 검증된 도구입니다. 생태계 규모 자체가 비교가 안 됩니다.

둘째, 재귀적 추론이 필요한 일상적 상황이 드뭅니다. Datalog가 SQL에 대해 가지는 가장 명확한 이점은 재귀(recursion)인데, “조상의 조상”이나 “친구의 친구”를 따라가야 하는 상황이 일상적 데이터 작업에서 얼마나 자주 등장하는지 생각해보면 그리 많지 않습니다. SQL의 WITH RECURSIVE가 불편하기는 해도, 그 불편함을 느낄 기회 자체가 드뭅니다.

셋째, 도구의 접근성 문제가 있습니다. Python에서 Pandas 한 줄이면 해결되는 일을 위해 별도의 Datalog 엔진을 설치하고, 사실을 정의하고, 규칙을 작성해야 한다면 전환 비용이 작지 않습니다. 도구가 주는 가치가 그 비용을 넘지 못하면 채택은 일어나지 않습니다.

그럼에도 가능성이 보이는 영역들

그래도 Datalog가 일상의 도구로 가치를 가질 수 있는 지점이 전혀 없는 것은 아닙니다. 최근에 떠올린 몇 가지 방향을 정리해봅니다.

1. 개인 지식 관리 (Personal Knowledge Management)

Obsidian이나 Logseq 같은 도구를 쓰면서 노트 사이의 관계를 [[링크]]로 연결하는 사람이 늘고 있습니다. 이 링크 그래프는 본질적으로 사실(Facts)의 집합입니다.

references("Datalog 소개", "논리 프로그래밍").
references("논리 프로그래밍", "Prolog").
tagged("Datalog 소개", "datalog").
tagged("논리 프로그래밍", "logic").

% 간접적으로 관련된 노트 찾기
related(X, Y) :- references(X, Y).
related(X, Y) :- references(X, Z), related(Z, Y).

% 같은 태그를 공유하는 노트 클러스터
cluster(X, Y) :- tagged(X, T), tagged(Y, T), X \= Y.

“이 노트와 간접적으로 연결된 노트가 뭐지?”, “내가 놓치고 있는 연결 고리가 있을까?” 같은 질문을 표현하는 데에는 SQL보다 Datalog가 자연스럽습니다. 노트가 수백 개를 넘어가면, 단순한 링크 목록을 넘어 추론으로 관계를 끌어내는 사용 방식이 의미를 가지기 시작합니다.

2. 의존성과 영향 분석

소프트웨어 프로젝트의 의존성 관리는 개발자의 일상입니다. 패키지 A가 B에 의존하고, B가 C에 의존할 때, C에 보안 취약점이 발견되면 영향받는 모든 패키지를 찾아야 합니다.

depends_on("my-app", "web-framework").
depends_on("web-framework", "http-lib").
depends_on("http-lib", "openssl").
vulnerable("openssl").

% 전이적 의존성
transitive_dep(X, Y) :- depends_on(X, Y).
transitive_dep(X, Y) :- depends_on(X, Z), transitive_dep(Z, Y).

% 취약한 패키지에 간접적으로 의존하는 모든 패키지
at_risk(X) :- transitive_dep(X, Y), vulnerable(Y).

물론 npm audit이나 pip-audit 같은 전용 도구가 이미 있습니다. Datalog의 장점은 전용 도구가 포착하지 못하는 질문을 사용자가 직접 규칙으로 써서 물어볼 수 있다는 점입니다. “이 모듈을 수정하면 영향받는 테스트는?”, “이 설정을 변경하면 어떤 서비스가 재시작되어야 하는가?” 같은 질문은 결국 전이적 관계 위에서의 도달 가능성 문제이고, Datalog는 이를 선언적으로 표현하는 데 잘 맞는 언어입니다.

3. 접근 권한의 선언적 관리

RBAC(Role-Based Access Control)은 어디에나 있습니다. 사내 시스템, 클라우드 인프라, 심지어 Google Drive의 공유 설정까지. 문제는 권한이 중첩되고 상속될 때 “이 사람이 이 리소스에 접근할 수 있는가?”라는 질문에 답하기가 점점 어려워진다는 것입니다.

role("김과장", "팀장").
role("이대리", "개발자").
inherits("팀장", "개발자").
permission("개발자", "코드저장소", "read").
permission("팀장", "코드저장소", "write").

% 역할 상속
has_role(User, Role) :- role(User, Role).
has_role(User, Role) :- role(User, R), inherits(R, Role).

% 최종 권한 계산
can_access(User, Resource, Action) :-
    has_role(User, Role),
    permission(Role, Resource, Action).

can_access("김과장", "코드저장소", "read")가 참인지를 확인하는 것은 단순 조회가 아니라 추론입니다. 팀장 역할이 개발자 역할을 상속하고, 개발자에게 read 권한이 있기 때문에 김과장도 read 권한을 가진다는 결론이 규칙에서 따라 나와야 합니다. 역할 계층이 깊어지고 조건이 복잡해질수록, 같은 추론을 SQL의 다중 조인으로 옮겨 쓰는 일은 점점 힘들어집니다. Google의 Zanzibar나 Oso 같은 권한 관리 시스템이 내부에서 Datalog 계열의 추론 엔진을 채택한 배경에는 이런 맥락이 있습니다.

4. 설정과 규칙의 검증

인프라 설정(Infrastructure as Code)이 복잡해지면, 설정 간의 일관성을 검증하는 것이 중요해집니다. “프로덕션 DB는 반드시 암호화가 활성화되어야 한다”, “외부에 노출된 서비스는 인증 미들웨어를 거쳐야 한다”—이런 정책을 Datalog 규칙으로 표현하고, 현재 설정(Facts)에 대해 위반 여부를 검증할 수 있습니다.

service("api-gateway", "external").
service("internal-api", "internal").
has_auth("api-gateway").

% 정책: 외부 서비스는 반드시 인증이 있어야 한다
violation(S) :- service(S, "external"), \+ has_auth(S).

OPA(Open Policy Agent)의 Rego 언어가 이미 이 영역에서 자리를 잡고 있지만, Rego의 설계 자체가 Datalog의 영향을 강하게 받았습니다. “정책은 결국 사실과 규칙의 문제”라는 관점이 이 영역과 잘 맞아떨어지기 때문입니다.

일상의 도구가 되려면

이런 가능성에도 불구하고, Datalog가 일상의 도구로 자리 잡으려면 여전히 넘어야 할 벽이 있습니다. 가장 큰 것은 생태계와 통합입니다. SQL이 강력한 이유는 언어 자체의 표현력보다 PostgreSQL, MySQL 같은 성숙한 DBMS 생태계, 수십 년간 축적된 라이브러리, 그리고 거의 모든 프로그래밍 언어에서 네이티브로 지원된다는 점에 있습니다. Datalog에도 Soufflé, Differential Datalog, Naga 같은 구현체가 있지만, “pip install 하고 바로 쓴다”는 수준의 접근성까지는 아직 거리가 있습니다.

결국 Datalog가 일상에 스며들려면 독립된 도구가 아니라 기존 워크플로우에 얹히는 형태가 되어야 할 것 같습니다. Rego가 Kubernetes 생태계 안쪽에서 쓰이게 된 것처럼, 혹은 SQLite가 서버 없이 어디에든 박히는 DB로 자리 잡은 것처럼 말이죠. 가벼운 임베디드 Datalog 엔진을 Python이나 JavaScript에서 한 줄로 부르고, 의존성 분석이나 권한 검증 같은 구체적인 문제에 바로 적용할 수 있는 형태—이 방향이 가장 그럴듯해 보입니다.

마치며

특수한 도메인에서 Datalog의 가치는 이미 증명돼 있습니다. 정적 분석, 보안, 네트워크 같은 영역에서 Datalog를 대체할 도구는 찾기 어렵습니다. 반면 “일반적인 일상”이라는 문맥에서 Datalog는 여전히 자기 자리를 찾는 중입니다.

정리하면서 든 생각은, 위에 나열한 네 가지 영역—노트 간 관계, 의존성 분석, 권한 추론, 설정 검증—이 공통적으로 “사실과 규칙으로부터 결론을 도출하는” 형태의 문제라는 점이었습니다. 이미 각자의 자리에서 다른 도구로 처리되고 있지만, 그렇기 때문에 오히려 Datalog의 잠재적 영역이 어디쯤에 있는지 보여주기도 합니다.

다음에는 이 고민을 코드로 옮겨볼 생각입니다. 가벼운 Datalog 엔진을 실제 일상적인 문제에 적용해보는 실험을 해보려 합니다.


관련 글