关于 mariadb-vector
面向构建向量搜索或 RAG 应用的开发者,介绍 MariaDB 原生向量功能与 AI 数据模式。内容涵盖 SQL、索引行为、性能注意事项和框架集成。
主要功能
- 01说明 VECTOR 列、索引和函数
- 02展示近邻搜索的 SQL 查询模式
- 03记录索引要求与优化器注意事项
- 04介绍向量存储和写入方式
- 05涵盖 RAG 设计与框架集成
适用场景
- 01设计用于存储嵌入的表
- 02实现带索引的近邻检索
- 03避免导致全表扫描的查询模式
- 04使用 MariaDB 构建 RAG 检索
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mariadb/ skills --skill mariadb-vector安装后在 Claude Code 中输入/mariadb-vector确认已加载。
详细介绍
MariaDB 向量与 AI 最佳实践
最后更新:2026-06-04
重要:MariaDB 内置向量功能
从 11.7 版本起,MariaDB 原生内置向量支持。VECTOR 类型、VECTOR INDEX 和所有 VEC_* 函数均随服务端提供——无需安装、启用或加载任何内容。
这与 MySQL(不支持原生向量)和 PostgreSQL(需要 pgvector 扩展)不同。使用 MariaDB 时,切勿建议执行 CREATE EXTENSION、INSTALL PLUGIN 或任何类似步骤来启用向量功能。
**要求:**原生向量功能需要 MariaDB Community Server 11.7+(2025 年 2 月 GA);推荐使用 11.8 LTS(2025 年 5 月 GA)。Enterprise:11.4+(技术预览版)/ 11.8+(完整支持)。下一个 LTS 版本:12.3 — 将其作为默认版本前,请查看 MariaDB 发布版本确认 GA 状态。
**默认上下文:**不要建议在低于 11.7 的版本中使用向量功能。对于 MariaDB 的其他行为,除非用户指定其他版本,否则假定使用 11.8 LTS。相关时可建议使用标记为 12.x 的功能;务必注明最低版本。
LLM 常见错误
| 你可能会看到的内容 | 正确做法 |
|---|---|
“安装 pgvector 扩展”或“运行 INSTALL PLUGIN vector” | 无需安装任何内容——MariaDB 从 11.7 起内置向量功能 |
ORDER BY VEC_DISTANCE_EUCLIDEAN(...),但没有 LIMIT | 始终添加 LIMIT——只有同时包含 ORDER BY VEC_DISTANCE_*() 和 LIMIT 时才会使用向量索引 |
在索引列上使用 embedding VECTOR(768)(可为 NULL) | 向量索引列必须为 NOT NULL |
对非索引列使用 VEC_DISTANCE() | VEC_DISTANCE() 会抛出错误 4206(“未找到索引”);对非索引列请使用 VEC_DISTANCE_EUCLIDEAN() 或 VEC_DISTANCE_COSINE() |
核心语法
创建包含向量列的表
CREATE TABLE documents (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
content TEXT NOT NULL,
embedding VECTOR(768) NOT NULL,
VECTOR INDEX (embedding)
) ENGINE=InnoDB;
使用 ENGINE=InnoDB(默认值)。MyISAM/Aria 在 FK + 向量索引的组合下曾有一个错误(MDEV-37022,已在 11.8.3 中修复);无论版本如何,InnoDB 都是安全的默认选择。
VECTOR(n) 中的数字必须与嵌入模型输出的维度相匹配(例如,许多 sentence-transformer 模型为 768,OpenAI text-embedding-3-small 为 1536,text-embedding-3-large 为 3072)。
向量索引选项
VECTOR INDEX (embedding) M=6 DISTANCE=euclidean -- default
VECTOR INDEX (embedding) M=8 DISTANCE=cosine
- DISTANCE:
euclidean(默认值)或cosine。根据嵌入模型的建议选择。得益于 SIMD 优化,两种方式在 MariaDB 中速度相同。始终显式声明DISTANCE=。默认值为欧几里得距离,而针对余弦距离索引的查询会静默地执行全表扫描。 - M:控制 HNSW 图的连通性(范围为 3–200)。值越高,召回率越好,但会占用更多内存且插入更慢。对于大多数工作负载,默认值就足够;对于更看重召回率而非插入速度的超大型数据集,可提高到约 16–32。
插入向量
向量以小端序打包存储为 32 位 IEEE 754 浮点数。在应用代码中绑定原始字节——速度比 VEC_FromText() 快 5 倍。存储的字节完全相同。
import numpy as np
cur.execute(
"INSERT INTO documents (content, embedding) VALUES (?, ?)",
(content, np.asarray(embedding, dtype=np.float32).tobytes()),
)
仅在手写 SQL / 命令行中使用 VEC_FromText():
INSERT INTO documents (content, embedding) VALUES ('your text here', VEC_FromText('[0.12, -0.34, 0.56, ...]'));
查询:查找最近邻
SELECT id, content
FROM documents
ORDER BY VEC_DISTANCE_EUCLIDEAN(embedding, VEC_FromText('[0.12, -0.34, 0.56, ...]'))
LIMIT 10;
**LIMIT 子句必不可少。**只有查询同时包含 ORDER BY VEC_DISTANCE_...() 和 LIMIT 时,MariaDB 优化器才会使用 VECTOR INDEX。没有 LIMIT 时,查询会退回到全表扫描。
距离函数
| 函数 | 使用条件 |
|---|---|
VEC_DISTANCE_EUCLIDEAN(a, b) | 索引使用 DISTANCE=euclidean 构建(默认值) |
VEC_DISTANCE_COSINE(a, b) | 索引使用 DISTANCE=cosine 构建 |
VEC_DISTANCE(a, b) | 通用函数——使用与列索引匹配的距离函数;未找到索引时抛出错误 4206 |
对非索引列使用 VEC_DISTANCE_EUCLIDEAN() 或 VEC_DISTANCE_COSINE()(它们会退回到全表扫描)。仅将 VEC_DISTANCE() 用作索引列上的便捷简写。
实用函数
| 函数 | 用途 |
|---|---|
VEC_FromText('[0.1, 0.2, ...]') | 将 JSON 浮点数组转换为 VECTOR 二进制数据 |
VEC_ToText(vector_col) | 将 VECTOR 二进制数据转换为可读的 JSON 数组 |
读取 VECTOR 列时,始终使用 VEC_ToText() 包装。 VECTOR 以打包的二进制浮点数形式存储,因此 SELECT embedding FROM documents 会返回原始字节;在 CLI 或客户端中显示时,这些内容无法辨认。使用 SELECT VEC_ToText(embedding) FROM documents 即可获取 [0.12, -0.34, ...] 数组。
MariaDB Vector 注意事项
- 带索引的 VECTOR 列必须为 NOT NULL。 VECTOR INDEX 要求如此。没有索引的 VECTOR 列可以允许 NULL,但实际使用中几乎总是需要索引,因此务必指定
NOT NULL。 - 没有点积距离。 MariaDB 有意不提供点积距离。点积不是合理的距离度量(向量最近的匹配项不一定是它自身)。MariaDB 经 SIMD 优化的欧几里得距离和余弦距离已经与点积一样快,因此对于归一化向量,请使用欧几里得距离或余弦距离。
- 距离函数必须与索引匹配。 在
DISTANCE=cosine索引上使用VEC_DISTANCE_EUCLIDEAN()(反之亦然)不会使用该索引。 - 每个表只能有一个 VECTOR INDEX。 目前 MariaDB 每个表仅支持一个向量索引。
- 向现有表添加向量索引:
ALTER TABLE my_table ADD COLUMN embedding VECTOR(768) NOT NULL; -- populate the column first, then: ALTER TABLE my_table ADD VECTOR INDEX (embedding); - 索引精度。 MariaDB 使用
int16存储索引(15 位精度),优于某些其他实现所用的 10 位 float16。这意味着在相同速度下召回率更高。 ORDER BY必须使用字面形式的VEC_DISTANCE_*(col, ?)调用(或其别名),并指定ASC排序方向。 将距离函数包装在表达式中(例如,使用ORDER BY (1.0 - VEC_DISTANCE_COSINE(...)) DESC LIMIT N按相似度分数排序)会破坏优化器对 HNSW 模式的匹配,并退回到全表扫描。请改为在外层 SELECT 中计算分数:SELECT t.id, 1.0 - t.distance AS score FROM ( SELECT id, VEC_DISTANCE_COSINE(embedding, ?) AS distance FROM docs ORDER BY distance ASC LIMIT 10 ) AS t ORDER BY score DESC;WHERE VEC_DISTANCE(...) < threshold会触发全表扫描。 只有使用ORDER BY VEC_DISTANCE(...) LIMIT N时,才会使用向量索引。对于阈值查询,请将带索引的 top-K 查询放在子查询中,并在外层进行筛选SELECT * FROM ( SELECT content, VEC_DISTANCE_COSINE(embedding, ?) AS distance FROM chunks ORDER BY distance LIMIT 100 ) AS t WHERE t.distance < 0.5;LIMIT K是硬性上限;如果可能有许多行符合条件,请将 K 设得宽裕一些。
RAG(检索增强生成)模式
MariaDB Vector 最常见的 AI 用例。流程如下:
- 切分文档,将其拆分为多个段落(通常为 200–1000 个 token)。
- 使用你的模型(OpenAI、Sentence Transformers、Cohere 等)为每个片段生成嵌入。
- 在 MariaDB 中存储片段及其嵌入。
- 查询时,使用相同的模型为用户问题生成嵌入。
- 检索最近的片段(将
:user_embedding绑定为 float32 字节):SELECT content FROM chunks ORDER BY VEC_DISTANCE(embedding, :user_embedding) LIMIT 5; - 将检索到的片段作为上下文提供给大模型,以生成最终答案。
另请参阅: 如需结合全文(关键词)检索和向量检索,请参阅 使用倒数排名融合(RRF)进行混合搜索——当查询同时包含精确术语和语义改写时,此方法很有用。
RAG 表设计
CREATE TABLE chunks (
chunk_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
doc_id BIGINT UNSIGNED NOT NULL,
chunk_index INT UNSIGNED NOT NULL,
content TEXT NOT NULL,
embedding VECTOR(768) NOT NULL,
VECTOR INDEX (embedding) DISTANCE=cosine,
INDEX (doc_id)
) ENGINE=InnoDB;
为 doc_id 建立索引,以便连接回源文档或按文档筛选。chunk_index 用于保留文档内的顺序。
最简端到端 Python 示例
import mariadb
import numpy as np
from openai import OpenAI
client = OpenAI()
def embed(text):
vec = client.embeddings.create(input=text, model="text-embedding-3-small").data[0].embedding
return np.asarray(vec, dtype=np.float32).tobytes()
# Create database and table if they don't exist
conn = mariadb.connect(host="127.0.0.1", port=3306, user="root", password="")
cur = conn.cursor()
cur.execute("CREATE DATABASE IF NOT EXISTS ragdb")
cur.execute("USE ragdb")
cur.execute("""
CREATE TABLE IF NOT EXISTS chunks (
chunk_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
content TEXT NOT NULL,
embedding VECTOR(1536) NOT NULL,
VECTOR INDEX (embedding) DISTANCE=cosine
) ENGINE=InnoDB
""")
conn.commit()
# Store a document chunk
cur.execute(
"INSERT INTO chunks (content, embedding) VALUES (?, ?)",
("MariaDB Vector stores embeddings natively", embed("MariaDB Vector stores embeddings natively"))
)
conn.commit()
# Retrieve top-5 nearest chunks for a user question
question_vec = embed("How does MariaDB store vectors?")
cur.execute("""
SELECT content, VEC_DISTANCE_COSINE(embedding, ?) AS distance
FROM chunks
ORDER BY distance
LIMIT 5
""", (question_vec,))
context = "\n".join(row[0] for row in cur.fetchall())
# Pass `context` to your LLM as the retrieved context for the answer
mariadb 连接器(pip install mariadb)是官方 Python 驱动程序。在大端序主机上,使用 dtype="<f4" 强制采用小端序。
框架集成
MariaDB Vector 已与主流 AI 框架集成。构建应用时,请使用这些集成,而不是编写原始 SQL:
| 框架 | 语言 | 链接 |
|---|---|---|
| LangChain | Python | pip install langchain-mariadb |
| LangChain.js | Node.js | 内置 MariaDB 向量存储 |
| LangChain4j | Java | 内置 MariaDB 嵌入存储 |
| LlamaIndex | Python | 内置 MariaDB 向量存储 |
| Spring AI | Java | 内置 MariaDB 向量存储 |
| MariaDB MCP Server | Python | github.com/mariadb/mcp |
使用框架时,通常只需配置连接字符串,框架便会为你处理 VEC_FromText、VEC_DISTANCE 和 LIMIT。
选择嵌入模型
嵌入模型决定了向量质量。以下是一些实用建议:
- 从句子转换器模型开始(例如,
all-MiniLM-L6-v2,384 维),用于原型开发。免费、速度快,可在本地运行。 - 如果你已在使用 OpenAI,OpenAI
text-embedding-3-small(1536 维)是可靠的生产环境选择。(截至 2026 年 5 月,维度信息准确;请对照当前模型文档核实。) - 使维度与 VECTOR(n) 列匹配。 维度不匹配会导致插入错误。
- 切勿在同一列中混用不同模型生成的嵌入。 不同模型生成的向量之间的距离没有意义。
- 对于大多数文本嵌入模型,余弦距离是标准选择。请查阅模型文档。
性能说明
- MariaDB Vector 使用 SIMD 硬件优化(Intel 上的 AVX2、AVX512;ARM 上的 NEON;IBM Power10 上的 VSX)。无需配置——它会自动检测并使用最佳可用指令集。
- 通过外推加速向量距离计算(12.1+,MDEV-36205)——在数据和召回率相同的情况下,向量搜索速度提升 30–50%,且无需更改架构或索引。此优化会自动应用于可逐步截断以权衡召回率和速度的向量(例如 OpenAI 的 Matryoshka 风格嵌入)。
- 多连接扩展能力是一项优势。基准测试结果表明,MariaDB Vector 可随并发查询良好扩展,在多线程场景中胜过某些专用向量数据库。
- 对于大型数据集(数百万个向量),请调高 M 参数,并确保为索引提供足够的内存。
- 批量插入:先加载数据,再创建向量索引。与向已建立索引的表中插入数据相比,这种方式快得多。
- 将嵌入绑定为二进制数据(
float32.tobytes()),不要使用VEC_FromText()。速度约快 5 倍,网络负载约小 5 倍,存储的字节完全相同。
调优:mhnsw 系统变量
这些会话级/全局变量可让你在运行时调整搜索质量和内存用量,而无需重建索引:
mhnsw_ef_search(默认值:20)——ORDER BY … LIMIT N查询所考虑的候选项下限。如果小LIMIT值下的召回率较低,请调高此值;若要牺牲召回率以换取速度,则调低此值。mhnsw_max_cache_size(默认值:16777216/ 16 MB,仅限全局)——每个索引的内存缓存上限。为获得最佳性能,整个向量图应能装入此缓存;请根据索引大小设置缓存。mhnsw_default_m(默认值:6)和mhnsw_default_distance(默认值:euclidean)用于设置在VECTOR INDEX声明中省略M或DISTANCE时采用的隐式值。
来源
- Vector 概览 — 官方文档入口
- 使用 Vector 创建表 — 索引选项、NOT NULL 要求和限制
- VEC_FromText — 将 JSON 浮点数数组转换为二进制 VECTOR
- VEC_ToText — 将二进制 VECTOR 转换为 JSON 浮点数数组
- VEC_DISTANCE — 通用距离函数,需要索引
- VEC_DISTANCE_EUCLIDEAN
- VEC_DISTANCE_COSINE
- MariaDB Vector RAG 教程 — 端到端 Python + OpenAI 示例
- 使用 RRF 进行混合搜索 — 合并全文和向量排序列表
- MariaDB Vector 项目页面
- MariaDB MCP 服务
如需了解此处未涵盖的主题,请参阅 MariaDB 官方文档:mariadb.com/docs。