mcpField
M
mariadb-vector

mariadb-vector

github.com/mariadb数据与数据库17114 次安装2 周前更新
代码仓库

关于 mariadb-vector

面向构建向量搜索或 RAG 应用的开发者,介绍 MariaDB 原生向量功能与 AI 数据模式。内容涵盖 SQL、索引行为、性能注意事项和框架集成。

主要功能

  1. 01说明 VECTOR 列、索引和函数
  2. 02展示近邻搜索的 SQL 查询模式
  3. 03记录索引要求与优化器注意事项
  4. 04介绍向量存储和写入方式
  5. 05涵盖 RAG 设计与框架集成

适用场景

  1. 01设计用于存储嵌入的表
  2. 02实现带索引的近邻检索
  3. 03避免导致全表扫描的查询模式
  4. 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 用例。流程如下:

  1. 切分文档,将其拆分为多个段落(通常为 200–1000 个 token)。
  2. 使用你的模型(OpenAI、Sentence Transformers、Cohere 等)为每个片段生成嵌入。
  3. 在 MariaDB 中存储片段及其嵌入。
  4. 查询时,使用相同的模型为用户问题生成嵌入。
  5. 检索最近的片段(将 :user_embedding 绑定为 float32 字节):
    SELECT content
    FROM chunks
    ORDER BY VEC_DISTANCE(embedding, :user_embedding)
    LIMIT 5;
    
  6. 将检索到的片段作为上下文提供给大模型,以生成最终答案。

另请参阅: 如需结合全文(关键词)检索和向量检索,请参阅 使用倒数排名融合(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:

框架语言链接
LangChainPythonpip install langchain-mariadb
LangChain.jsNode.js内置 MariaDB 向量存储
LangChain4jJava内置 MariaDB 嵌入存储
LlamaIndexPython内置 MariaDB 向量存储
Spring AIJava内置 MariaDB 向量存储
MariaDB MCP ServerPythongithub.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 时采用的隐式值。

来源

如需了解此处未涵盖的主题,请参阅 MariaDB 官方文档:mariadb.com/docs。

评论

支持 Markdown