벡터 검색
벡터 검색 (Vector Search)
Turso의 네이티브 벡터 검색으로 시맨틱 검색, 추천 시스템, RAG 워크플로를 만드는 방법이에요. 확장 설치 없이 SQL 안에서 바로 벡터를 다룰 수 있어요.
출처: 문서
본문
Turso는 벡터 검색을 네이티브 기능으로 지원해요 — 확장이 전혀 필요 없어요. 벡터 임베딩을 관계형 데이터와 나란히 저장하고, 내장 거리 함수로 유사도 검색 쿼리를 할 수 있어요.
벡터 타입 (Vector Types)
Turso는 dense, sparse, quantized, binary 벡터 표현을 지원하고, 각각 어울리는 워크로드가 달라요.
Dense Vectors
dense 벡터는 모든 차원에 값을 저장해요. Turso는 두 가지 정밀도를 제공해요:
| Function | Precision | Storage per dimension | Best for |
|---|---|---|---|
vector32 |
32-bit float | 4 bytes | 대부분의 ML 임베딩 (OpenAI, sentence transformers) |
vector64 |
64-bit float | 8 bytes | 더 높은 정밀도가 필요한 애플리케이션 |
Sparse Vectors
sparse 벡터는 0이 아닌 값과 그 인덱스만 저장해서, 0이 많은 고차원 데이터에서 메모리를 아껴요.
| Function | Storage | Best for |
|---|---|---|
vector32_sparse |
Non-zero values + indices | TF-IDF, bag-of-words, 고차원 희소 데이터 |
Quantized Vectors
| Function | Storage per dimension | Best for |
|---|---|---|
vector8 |
1 byte (+8 bytes overhead) | Float32 대비 약 4배 압축이 미세한 정밀도 손실보다 가치 있는 대규모 검색 |
값은 min/max 스케일링으로 0-255 범위에 선형 양자화돼요. 역양자화는 f_i = alpha * q_i + shift예요.
Binary Vectors
| Function | Storage per dimension | Best for |
|---|---|---|
vector1bit |
1 bit | 이진 해싱, 근사 최근접 이웃 검색(Float32 대비 약 32배 압축) |
양수는 1로, 0 이하는 0으로 바뀌어요. 추출된 값은 +1/-1로 표시돼요.
대부분의 애플리케이션에서는
vector32가 좋은 출발점이에요. 테이블에 행이 아주 많다면 더 컴팩트한 타입도 탐색해 보세요.
벡터 저장하기 (Storing Vectors)
BLOB 컬럼을 만들어 관계형 데이터와 함께 임베딩을 저장해요:
CREATE TABLE documents (
id INTEGER PRIMARY KEY,
title TEXT,
content TEXT,
embedding BLOB
);
적절한 변환 함수로 벡터 임베딩이 든 행을 넣어요:
INSERT INTO documents (title, content, embedding) VALUES
('Machine learning basics', 'An introduction to ML concepts...', vector32('[0.2, 0.5, 0.1, 0.8]')),
('Database fundamentals', 'How relational databases work...', vector32('[0.1, 0.3, 0.9, 0.2]')),
('Neural networks guide', 'Deep learning architectures...', vector32('[0.3, 0.6, 0.2, 0.7]'));
sparse 벡터는 0 값이 자동으로 압축돼요:
INSERT INTO documents (title, content, embedding) VALUES
('Sparse example', 'A document with sparse features...', vector32_sparse('[0.0, 1.5, 0.0, 2.3, 0.0]'));
유사도 검색 (Similarity Search)
거리 함수로 가장 비슷한 벡터를 찾아요. 모든 거리 함수는 두 벡터가 같은 타입과 차원 수여야 해요. 값이 작을수록 더 유사해요.
코사인 거리 (Cosine Distance)
벡터 사이의 각도를 측정해요. 크기(magnitude)는 무시해요. 0(같은 방향)에서 2(반대 방향) 사이의 값을 반환해요.
SELECT title,
vector_distance_cos(embedding, vector32('[0.25, 0.55, 0.15, 0.75]')) AS distance
FROM documents
ORDER BY distance
LIMIT 5;
방향이 크기보다 중요한 텍스트 임베딩과 문서 유사도에 가장 적합해요.
유클리드 (L2) 거리 (Euclidean (L2) Distance)
n차원 공간에서의 직선 거리를 측정해요. vector1bit 벡터에서는 지원하지 않아요.
SELECT title,
vector_distance_l2(embedding, vector32('[0.25, 0.55, 0.15, 0.75]')) AS distance
FROM documents
ORDER BY distance
LIMIT 5;
이미지 임베딩, 공간 데이터, 절대 차이가 중요한 정규화되지 않은 임베딩에 가장 적합해요.
내적 거리 (Dot Product Distance)
음의 내적을 계산해요: -sum(v1[i] * v2[i]). 값이 작을수록(더 음수일수록) 유사도가 높아요.
SELECT title,
vector_distance_dot(embedding, vector32('[0.25, 0.55, 0.15, 0.75]')) AS distance
FROM documents
ORDER BY distance
LIMIT 5;
정규화된 임베딩(벡터가 단위 길이일 때는 코사인 거리와 동일)과 최대 내적 검색(MIPS)에 가장 적합해요.
자카드 거리 (Jaccard Distance)
차원별 최솟값과 최댓값의 비율을 기반으로 가중 자카드 거리를 계산해요. vector1bit 벡터에서는 이진 자카드 거리를 계산해요.
SELECT title,
vector_distance_jaccard(embedding, vector32_sparse('[0.0, 1.0, 0.0, 2.0]')) AS distance
FROM documents
ORDER BY distance
LIMIT 5;
sparse 벡터, 집합 비교, TF-IDF 표현, vector1bit의 이진 유사도에 가장 적합해요.
유틸리티 함수 (Utility Functions)
vector_extract
벡터 BLOB을 읽을 수 있는 JSON 표현으로 바꿔요:
SELECT vector_extract(embedding) FROM documents WHERE id = 1;
-- [0.200000,0.500000,0.100000,0.800000]
vector_concat
두 벡터를 하나로 이어 붙여요:
SELECT vector_extract(
vector_concat(vector32('[1.0, 2.0]'), vector32('[3.0, 4.0]'))
);
-- [1.000000,2.000000,3.000000,4.000000]
vector_slice
벡터의 연속 구간을 추출해요(0 기반, 끝 구간은 제외):
SELECT vector_extract(
vector_slice(vector32('[1.0, 2.0, 3.0, 4.0, 5.0]'), 1, 4)
);
-- [2.000000,3.000000,4.000000]
제약 사항 (Limitations)
vector1bit벡터에서는 유클리드 거리가 지원되지 않아요- 최대 벡터 차원 수는 65,536이에요
vector1bit의 코사인 거리는 표준 코사인 거리 대신 해밍 거리(다른 비트의 개수)를 반환해요
예제: 시맨틱 검색 (Example: Semantic Search)
벡터 저장과 유사도 검색을 결합한 완전한 엔드투엔드 예제예요:
-- Create a table with vector embeddings
CREATE TABLE articles (
id INTEGER PRIMARY KEY,
title TEXT NOT NULL,
content TEXT,
embedding BLOB
);
-- Insert articles with precomputed embeddings
INSERT INTO articles (title, content, embedding) VALUES
('Introduction to Machine Learning', 'ML is a subset of AI...', vector32('[0.12, -0.34, 0.56, 0.78]')),
('Database Design Patterns', 'Relational databases organize...', vector32('[0.82, 0.15, -0.44, 0.23]')),
('Neural Networks Explained', 'Neural networks are computing...', vector32('[0.14, -0.28, 0.62, 0.71]')),
('SQL Query Optimization', 'Efficient queries start with...', vector32('[0.75, 0.22, -0.38, 0.19]'));
-- Find the 3 most similar articles to a query vector
SELECT
title,
content,
vector_distance_cos(embedding, vector32('[0.10, -0.30, 0.50, 0.80]')) AS distance
FROM articles
ORDER BY distance
LIMIT 3;
유사도 검색은 테이블을 선형 스캔해요. 데이터셋이 크다면
WHERE절로 검색 대상 행을 좁히는 걸 고려해 보세요.