LatticeDB
네이티브 벡터 및 전체 텍스트 인덱싱을 갖춘 임베디드 속성 그래프 데이터베이스.
LatticeDB는 연결된, 의미론적(semantic), 그리고 텍스트 데이터를 위한 단일 파일 로컬 데이터베이스입니다. 이 데이터베이스를 사용하면 하나의 엔진과 하나의 쿼리 레이어에서 관계 추적(traverse relationships), 벡터 유사성 검색(vector similarity search), BM25 전체 텍스트 검색을 수행할 수 있습니다. 이는 제로-설정(zero-config) 운영 방식과 임베디드 단일 작성자 모델(embedded single-writer model)을 갖춘, 관계 중심 워크로드에 최적화되어 설계되었습니다.
LatticeDB는 로컬 애플리케이션이 관계, 의미론, 텍스트를 통해 동일한 데이터에 쿼리하고, 그 데이터를 같은 파일에서 영속적인 그래프 및 애플리케이션 이벤트를 소비할 수 있게 하는 임베디드 단일 파일 그래프 데이터베이스입니다. Graph RAG, 에이전트 메모리(agent memory), 로컬 지식 도구와 같은 워크로드는 이러한 기본 요소(primitives)를 기반으로 구축된 예시이며, 엔진의 정의는 아닙니다.
- 단일 파일: 전체 데이터베이스가 하나의 휴대 가능한 파일입니다. 서버나 설정이 필요 없습니다.
- 하나의 쿼리 레이어: 그래프 순회(Graph traversal), HNSW 벡터 유사성 검색, 그리고 BM25 전체 텍스트 검색을 동일한 쿼리 언어로 처리합니다.
- 하나의 이벤트 로그: 영속적인 이름 지정 스트림(Durable named streams)과 내장 그래프 변경 피드(built-in graph changefeed)가 그래프 쓰기와 동일한 트랜잭션/WAL 경로를 공유합니다.
- 로컬 우선(Local-first): 하나의 머신에서 단일 소유 프로세스를 위해 설계되었으며, WAL 기반의 내구성을 제공합니다.
- 빠름: 노드 조회는 0.13 μs입니다. 1M 벡터에서 100% 재현율(recall)로 벡터 검색은 0.83 ms입니다.
// 쿼리와 유사한 청크를 찾고, 해당 문서로 순회한 다음, 작성자로 이동합니다.
MATCH (chunk:Chunk)-[:PART_OF]->(doc:Document)-[:AUTHORED_BY]->(author:Person)
WHERE chunk.embedding <=> $query_vector < 0.3
...
설치
CLI
curl -fsSL https://raw.githubusercontent.com/jeffhajewski/latticedb/main/dist/install.sh | bash
Python
배포된 휠(wheels)에는 지원되는 플랫폼에 liblattice가 번들링될 것으로 예상됩니다. 소스 설치 시에도 LATTICE_BUNDLE_LIB_DIR=/path/to/lib를 사용하여 휠 빌드 중에 스테이징된 네이티브 라이브러리를 번들링할 수 있습니다.
TypeScript / Node.js
npm install @hajewski/latticedb
게시된 패키지 tarball에는 지원되는 플랫폼에 맞춰 liblattice가 번들링되어 제공될 것으로 예상됩니다. 소스 체크아웃의 경우, LATTICE_BUNDLE_LIB_DIR=/path/to/lib npm run bundle:native 명령을 사용하여 네이티브 라이브러리를 패키지에 스테이징할 수 있습니다.
Electron 앱은 바인딩을 메인 프로세스에서 실행하며, app.asar에서 네이티브 라이브러리를 언패킹해야 합니다. 자세한 내용은 Electron을 참조하십시오.
Java
JDK 21 이상을 요구합니다. Maven 빌드에 대한 내용은 [bindings/java/README.md]를 참조하십시오. 이 빌드는 JNI 브리지를 컴파일하고 zig-out/lib에서 liblattice를 스테이징합니다. 실행 가능한 지식 그래프(knowledge-graph) 예제는 bindings/java/src/main/java/io/latticedb/examples에 있습니다.
Go
현재의 cgo 워크플로우는 [bindings/go/README.md]를 참조하십시오. 기본 소비자 경로는 설치된 pkg-config 메타데이터를 사용하며, 리포지토리 내부 개발 시에는 zig-out/lib에 대해 -tags repolocal을 사용할 수 있습니다.
또한 examples/go에는 실행 가능한 그래프/벡터/텍스트 검색 예제가 있습니다.
최근 바인딩 표면(binding-surface) 정리 작업으로 인해 임베딩 헬퍼가 전용 모듈 및 서브패키지로 이동했습니다. 선호되는 import 구문과 현재 호환성 별칭은 [docs/client_api_migration.md]를 참조하십시오.
시작하기 (Start Here)
예제 (Example)
완전한 예제: 문서와 저자로 구성된 작은 지식 그래프를 생성하고, 임베딩을 저장하며, 텍스트를 인덱싱한 다음, 세 가지 검색 모드 모두에서 질의하는 과정입니다.
예제에서는 외부 서비스 없이 실행할 수 있도록 내장된 hash_embed / hashEmbed / HashEmbed 헬퍼를 사용합니다. 이는 의미론적 임베딩(semantic embedding)이 아닌 결정론적 플레이스홀더입니다. 따라서 유사한 텍스트가 가까운 벡터를 생성하지 않으므로, 거리 임계값은 임의적이며 유사성 질의는 아무것도 일치시키지 못할 수 있습니다. 결과가 의미를 가져야 하는 모든 경우에는 실제 임베딩 모델을 사용하십시오 — 임베딩 작업하기를 참조하세요.
Python
from latticedb import Database
from latticedb.embedding import hash_embed
...
TypeScript
import { Database } from "@hajewski/latticedb";
import { hashEmbed } from "@hajewski/latticedb/embedding";
...
Go
db, err := latticedb.Open("knowledge.db", latticedb.OpenOptions{
Create: true,
EnableVectors: true,
...
Java
import io.latticedb.*;
import java.util.List;
import java.util.Map;
...
빌드 지침 및 전체 실행 가능한 예제는 bindings/java/README.md를 참조하세요.
Apple M1에서 단일 스레드(single-threaded), 자동 확장 버퍼 풀을 사용하여 벤치마크를 수행했습니다. 재현하려면 zig build benchmark를 실행하세요. 이전에 이차적 추가 동작(quadratic append behavior)이 노출되었던 반복 용어 FTS 인덱싱 워크로드의 경우, zig build fts-benchmark를 실행하세요.
핵심 작업 (Core Operations)
| 작업 (Operation) | 지연 시간 (Latency) | 처리량 (Throughput) | 목표 (Target) | 상태 (Status) |
|---|
| 노드 조회 (Node lookup) | 0.13 μs | 7.9M ops/sec | < 1 μs | PASS |
| ... | | | | |
대규모 벡터 검색 (Vector Search) (HNSW)
128차원 코사인 벡터, M=16, ef_construction=200, ef_search=64, k=10. 재현하려면 zig build vector-benchmark를 실행하세요.
| Scale | 평균 지연 시간 | P99 지연 시간 | Recall@10 | 메모리 |
|---|
| 1,000 | 65 μs | 70 μs | 100% | 1 MB |
| ... | | | | |
| 검색 지연 시간은 99~100%의 Recall@10을 유지하면서 준선형적으로 (O(log N)) 증가합니다. 다양한 그래프 연결성을 위해 휴리스틱 이웃 선택(HNSW 논문 알고리즘 4)을 사용하고, 연결 페이지 패킹을 통해 메모리를 약 4.5배 줄였으며, 빠른 코사인 거리를 위해 사전 정규화된 내적(dot product)을 사용합니다. | | | | |
ef_search 민감도 (1M 벡터)
| ef_search | 평균 지연 시간 | Recall@10 |
|---|
| 16 | 506 μs | 57% |
| ... | | |
경쟁 분석
포인트 조회 (Point Lookups)
| 시스템 | 지연 시간 | 유형 | 출처 |
|---|
| LatticeDB | 0.13 μs | 임베디드 | zig build benchmark |
| ... | | | |
| LatticeDB의 B+Tree는 마이크로초(μs) 미만의 캐시된 조회 속도를 달성하여, RocksDB 인메모리 성능에 필적하며 디스크 상의 SQLite보다 23배 뛰어납니다. | | | |
벡터 검색 (Vector Search)
| 시스템 | 지연 시간 (10-NN) | 스케일 | 유형 | 출처 |
|---|
| LatticeDB | 평균 0.83 ms, 100% Recall | 1M | 임베디드 | zig build vector-benchmark |
| ... | | | | |
| 1M 규모에서 LatticeDB는 100%의 Recall@10을 달성하며 평균 0.83ms를 기록했습니다. 이는 FAISS 단일 스레드 HNSW보다 빠르며, Weaviate 및 Qdrant 서버 기반 시스템(실제로는 네트워크 오버헤드가 추가됨)과 경쟁할 만한 성능입니다. | | | | |
그래프 순회 (Graph Traversal)
| 시스템 | 2-hop (100K 노드) | 유형 | 출처 |
|---|
| LatticeDB | 39 μs | 임베디드 | zig build sqlite-benchmark |
| ... | | | |
| 오직 SQLite 행만 동일한 하드웨어와 동일한 테스트 환경에서 직접 비교 측정되었습니다. Kuzu 및 Neo4j 수치는 저희가 통제할 수 없는 제3자 게시물에 기반하며, 따라서 벤치마크 결과라기보다는 대략적인 크기(order-of-magnitude)의 참고 자료로 간주해야 합니다. | | | |
LatticeDB vs SQLite — 멱법칙 정도 분포를 가진 소셜 네트워크 그래프, 인접성 캐시 사전 워밍:
소규모 (10K 노드, 50K 에지)
| 워크로드 | LatticeDB | SQLite | 속도 향상(Speedup) |
|---|
| 1-hop traversal | 560 ns | 13.0 μs | 23x |
| ... | | | |
| 미디엄 스케일 (Medium Scale) (10만 개 노드, 50만 개 엣지) | | | |
| 워크로드 | LatticeDB | SQLite | 속도 향상(Speedup) |
|---|
| 1-hop traversal | 8.0 μs | 290.0 μs | 36x |
| ... | | | |
| 깊이 제한 탐색 (Depth-Limited Traversal) (1만 개 노드, 5만 개 엣지) | | | |
| 깊이(Depth) | LatticeDB | SQLite | 속도 향상(Speedup) |
|---|
| 10 | 311 μs | 121 ms | 390x |
| ... | | | |
LatticeDB는 인접 캐시(adjacency cache)와 비트셋 방문 추적(bitset visited tracking)을 사용한 너비 우선 탐색(BFS)을 사용합니다. SQLite는 UNION 중복 제거를 사용하는 재귀적 공통 테이블 표현식(recursive CTE)을 사용합니다. 둘 다 동일한 도달 가능한 노드 집합(~8천 개 노드)을 계산합니다. 깊이가 깊어질수록 SQLite의 CTE 오버헤드가 각 재귀 레벨마다 증가하여 격차가 벌어집니다. 재현하려면 zig build graph-benchmark -- --quick을 실행하십시오. | | | |
전문 검색 (Full-Text Search, BM25)
| 시스템 | 검색 지연 시간(Search Latency) | 유형(Type) | 출처(Source) |
|---|
| LatticeDB | 19 μs | 내장(Embedded) | zig build benchmark |
| ... | | | |
| LatticeDB의 BM25 점수 기반 역색인(inverted index)은 SQLite FTS5보다 약 300배 빠르며, 전용 Rust 검색 라이브러리인 Tantivy와 경쟁할 만합니다. | | | |
기능 (Features)
그래프 (Graph)
- 레이블 및 임의 속성을 가진 노드와 엣지
- 범위 지정된(scoped) 노드 및 엣지 속성에 대한 영구적 명시적 동등성 인덱스(Durable explicit equality indexes)
- 다중 홉 탐색, 가변 길이 경로(
*1..3)
- 커밋/롤백 및 충돌 복구 기능을 갖춘 ACID 트랜잭션
- MERGE, WITH, UNWIND, 집계 함수(
count, sum, avg, min, max, collect)
벡터 검색 (Vector Search)
- 설정 가능한 M, ef를 갖춘 HNSW 근사 최근접 이웃(approximate nearest neighbor)
- 내장 해시 임베딩 또는 Ollama/OpenAI용 HTTP 클라이언트
- 빠른 수집을 위한 대량 벡터 노드 삽입(bulk vector node insertion)
전문 검색 (Full-Text Search)
- 토큰화 및 어간 추출(stemming)이 적용된 BM25 순위 역색인
- 설정 가능한 레벤슈타인 거리(Levenshtein distance)를 갖춘 퍼지 검색(fuzzy search)
Cypher 쿼리 언어 (Cypher Query Language)
- MATCH, WHERE, RETURN, CREATE, DELETE, SET, REMOVE
- ORDER BY, LIMIT, SKIP, DETACH DELETE
- 벡터 거리 연산자:
<=>
- 전체 텍스트 검색 연산자:
@@
- 매개변수:
$name
기능 (Operations)
- 충돌 복구를 위한 쓰기 전 로그(write-ahead log)를 갖춘 단일 파일 저장소
- 연속 백업: 변경 사항을 디렉터리에 전송하고 특정 시점으로 복원
lattice backup을 사용한 핫 백업: 데이터베이스를 종료하지 않고 수행
- 객체 스토리지에 많은 작은 데이터베이스를 보관하기 위해 데이터베이스를 바이트로 직렬화(serialize)하고 바이트에서 여는 기능
:memory:를 사용하는 인메모리 데이터베이스: 파일을 전혀 건드리지 않음
- 명시적 소비자 오프셋, 수동 트리밍 및 그래프 변경 피드를 갖춘 영구 이름 스트림 (Durable named streams)
- 안전한 물리적 꼬리 회수를 위한 온라인 프리리스트 재사용 및
lattice compact
- 제로 설정(Zero configuration): 파일을 열고 작업을 시작함
- 로컬 애플리케이션을 위한 임베디드 단일 작성자 모델(single-writer model)
- 깔끔한 C API; Python, TypeScript, Go, Java 바인딩이 이를 감쌈
사용 사례 (Use Cases)
- 연결된 로컬 데이터: 메모, 문서, 카탈로그, 인용 그래프 및 엔티티 그래프
- 검색과 그래프 결합: 동일한 데이터 세트에 대한 관계 탐색(Relationship traversal), 의미 검색(Semantic search), 어휘 검색(Lexical search)
- 로컬 지식 도구: 별도의 서버를 실행할 필요 없이 그래프 구조가 필요한 임베디드 앱
- 에이전트 메모리 및 RAG 파이프라인: 그래프/벡터/텍스트 기질을 기반으로 구축된 작업 부하의 한 예시 클래스
- 로컬 개발: 단일 머신에서 프로토타이핑하기 위한 Neo4j 또는 Weaviate의 경량 대안
다른 것을 사용해야 할 때 (When to Use Something Else)
LatticeDB는 빠르지만, 속도가 유일하게 중요한 것은 아닙니다. 다음은 다른 도구가 더 나은 선택인 경우입니다.
동시에 여러 애플리케이션이 동일한 데이터베이스에 쓰기 작업을 해야 하는 경우.
LatticeDB는 단일 작성자 모델(single-writer model)을 갖춘 임베디드 방식입니다. 하나의 프로세스가 파일을 열고 소유합니다. 네트워크를 통해 많은 클라이언트가 연결되어야 한다면, Neo4j, PostgreSQL 또는 다른 클라이언트-서버 데이터베이스를 사용하십시오.
데이터가 근본적으로 테이블 형태일 때.
만약 데이터가 행과 열에 자연스럽게 맞는 경우(판매 기록, 사용자 계정, 시계열 등) SQLite나 PostgreSQL 같은 관계형 데이터베이스(RDBMS)가 더 간단하고 충분히 빠를 것입니다. 그래프 데이터베이스는 레코드 간의 관계 자체가 핵심일 때 빛을 발합니다.
단일 머신을 넘어 확장해야 할 때.
LatticeDB는 모든 것을 하나의 파일에 한 대의 머신에 저장합니다. 이 파일의 변경 사항을 다른 곳으로 지속적으로 전송할 수 있어 디스크 장애가 전체 손실이 아닌 몇 초 단위로 비용이 발생하지만, 이는 클러스터링(clustering)이라기보다는 백업(backup)입니다. 샤딩(sharding), 읽기를 처리하는 다중 노드 복제본(multi-node replicas), 또는 수십억 개의 노드를 가로지르는 분산 쿼리(distributed queries)가 필요하다면 Neo4j 클러스터, Dgraph, 또는 Neptune과 같은 관리형 서비스를 살펴보세요.
완전한 Cypher 언어가 필요할 때.
LatticeDB는 Cypher의 대부분을 지원하지만 전부를 지원하지는 않습니다. OPTIONAL MATCH나 CALL 프로시저와 같은 기능은 아직 구현되지 않았습니다. 쿼리가 이러한 기능에 의존한다면, Neo4j가 완벽한 구현체입니다.
성숙한 도구 및 생태계가 필요할 때.
Neo4j는 시각화 도구(visualization tools), 관리 대시보드(admin dashboards), 모니터링, 모든 언어의 드라이버, 그리고 수년간 축적된 커뮤니티 리소스를 갖추고 있습니다. PostgreSQL은 수십 년간의 도구를 보유하고 있습니다. LatticeDB는 새롭고 간결하지만 — 이는 임베딩(embedding) 측면에서는 강점일 수 있으나, 데이터베이스 주변에 풍부한 운영 생태계가 필요하다면 약점이 될 수 있습니다.
소스 코드에서 빌드하기