SingleStore 9 — Vector & Hybrid Search
SingleStore 9 — Vector & Hybrid Search
Các bài trước đã dựng một CSDL quan hệ phân tán, HTAP, biết lưu cột nén và index tốt. Bài này thêm một mảnh ghép của thời đại AI: tìm kiếm theo ngữ nghĩa (semantic search) dựa trên vector embedding. Điểm mấu chốt cần khắc cốt ghi tâm: SingleStore không phải một "vector database" riêng lẻ — nó là một CSDL SQL quan hệ có thêm khả năng vector. Nhờ vậy bạn gộp được filter quan hệ + full-text + tìm vector gần đúng trong DUY NHẤT một câu SQL, thay vì phải bê dữ liệu qua một hệ vector chuyên dụng thứ hai rồi tự khâu kết quả lại.
Mô hình tinh thần: embedding là "toạ độ ngữ nghĩa"
Một mô hình học sâu (embedding model) biến văn bản/ảnh/giao dịch thành một vector số thực có vài trăm đến vài nghìn chiều (ví dụ 384, 768, 1536 chiều). Ý nghĩa cốt lõi: hai nội dung có ngữ nghĩa gần nhau → hai vector nằm gần nhau trong không gian nhiều chiều. "Gần" ở đây đo bằng khoảng cách (càng nhỏ càng giống) hoặc độ tương đồng (càng lớn càng giống).
Tìm kiếm ngữ nghĩa vì thế quy về một bài toán hình học: cho một vector truy vấn q (embedding của câu hỏi), tìm k vector gần q nhất trong bảng — bài toán k-nearest-neighbors (kNN).
Lưu ý ranh giới: SingleStore không tự sinh embedding. Bạn gọi mô hình (OpenAI, mô hình nội bộ, v.v.) ở tầng ứng dụng/pipeline, rồi lưu vector vào SingleStore và tìm kiếm trên đó.
Kiểu dữ liệu VECTOR
SingleStore (bản mới) có kiểu VECTOR(n[, elem_type]) — một mảng số có độ dài cố định n chiều, mặc định phần tử là số thực 32-bit. Trước khi có kiểu native này, embedding thường được lưu dạng BLOB và các hàm khoảng cách vẫn hoạt động trên đó; kiểu VECTOR giúp khai báo rõ ràng, kiểm tra chiều, và gắn được vector index.
-- SingleStore (cú pháp tương thích MySQL) — minh hoạ, KHÔNG chạy trong sandbox
CREATE TABLE kb_docs (
doc_id BIGINT NOT NULL,
customer_id BIGINT,
doc_type VARCHAR(32), -- 'contract', 'email', 'sao_ke'...
lang VARCHAR(8),
created_at DATETIME,
body TEXT, -- nội dung gốc (cho full-text)
embedding VECTOR(1536) NOT NULL, -- toạ độ ngữ nghĩa
SHARD KEY (doc_id),
KEY (customer_id) USING HASH,
SORT KEY (created_at)
) USING CLUSTERED COLUMNSTORE;
Điểm cần nhớ:
- Chiều phải cố định và khớp mô hình sinh ra nó. Trộn vector 768 và 1536 chiều vào cùng cột là vô nghĩa.
- Vector nằm ngay trong bảng quan hệ, cạnh
customer_id,doc_type,created_at. Đây là nền tảng cho việc lọc quan hệ + vector chung một query. - Bảng dùng
CLUSTERED COLUMNSTORE(xem Universal Storage) — hợp cho khối embedding lớn, nén tốt; đồng thời Universal Storage cho phép point-lookup/update để cập nhật tài liệu.
Hàm khoảng cách & tương đồng
Hai hàm cốt lõi để so hai vector:
| Hàm | Trả về | "Giống nhau" khi | Sắp xếp lấy top-k |
|---|---|---|---|
DOT_PRODUCT(a, b) | Tích vô hướng (độ tương đồng) | Giá trị càng LỚN | ORDER BY ... DESC |
EUCLIDEAN_DISTANCE(a, b) | Khoảng cách Euclid (L2) | Giá trị càng NHỎ | ORDER BY ... ASC |
Vài lưu ý quan trọng:
- Chuẩn hoá (normalize) để có cosine similarity: nếu bạn chuẩn hoá mọi vector về độ dài 1 (unit length), thì
DOT_PRODUCTchính bằng cosine similarity — thước đo phổ biến nhất cho text embedding. Nhiều pipeline chuẩn hoá vector ngay khi sinh để dùng thẳngDOT_PRODUCT. - Nhất quán thước đo: phải dùng cùng một metric khi build embedding, khi build vector index, và khi truy vấn. Trộn metric là nguyên nhân kinh điển khiến kết quả "gần đúng" trở nên vô nghĩa.
- Ngoài dạng hàm, bản mới còn hỗ trợ toán tử hạ tầng tương ứng cho vector; nếu không chắc ký hiệu cụ thể của phiên bản đang dùng, cứ dùng dạng hàm
DOT_PRODUCT/EUCLIDEAN_DISTANCEcho rõ ràng và tra docs để xác nhận.
Tìm chính xác (exact kNN) vs. gần đúng (ANN)
Cách đơn giản nhất là quét toàn bộ (exact / brute-force kNN): tính khoảng cách từ q tới mọi hàng rồi sắp xếp lấy top-k. Kết quả chính xác tuyệt đối, nhưng chi phí tuyến tính theo số hàng — vài triệu vector nghìn chiều là rất nặng. Với bảng nhỏ hoặc sau khi đã lọc quan hệ còn ít hàng, exact kNN hoàn toàn ổn (và nhờ MPP + code generation của SingleStore, quét song song trên các leaf khá nhanh).
Khi khối vector lớn, ta cần ANN — Approximate Nearest Neighbor: đánh đổi một chút độ chính xác (recall < 100%) để lấy tốc độ nhanh gấp nhiều lần. SingleStore hỗ trợ vector index để làm việc này. Về mặt định tính có hai họ thuật toán phổ biến mà bản mới hỗ trợ:
- IVF (inverted file, ví dụ
IVF_PQ): phân cụm không gian vector thành nhiều "ô" (centroid); truy vấn chỉ quét vài ô gầnqthay vì toàn bộ. Biến thể PQ (product quantization) nén vector để giảm bộ nhớ và tăng tốc, đổi lại mất mát nhẹ. - HNSW (đồ thị phân tầng): xây một đồ thị "hàng xóm gần" nhiều tầng, đi men theo đồ thị để tới vùng gần
qrất nhanh. Thường cho recall/tốc độ tốt, đổi lại tốn RAM hơn khi build.
Đây là ví dụ các loại index; tên và tuỳ chọn cụ thể phụ thuộc phiên bản SingleStore. Hãy tra mục "Vector Indexing" trong docs để lấy đúng cú pháp
INDEX_OPTIONSvà danh sáchindex_typecủa phiên bản bạn dùng — đừng đoán tham số.
Điểm chung với triết lý index ở bài chỉ mục & tối ưu: index không miễn phí — nó tốn dung lượng/RAM và làm ghi chậm hơn; chỉ dựng vector index khi khối dữ liệu đủ lớn để exact kNN thành nút cổ chai.
Câu truy vấn vector thật
Đây là dạng truy vấn semantic search cốt lõi — tìm 5 tài liệu gần nhất với vector truy vấn :q:
-- SingleStore — top-k theo độ tương đồng (minh hoạ)
SELECT
doc_id,
doc_type,
DOT_PRODUCT(embedding, :q) AS similarity -- :q là VECTOR(1536) của câu hỏi
FROM kb_docs
ORDER BY similarity DESC -- tương đồng lớn nhất lên đầu
LIMIT 5;
Sức mạnh thật sự lộ ra khi gộp filter quan hệ vào cùng câu — điều mà một vector store thuần tuý làm rất vụng:
-- SingleStore — vector search CÓ điều kiện quan hệ, trong 1 truy vấn (minh hoạ)
SELECT
d.doc_id,
d.doc_type,
c.segment,
DOT_PRODUCT(d.embedding, :q) AS similarity
FROM kb_docs AS d
JOIN customers AS c ON c.customer_id = d.customer_id
WHERE d.lang = 'vi'
AND d.doc_type IN ('contract', 'sao_ke')
AND d.created_at >= '2026-01-01' -- lọc quan hệ trước
AND c.segment = 'PRIORITY'
ORDER BY similarity DESC
LIMIT 10;
Đây chính là luận điểm trung tâm: filter theo ngôn ngữ, loại tài liệu, thời gian, phân khúc khách hàng + xếp hạng theo ngữ nghĩa — tất cả trong một câu SQL, một engine, một giao dịch nhất quán. Không cần đồng bộ hai hệ, không lệch dữ liệu, dùng được JOIN, GROUP BY, quyền truy cập quan hệ như bình thường.
Lưu ý kỹ thuật: khi có
WHERElọc chặt, đôi khi exact kNN trên tập đã lọc lại nhanh và chính xác hơn ANN. Ngược lại, để ANN index phát huy,ORDER BYphải khớp đúng metric mà index được xây. DùngEXPLAIN/PROFILE(xem [query execution]/[indexing]) để xác nhận optimizer có dùng vector index hay không.
Hybrid search: full-text MATCH + vector
Vector search giỏi nắm ngữ nghĩa nhưng có thể bỏ sót từ khoá chính xác (số hợp đồng, mã giao dịch, tên riêng hiếm). Full-text search thì ngược lại: khớp từ khoá tốt, nhưng "mù" ngữ nghĩa. Hybrid search kết hợp cả hai để bù khuyết điểm của nhau.
SingleStore hỗ trợ full-text search qua FULLTEXT index và cú pháp MATCH (col) AGAINST ('...'), trả về điểm liên quan (relevance score) theo từ khoá. Vì cả full-text lẫn vector đều nằm trong cùng bảng SQL, ta ghép chúng trong một truy vấn:
Một cách kết hợp trực tiếp là cộng có trọng số hai điểm đã chuẩn hoá:
-- SingleStore — hybrid: full-text + vector trong 1 truy vấn (minh hoạ)
SELECT
doc_id,
doc_type,
MATCH (body) AGAINST ('phí thường niên thẻ tín dụng') AS text_score,
DOT_PRODUCT(embedding, :q) AS vec_score,
0.4 * MATCH (body) AGAINST ('phí thường niên thẻ tín dụng')
+ 0.6 * DOT_PRODUCT(embedding, :q) AS final_score
FROM kb_docs
WHERE lang = 'vi'
HAVING text_score > 0 OR vec_score > 0.75 -- giữ ứng viên đủ liên quan
ORDER BY final_score DESC
LIMIT 10;
Trọng số (0.4/0.6) là tham số cần chỉnh theo dữ liệu thực; ngoài weighted-sum, thực tế còn dùng rank fusion (ví dụ Reciprocal Rank Fusion) để tránh phụ thuộc thang điểm của hai phương pháp. Ý tưởng cốt lõi giữ nguyên: cùng một bảng, một câu SQL cho ra kết quả vừa đúng từ khoá vừa đúng ngữ nghĩa.
Vì sao "gộp trong 1 truy vấn" là lợi thế lớn
Kiến trúc điển hình khi dùng một vector DB riêng: dữ liệu quan hệ ở CSDL chính, embedding ở vector store; ứng dụng phải (1) truy vấn vector store lấy id, (2) quay lại CSDL lọc/join theo quyền, thời gian, trạng thái, (3) tự trộn kết quả. Hệ quả: hai nguồn sự thật dễ lệch, lộ trình phức tạp, khó đảm bảo nhất quán và bảo mật ở tầng dòng.
Với SingleStore, embedding là một cột trong bảng quan hệ, nên:
- Nhất quán giao dịch: cập nhật tài liệu và cập nhật vector trong cùng transaction (ACID).
- Một mặt phẳng bảo mật/quyền: cùng cơ chế phân quyền quan hệ áp cho cả tìm kiếm ngữ nghĩa.
- Sức mạnh SQL đầy đủ:
JOIN,WHERE,GROUP BY, aggregate, window — áp thẳng lên kết quả vector. - Đơn giản vận hành: một hệ để backup/HA/giám sát thay vì hai.
Use case thực tế
Bối cảnh (minh hoạ): NCB xây trợ lý RAG cho nhân viên hỗ trợ khách hàng, tra cứu trên ~8 triệu tài liệu (hợp đồng, biểu phí, email, sao kê) đã embedding 1536 chiều. Đồng thời tái dùng chính hạ tầng này cho một use case chống gian lận: tìm các giao dịch "tương tự về hành vi" với một giao dịch nghi vấn.
Cách làm:
- RAG semantic search: câu hỏi của nhân viên được embedding ở tầng app, đẩy xuống SingleStore. Truy vấn hybrid (full-text
MATCHcho mã hợp đồng/biểu phí chính xác +DOT_PRODUCTcho ngữ nghĩa), kèmWHERE lang='vi'và lọc theo quyền xem theo phân khúc khách hàng — tất cả một câu SQL. Top-5 đoạn liên quan được nạp làm ngữ cảnh cho mô hình sinh câu trả lời. - Tìm giao dịch tương tự / chống gian lận: mỗi giao dịch có vector đặc trưng (số tiền, kênh, thời điểm, mô tả đối tác...). Khi một giao dịch bị gắn cờ, hệ chạy
ORDER BY DOT_PRODUCT(feature_vec, :nghi_van) DESC LIMIT 50cộng với filter quan hệ (WHERE txn_time >= ... AND channel = 'ONLINE' AND amount > 50000000) để khoanh vùng nhanh các giao dịch có mẫu hành vi giống, phục vụ điều tra AML. - Chọn exact vs. ANN: với truy vấn đã lọc quan hệ còn vài chục nghìn hàng, đội dùng exact kNN (chính xác 100%, đủ nhanh nhờ MPP). Với quét toàn kho tài liệu, dùng vector index ANN để giữ độ trễ tương tác thấp.
Các con số chỉ mang tính minh hoạ. Giá trị cốt lõi: một nền tảng phục vụ cả OLTP giao dịch, phân tích, lẫn semantic/vector search — không phải bê dữ liệu qua hệ thứ ba.
Ghi nhớ
- SingleStore là CSDL SQL quan hệ CÓ khả năng vector, không phải vector DB riêng — điểm mạnh là gộp filter quan hệ + full-text + vector trong 1 truy vấn.
- Kiểu
VECTOR(n)lưu embedding chiều cố định ngay trong bảng quan hệ; chiều phải khớp mô hình sinh ra nó. DOT_PRODUCT(càng lớn càng giống →ORDER BY ... DESC) vàEUCLIDEAN_DISTANCE(càng nhỏ càng gần →ORDER BY ... ASC); chuẩn hoá vector đểDOT_PRODUCT= cosine similarity. Giữ nhất quán một metric.- Exact kNN cho kết quả chính xác 100% nhưng quét tuyến tính; ANN vector index (ví dụ IVF_PQ, HNSW) đổi chút recall lấy tốc độ khi khối vector lớn.
- Sau khi lọc quan hệ chặt, đôi khi exact kNN trên tập nhỏ lại nhanh và đúng hơn ANN — dùng
EXPLAIN/PROFILEđể kiểm. - Hybrid search = full-text
MATCH ... AGAINST(từ khoá) + vector (ngữ nghĩa), kết hợp bằng weighted-sum hoặc rank fusion; trọng số phải chỉnh theo dữ liệu. - Use case ngân hàng: RAG/semantic search tài liệu và tìm giao dịch tương tự / chống gian lận — cùng một nền tảng, nhất quán ACID và một mặt phẳng bảo mật.
- Không chắc tên
index_type/cú phápINDEX_OPTIONScủa phiên bản → tra docs, đừng đoán.
Nguồn tham khảo
- SingleStore Documentation — Vector Type (
VECTOR) - SingleStore Documentation — Vector Functions (
DOT_PRODUCT,EUCLIDEAN_DISTANCE) - SingleStore Documentation — Vector Indexing (ANN,
index_type: IVF / HNSW và biến thể) - SingleStore Documentation — Full-Text Search (
FULLTEXTindex,MATCH ... AGAINST) - SingleStore Documentation — Hybrid Search
- SingleStore Documentation — Columnstore / Universal Storage
- SingleStore Engineering Blog — bài về vector search và hybrid search (khi tra cứu tên bài cụ thể)
Bài viết liên quan
Index (B-Tree) giúp database tìm dữ liệu theo O(log n) thay vì quét tuần tự O(n). Bài giải thích cấu trúc B-Tree, các loại index (hash, composite, partial, covering), khi nào optimizer bỏ index, cách đọc EXPLAIN/EXPLAIN ANALYZE (seq vs index scan, cost, rows, kiểu join), selectivity, leftmost prefix và các mẫu tối ưu: SARGable, keyset pagination, diệt N+1.
Kiến trúc shared-nothing của SingleStore: Master Aggregator giữ metadata và điều phối, Child Aggregator scale kết nối, Leaf node chứa dữ liệu chia thành partition. Bài mổ xẻ luồng một query (aggregator nhận → pushdown xuống leaf → gộp kết quả) và cơ chế High Availability master/replica, failover, redundancy level.
Khoá chính/ngoại/tổng hợp, ràng buộc (NOT NULL, UNIQUE, CHECK, FK) và cách mô hình hoá quan hệ 1:1, 1:n, n:n cho hệ khách hàng — tài khoản — giao dịch. Đi qua chuẩn hoá 1NF/2NF/3NF bằng ví dụ trước/sau cụ thể, rồi bàn khi nào nên cố tình phi chuẩn hoá để đọc nhanh — giúp thiết kế lược đồ đúng ngay từ đầu.
Nhập môn dữ liệu không gian (spatial/geospatial): dữ liệu gắn vị trí trên Trái Đất, các loại hình học điểm/đường/vùng, hệ toạ độ CRS/SRID (WGS84, UTM/VN2000), vector vs raster, quan hệ và phép đo không gian. Đặt nền cho cả series GIS và giá trị của nó với ngân hàng NCB: mạng lưới chi nhánh/ATM, phân tích khách hàng theo địa bàn, rủi ro và gian lận theo vị trí.
Cảm nhận của bạn
Bình luận
Chưa có bình luận. Hãy là người đầu tiên chia sẻ!