Sự bùng nổ của Trí tuệ Nhân tạo và các mô hình Học sâu (Deep Learning) đã tạo ra một dạng dữ liệu hoàn toàn mới và cực kỳ phổ biến: véc-tơ nhúng (embeddings). Để lưu trữ, quản lý và thực hiện tìm kiếm tương đồng trên hàng triệu véc-tơ này ở thời gian thực, các cơ sở dữ liệu truyền thống (SQL/NoSQL) không thể đáp ứng được hiệu năng. Đó là lý do Cơ sở dữ liệu Vector (Vector Database) ra đời.
Bài học này sẽ đưa bạn đi từ gốc rễ bài toán: Dữ liệu phi cấu trúc là gì, tại sao biểu diễn véc-tơ lại quan trọng, sự khác biệt kiến trúc cốt lõi với SQL, cho đến các thách thức toán học trong không gian đa chiều và các giải thuật tìm kiếm kinh điển.
1.1 Sự trỗi dậy của Dữ liệu phi cấu trúc và Vector nhúng (Embeddings)
Trong thế giới số, hơn 80% dữ liệu được tạo ra là dữ liệu phi cấu trúc (unstructured data): bài viết, email, tệp âm thanh, video, hình ảnh... Dữ liệu này không thể biểu diễn trực tiếp dưới dạng các bảng dòng-cột rõ ràng của cơ sở dữ liệu quan hệ. Trước đây, để tìm kiếm trên dữ liệu này, chúng ta sử dụng tìm kiếm từ khóa (lexical search) bằng cách bóc tách chuỗi thô. Tuy nhiên, cách này hoàn toàn bỏ qua ngữ cảnh và ý nghĩa thực sự của dữ liệu.
Các mô hình học sâu hiện đại giải quyết bài toán này bằng cách dịch chuyển dữ liệu phi cấu trúc sang một không gian đặc trưng dày đặc (dense feature space). Mỗi phần tử dữ liệu (một đoạn văn, một bức ảnh) sẽ được mô hình ánh xạ thành một véc-tơ nhúng dày đặc (dense vector / embedding) - thực chất là một mảng gồm các số thực dấu phẩy động có độ dài cố định (thường từ 768 đến 1536 chiều).
Mỗi chiều trong véc-tơ nhúng đại diện cho một đặc trưng ẩn (latent feature) mà mô hình tự học được. Ví dụ, một chiều có thể đại diện cho "độ trang trọng" của văn bản, một chiều khác đại diện cho "chủ đề công nghệ". Các điểm dữ liệu có ý nghĩa ngữ nghĩa tương tự nhau sẽ được mô hình kéo gần nhau trong không gian véc-tơ này.
Để lưu trữ các véc-tơ này, một bản ghi cơ sở dữ liệu vector thường chứa một định danh duy nhất (ID), chính mảng véc-tơ nhúng (embedding), và dữ liệu thuộc tính đi kèm (metadata) để lọc.
{
"id": "article-94812",
"vector": [0.1283, -0.0512, 0.8921, 0.3412, -0.2201, 0.0418, 0.5123, -0.1982],
"metadata": {
"title": "Cơ sở dữ liệu Vector là gì?",
"author": "Quang Tang",
"category": "Artificial Intelligence",
"publish_date": "2026-07-20"
}
}
1.2 Phân biệt CSDL truyền thống vs CSDL Vector
Sự khác biệt lớn nhất giữa cơ sở dữ liệu truyền thống (như PostgreSQL, MySQL) và cơ sở dữ liệu vector nằm ở mục tiêu truy vấn và cơ chế chỉ mục:
-
CSDL truyền thống (SQL/NoSQL): Tìm kiếm dựa trên phép so khớp chính xác (exact match)
của các giá trị hoặc khoảng giá trị (ví dụ:
WHERE price < 100hoặcWHERE username = 'bob'). Chỉ mục được xây dựng trên cấu trúc cây B-Tree hoặc LSM-Tree để tra cứu trong thời gian $O(\log N)$. - CSDL Vector: Tìm kiếm dựa trên sự tương đồng hình học (similarity search) trong không gian metric đa chiều. Câu hỏi không phải là "véc-tơ nào bằng khít véc-tơ này?", mà là "những véc-tơ nào nằm gần véc-tơ truy vấn nhất?".
Dưới đây là bảng đối chiếu chi tiết giữa hai hệ thống:
| Đặc tính | Cơ sở dữ liệu Quan hệ (Relational) | Cơ sở dữ liệu Vector (Vector DB) |
|---|---|---|
| Mô hình dữ liệu | Bảng (Dòng & Cột) có cấu trúc nghiêm ngặt. | Mảng véc-tơ nhúng số thực kèm Metadata JSON. |
| Cơ chế so khớp | So khớp chính xác hoặc lọc logic (AND, OR, =). |
So khớp xấp xỉ khoảng cách gần nhất (L2, Cosine). |
| Cấu trúc chỉ mục | B-Tree, Hash Index, LSM-Tree. | HNSW (Đồ thị), IVF (Danh sách ngược), PQ (Lượng tử hóa). |
| Độ phức tạp truy vấn | $O(\log N)$ cực nhanh và chính xác 100%. | $O(N)$ (KNN thô) hoặc $O(\log N)$ (ANN xấp xỉ). |
Một số lập trình viên cố gắng lưu véc-tơ dưới dạng mảng số trong SQL và viết câu lệnh tính khoảng cách thủ công (ví dụ chạy phép tính cộng bình phương hiệu số). Điều này dẫn đến việc hệ quản trị cơ sở dữ liệu phải quét toàn bộ bảng (Table Scan / Sequential Scan). Khi số dòng đạt tới vài chục nghìn, câu lệnh truy vấn sẽ nghẽn hoàn toàn và tốn hàng giây để phản hồi.
1.3 Lời nguyền chiều kích (Curse of Dimensionality)
Tại sao chúng ta không thể sử dụng các cấu trúc chỉ mục phân hoạch không gian thông thường (như KD-Tree hay R-Tree) vốn hoạt động rất tốt trong không gian 2D hoặc 3D cho véc-tơ nhúng?
Câu trả lời nằm ở hiện tượng hình học kỳ lạ trong không gian nhiều chiều được gọi là Lời nguyền chiều kích (Curse of Dimensionality). Khi số chiều $d$ tiến tới vô cùng, khoảng cách giữa điểm gần nhất và điểm xa nhất trong một tập điểm ngẫu nhiên sẽ dần hội tụ về bằng nhau.
Về mặt toán học, nếu ta chọn ngẫu nhiên các điểm trong một khối lập phương đơn vị $d$ chiều, tỉ số chênh lệch khoảng cách:
\[\lim_{d \to \infty} \frac{D_{\max} - D_{\min}}{D_{\min}} = 0\]Trong đó $D_{\max}$ và $D_{\min}$ lần lượt là khoảng cách lớn nhất và nhỏ nhất giữa các điểm. Khi tỉ số này tiến về 0, mọi điểm dữ liệu đều trở nên "cách đều nhau". Mọi ranh giới hình học bị xóa nhòa, khiến việc phân chia không gian bằng các mặt phẳng cắt (như cơ chế của KD-Tree) mất hoàn toàn tác dụng phân nhóm, quay trở về độ phức tạp quét tuyến tính $O(N)$.
Để tự kiểm chứng điều này, đoạn mã JavaScript dưới đây sinh các điểm ngẫu nhiên trong không gian 2 chiều và 100 chiều để đo lường tỉ số chênh lệch:
function getMinMaxRatio(dimensions, numPoints = 100) {
// Tạo các điểm ngẫu nhiên d chiều
const points = Array.from({ length: numPoints }, () =>
Array.from({ length: dimensions }, () => Math.random())
);
let min = Infinity;
let max = 0;
for (let i = 0; i < numPoints; i++) {
for (let j = i + 1; j < numPoints; j++) {
let sum = 0;
for (let k = 0; k < dimensions; k++) {
const diff = points[i][k] - points[j][k];
sum += diff * diff;
}
const dist = Math.sqrt(sum);
if (dist < min) min = dist;
if (dist > max) max = dist;
}
}
return (max - min) / min;
}
console.log("Tỉ số chênh lệch ở không gian 2 chiều:", getMinMaxRatio(2));
console.log("Tỉ số chênh lệch ở không gian 100 chiều:", getMinMaxRatio(100));
1.4 Giải thuật lân cận gần nhất: KNN thô vs Tìm kiếm xấp xỉ ANN
Để giải quyết bài toán tìm kiếm tương đồng vector, chúng ta chia làm hai nhóm giải thuật chính:
- K-Nearest Neighbors (KNN) chính xác: Duyệt qua tất cả các bản ghi trong cơ sở dữ liệu, tính toán khoảng cách hình học giữa véc-tơ truy vấn và từng véc-tơ lưu trữ, sau đó sắp xếp để lấy ra K điểm gần nhất. Thuật toán này đảm bảo độ chính xác (Recall) 100% nhưng có độ phức tạp thời gian là $O(d \cdot N)$ với $N$ là tổng số điểm và $d$ là số chiều.
- Approximate Nearest Neighbor (ANN) xấp xỉ: Chấp nhận đánh đổi một chút độ chính xác (ví dụ Recall đạt 95% - 99%) để đổi lấy tốc độ tìm kiếm vượt trội nhờ cấu trúc chỉ mục thông minh. ANN giảm độ phức tạp tìm kiếm xuống còn $O(\log N)$ hoặc $O(\sqrt{N})$.
Dưới đây là một triển khai cơ bản của thuật toán KNN chính xác trên Node.js để bạn nắm vững cơ chế tính khoảng cách:
function exactKNN(query, dataset, k) {
const scored = dataset.map((item) => {
// Tính khoảng cách Euclidean L2
let sum = 0;
for (let i = 0; i < query.length; i++) {
const diff = query[i] - item.vector[i];
sum += diff * diff;
}
const dist = Math.sqrt(sum);
return { item, distance: dist };
});
// Sắp xếp tăng dần theo khoảng cách
scored.sort((a, b) => a.distance - b.distance);
// Trả về K phần tử gần nhất
return scored.slice(0, k).map(s => s.item.id);
}
const mockDb = [
{ id: "A", vector: [0.1, 0.2] },
{ id: "B", vector: [0.9, 0.8] },
{ id: "C", vector: [0.15, 0.22] }
];
console.log("KNN kết quả:", exactKNN([0.11, 0.21], mockDb, 2)); // Kết quả sẽ là ['A', 'C']
Khi sử dụng tìm kiếm KNN thô trên tập dữ liệu nhỏ (vài nghìn điểm), bạn hoàn toàn không cần xây dựng chỉ mục phức tạp (IVF/HNSW). Cơ chế Flat Index (tìm kiếm vét cạn) chạy trực tiếp trên mảng nhị phân trong bộ nhớ RAM có độ trễ cực nhỏ và độ chính xác tuyệt đối.
1.5 Ứng dụng thực tế: Hệ gợi ý và Tìm kiếm ngữ nghĩa
Vector DB đóng vai trò xương sống cho hai bài toán kinh điển của AI:
- Tìm kiếm ngữ nghĩa (Semantic Search): Khắc phục nhược điểm của tìm kiếm từ khóa. Khi người dùng nhập "phương tiện di chuyển hai bánh", mô hình nhúng dịch nghĩa của truy vấn và tìm thấy các vector của từ "xe máy", "xe đạp" dù không trùng khớp bất kỳ chữ cái nào với từ khóa tìm kiếm.
- Hệ thống gợi ý (Recommendation Systems): Gợi ý bài hát, phim ảnh tương tự dựa trên hành vi người dùng. Hành vi hoặc sở thích được nén thành một véc-tơ đặc trưng, và Vector DB sẽ nhanh chóng lấy ra Top K sản phẩm có đặc trưng tương đồng nhất.
Ví dụ dưới đây mô phỏng một kịch bản tìm kiếm ngữ nghĩa đơn giản sử dụng Mock Embedding và Vector DB:
const documents = [
{ id: "doc_1", text: "Học lập trình JavaScript cơ bản cho người mới bắt đầu", vector: [0.85, 0.12] },
{ id: "doc_2", text: "Cách làm bánh mì Việt Nam giòn xốp tại nhà", vector: [0.11, 0.92] },
{ id: "doc_3", text: "Tối ưu hóa mã nguồn C++ và quản lý bộ nhớ Heap", vector: [0.79, 0.15] }
];
// Query: "viết mã js" -> được Embedding Model chuyển đổi thành vector [0.88, 0.10]
const queryVector = [0.88, 0.10];
function searchSemantic(queryVec, docs, k = 1) {
const results = docs.map(doc => {
// Tính Euclidean L2
const d = Math.sqrt(
(queryVec[0] - doc.vector[0])**2 + (queryVec[1] - doc.vector[1])**2
);
return { doc, distance: d };
});
results.sort((a, b) => a.distance - b.distance);
return results.slice(0, k).map(r => r.doc.text);
}
console.log("Kết quả tìm kiếm ngữ nghĩa:", searchSemantic(queryVector, documents, 1));
// Đầu ra sẽ là bài viết JavaScript nhờ sự tương đồng ngữ nghĩa lớn
Trong các ứng dụng chatbot doanh nghiệp, Vector DB đóng vai trò như bộ nhớ ngoài (Long-term memory). Khi người dùng đặt câu hỏi, hệ thống truy vấn Vector DB để lấy ra các đoạn tài liệu liên quan nhất (Context), sau đó nhét đoạn tài liệu này vào prompt gửi cho LLM (GPT-4, Claude). Điều này giúp LLM trả lời chính xác thông tin nội bộ mà không cần phải tinh chỉnh (fine-tune) lại mô hình.
Trải nghiệm Trực quan hóa Tương tác
Dưới đây là trình Lab thực nghiệm tương tác 2D. Bạn có thể Click để đặt điểm Query (sao đỏ) và quan sát vòng tròn quét khoảng cách tối đa của chỉ mục Flat Index tìm kiếm KNN:
📖 Tài liệu tham khảo
Tải file code thực hành minh họa bài học
Tải tệp tin code mẫu JavaScript chạy độc lập để thực nghiệm KNN Search và Lời nguyền chiều kích trên máy tính của bạn:
Tải về vectordb_basics_demo.js
Bình luận