一套 C++ 内核同时跑在 PG、DuckDB 和 SQLite 上:VexDB-Lite 跨引擎向量检索共享设计解析

发布时间:2026/10/7 15:33:03
一套 C++ 内核同时跑在 PG、DuckDB 和 SQLite 上:VexDB-Lite 跨引擎向量检索共享设计解析 一套 C 内核同时跑在 PG、DuckDB 和 SQLite 上VexDB-Lite 跨引擎向量检索共享设计解析【免费下载链接】VexDB-LiteA cross-platform vector database, which can be integrated into existing databases as a plugin.项目地址: https://gitcode.com/gh_mirrors/ve/VexDB-LiteVexDB-Lite是一个可嵌入现有数据库的跨平台向量数据库插件同一套 C 图索引算法、SIMD 距离内核与 PQ / RaBitQ 量化代码同时服务于PostgreSQL、DuckDB 和 SQLite三大引擎——这正是它最值得新手学习的共享内核设计。本文将用最少代码拆解这套跨引擎向量检索架构是怎么做到的。上图来自项目 iOS 演示工程的 Agent 架构图向量数据库Vector Database正是现代 AI Agent 长期记忆与工具调用的底层支撑而 VexDB-Lite 让这套能力可以无缝嵌入你已有的数据库。为什么向量能力很难跨数据库复用给一个数据库加上向量检索能力通常要解决四件事能力说明复用难度向量数据类型PG 是floatvector(N)DuckDB 是FLOAT[N]中距离函数L2 / 余弦 / 内积性能核心依赖 SIMD 指令高图索引HNSW 类内存管理、锁模型各不相同极高量化压缩PQ / RaBitQ训练码本 压缩存储高多数向量扩展只服务单一引擎把算法和宿主数据库的内脏内存上下文、锁、页面格式搅在一起。VexDB-Lite 的做法是反过来的把 80% 的算法抽到一个与引擎无关的公共内核每个引擎只写一层薄薄的适配代码。一眼看懂三层架构与目录布局common/ ← 引擎无关的共享 C 内核算法 距离 量化 vexdb_pg/ ← PostgreSQL 扩展vexdb_graph 索引访问方法 vexdb_duckdb/ ← DuckDB 扩展GRAPH_INDEX vexdb_sqlite/ ← SQLite 虚拟表实现三个引擎目录里几乎只有胶水SQL 函数绑定、索引接口、优化器改写。而真正的图构建、邻居搜索、距离计算、量化编解码全部在 common/ 中完成被三处 CMake 构建直接引用。项目根 README.md 开头一句话就点明了这个设计The backends share the same graph index algorithm, SIMD distance dispatch, and PQ/RaBitQ quantization kernels.上图来自项目示例工程一段文本prompt经 LLM/Embedding 变成向量后检索就落在向量索引上——无论它背后是 PG、DuckDB 还是 SQLite走的都是同一套内核。技巧一模板算法 可插拔存储一份图索引代码走天下图索引算法本体在 common/include/graph_index/graph_index_algorithm.h它是一个双模板参数类template typename Store, typename Dister, templatetypename class Alloc PgAlloc class GraphIndexAlgorithm { ... };三个维度全部做成插槽Store存储PG 用它的 buffer/页面格式DuckDB 用内存存储SQLite 用虚拟表存储——算法层完全不感知。Dister距离器决定用原始向量还是量化码算距离甚至能否用估计距离剪枝has_estimation_func。Alloc分配器PG 的palloc、DuckDB 的malloc通过编译期宏切换。编译期就能确定内存直存还是量化存储、要不要 refine见 graph_index_algorithm.h 中的need_refine/mem_store特判没有一次运行期if为宿主引擎付出的性能代价。技巧二SIMD 距离内核 编译期分发一套算 PG/DuckDB/SQLite 三家距离计算是向量库的性能命脉。common/distance/core/ 目录按 CPU 架构提供全套内核arch_dispatch_macros.h按 SSE / AVX / AVX-512 / NEON 能力做编译期架构分发distance_dispatcher.h在度量 × 精度 × 是否量化的笛卡尔积上把正确的内核函数指针填进统一入口各后端源码avx.cpp、neon_dispatcher.cpp 等三引擎编译同一份。有意思的是分发器里的宿主适配只有一小段条件编译见 distance_dispatcher.hPG_VEXDB_TARGET_PG→ 接入 PG 的量化元信息PG_VEXDB_TARGET_DUCK→ 接入 DuckDB 依赖头PG_VEXDB_TARGET_SQLITE→ 无宿主 store直接用 quantizer_type.h。也就是说量化分支只在 PG 上启用时其他引擎连模板展开都不会发生——差异被压缩在头文件级别的几个 include 里而不是散落全代码的#ifdef。技巧三Shim 垫片——让 PG 风格代码在 DuckDB 里无感编译共享内核历史上沿用了 PostgreSQL 的内核风格palloc、LWLock、MemoryContext、MAXALIGN……这些在 DuckDB 里根本不存在。VexDB-Lite 没有为此维护两套代码而是写了一层垫片duck_pg_shim.hpp 用标准 C 的std::atomic等价实现了 PG 风格的锁原语用vtl/allocator提供palloc等内存符号——注释里写得很直白The main code compiles without #ifdef.SQLite 侧同理在 distance_dispatcher.h 里把Assert/Assume降级为空操作。最像 PG 的那个方言成为内核的通用语言其他引擎各自垫一层翻译这是三端共源码能低成本成立的关键。技巧四PQ / RaBitQ 量化内核同样共享量化不是每个引擎单独实现的。common/quantizer/ 目录里product_quantizer.hPQ 乘积量化器注释标明 Backend-neutral; uses our shared PQContext (allocator random parallel)——分配器、随机数、并行训练全部注入common/rabitq/RaBitQ 旋转、估计与码距计算PG 用它做量化图遍历DuckDB 同样复用。README.md 的能力矩阵里可以看到收益DuckDB 官方 VSS 扩展没有 PQ、没有 SIMD 分发而 VexDB-Lite 靠这套共享内核补齐了全部能力且 PG 与 DuckDB 的量化行为完全一致。如何验证三个引擎结果一致共享内核最怕的是看着一样、跑出来不一样。项目在 tests/spec/ 下维护了一整套跨引擎规格测试同一份 YAML 用例分别在 PG、DuckDB、SQLite 上执行并比对结果如 tests/spec/duckdb/、tests/spec/pg/、tests/spec/sqlite/配合 tests/spec/README.md 描述的规范化比对流程距离值、索引召回、边界行为三端一致才算通过。这是一套算法多处跑能持续演进的保障。给工程师的启发如何设计跨引擎共享内核找到真正的公共集合图算法、距离内核、量化编解码——它们天然不依赖宿主。把差异参数化而不是复制代码存储、距离器、分配器做成模板参数编译期消除分支。用一个宿主方言统一内核选最复杂宿主这里是 PG的风格为通用语言其他宿主写 shim 垫片。能力差异声明在分发层哪个引擎支持量化、哪个走纯图集中写在 dispatcher 的条件编译里。用同一份测试规格回归所有引擎规格一致性比单引擎性能更重要。总结VexDB-Lite 的跨引擎共享内核本质上是公共 C 算法 编译期可插拔宿主 薄适配层 统一规格测试四件套。对新手而言这套结构是一个难得的范本它展示了如何把 SIMD 距离、图索引、PQ/RaBitQ 量化这些高难度组件组织成能在 PostgreSQL、DuckDB、SQLite 上原样复用的工程资产。想深入了解推荐从 README.md 的能力矩阵开始再对照 common/include/graph_index/graph_index_algorithm.h 和 common/distance/core/distance_dispatcher.h 两份头文件30 分钟就能摸清整个共享内核的骨架。【免费下载链接】VexDB-LiteA cross-platform vector database, which can be integrated into existing databases as a plugin.项目地址: https://gitcode.com/gh_mirrors/ve/VexDB-Lite创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考