数据库家谱里有两个分支最近被频繁并排提到:一个是时序数据库(Time Series Database),一个是向量数据库(Vector Database)。它们名字里都带“数据库”,但解决的是完全不同的问题。很多文章只说“时序库管监控数据、向量库管 AI 检索”,但对于“为什么传统关系型数据库做不了”“各自适合什么数据特征”“两个库能不能配合用”往往讲得不够清楚。
这篇博文就把这两类数据库拆开看:先讲各自解决什么核心问题,再讲存储和查询机制,然后给出一套从启动到查询验证的落地流程,最后聊选型和常见坑。适合后端开发、数据工程师、架构师,以及刚接触大数据存储技术、想知道该选哪个库的人。
1. 数据库家谱里的两个分支:核心能力速览
先给一张速览表,把两类数据库最关键的差异摆出来。
| 对比维度 | 时序数据库 | 向量数据库 |
|---|---|---|
| 核心问题 | 海量时间序列数据的写入、聚合、保留 | 高维向量的相似度检索与索引管理 |
| 典型数据 | 监控指标、日志时序、IoT 传感器、金融行情 | 文本 Embedding、图像特征、音频特征 |
| 基本数据单元 | 一条带时间戳的指标记录 | 一个向量 ID + 高维向量数组 + 元数据 |
| 常见查询 | 按时间范围聚合、降采样、同比环比 | 语义相似度 TopK 检索、带过滤条件检索 |
| 写入特点 | 持续高并发追加写,几乎不更新 | 批量导入为主,在线写入频率相对可控 |
| 索引/存储核心 | LSM Tree、列式压缩、时间分区、降采样 | HNSW、IVF、PQ 等近似最近邻索引 |
| 代表产品 | InfluxDB、TDengine、TimescaleDB、Prometheus、VictoriaMetrics、IoTDB | Milvus、Qdrant、Weaviate、Chroma、pgvector |
| 不适合的事情 | 复杂事务、多表关联、任意结构数据 | 精确条件查询、事务写入、数值聚合 |
一句话概括:时序数据库管的是一根连续变化的“线”,向量数据库管的是一群分散在高维空间里的“点”。前者强调时间维度上的顺序和趋势,后者强调空间维度上的距离和相似度。
2. 时序数据库解决的是什么问题
2.1 时序数据的特征
时序数据最基本的形态是“在时间轴上持续产生、按固定或不固定间隔采集”的数据。比如服务器的 CPU 使用率、容器内存占用、温湿度传感器读数、车辆 GPS 轨迹、股票分时价格。这类数据有三个典型特征:
第一,写入量大且持续。一台服务器每 5 秒上报一次指标,一天就有超过 1.7 万条记录。一个中等规模的集群如果有几千个节点,每天写入量会达到数亿甚至数十亿条。
第二,数据很少修改。昨日 16:00 的 CPU 使用率就是那个值,业务上基本不会回滚修改。时序库的写入模式本质上是一次写入、多次读取。
第三,查询总是带时间范围。用户很少问“CPU 使用率等于 50% 的所有记录”,而是问“最近 5 分钟 CPU 平均值”“上周每天高峰值是多少”“和去年同期比涨了多少”。
一旦数据特征是这样,传统关系型数据库的劣势就很明显了。
2.2 为什么传统关系库搞不定
关系型数据库(MySQL、PostgreSQL)擅长的是事务性场景:订单、用户、库存,数据量在百万到千万级,需要强一致性和复杂关联查询。但面对时序数据,它有几个硬伤。
第一个硬伤是写入吞吐。关系库写入一行要在 B+ Tree 里做随机插入,同时维护索引,写入吞吐到一定量级会被锁、IO 和 WAL 放大卡住。时序数据一天写入亿级记录,如果每个指标都是独立一行,MySQL 很难扛住这种持续追加压力。第二个硬伤是存储放大。时序数据通常同构,如果不用列式压缩,单条记录重复的时间戳和指标名会占掉大量磁盘。第三是清理问题。监控数据通常有保存周期,超过 30 天就删。关系库对海量数据做定期删除容易产生碎片、影响查询性能。这些场景逼迫存储系统专门为“时间”做设计。
2.3 时序数据库的核心机制
时序数据库并不是简单地给数据库加了时间戳字段,它的整个存储引擎都围绕时间轴重写了。
存储层普遍采用LSM Tree变体。新数据先写内存表(MemTable),达到阈值再批量刷盘为有序文件,避免随机写。刷盘后的数据文件按时间有序排列,天然适合做时间段裁剪,查询时只要定位到对应分片,不用扫全表。
列式存储和压缩是第二个关键。同一批数据里,时间戳序列非常规律,指标值往往在某个区间内波动,用 Delta 编码、Varint 编码、Gorilla 压缩能获得很高的压缩比。传统行式存储存 3 个月的数据可能需要上百 GB,时序库可能只需要十分之一的空间。
时间分区与保留策略是第三个设计。表和底层文件按时间桶划分,比如按天、按小时分区。查询指定时间范围时直接跳过无关分区;超过保留时间的数据可以整块删除,不产生逐行删除的代价。很多时序库还带连续查询或降采样能力,把原始数据预聚合到分钟级、小时级汇总表,历史趋势查询直接走聚合数据,响应时间大幅下降。
这就是时序库解决问题的思路:不追求普适的数据处理,而是把“随时间的顺序写入、按时间的范围读取”做到极致。
3. 向量数据库解决的是什么问题
3.1 向量数据从哪里来
向量数据库处理的数据不是一张表,而是一串浮点数组成的向量。在 AI 应用里,文本、图片、音频会被模型转换成高维向量,例如 text-embedding 模型可以把句子转成 1024 维或 1536 维的数组。这些向量代表了原始内容的“语义特征”。
一个句子“今天天气很好”和一个句子“今天的阳光很舒服”,字面完全不同,但 Embedding 向量在空间上很接近。向量检索就是利用这种空间距离来找到“语义上相似”的内容。
典型场景包括:
- 语义搜索:用户提问,先从知识库中召回语义最接近的文本片段,再交给大语言模型组织回答,也就是 RAG。
- 图像/以图搜图:把商品图转成向量,找相似商品。
- 推荐系统召回:把用户行为向量和内容向量做最近邻匹配。
- 去重、异常检测:判断某个新向量是否和已有向量集合过于接近。
3.2 为什么传统数据库做不了向量检索
理论上,关系型数据库存向量也不是不行,把数组序列化成字符串存进 TEXT 字段即可。问题在于查询方式。
SQL 无法高效表达“找到和某向量最接近的 10 个向量”。如果数据有几百万条,最简单的做法是一条条计算距离并排序——这是 O(N) 的暴力扫描。数据到千万级、亿级之后,离线任务可以用 Flink 跑,在线实时检索毫秒级返回就完全不可行了。
少量项目会给关系数据库加向量扩展,例如 pgvector 允许 PostgreSQL 里建向量列并用近似索引。但它本质是借用了关系库的能力边界,向量规模很大、需要独立扩展时,专业向量数据库更适合。
3.3 向量数据库的存储与索引机制
向量数据库要解决的是“最近邻搜索”的加速问题。精确搜索做不到高并发,于是工业界普遍用近似最近邻(ANN)索引,牺牲极小的精度来换取巨大的速度提升。
最常用的索引之一是HNSW(Hierarchical Navigable Small World)。它把向量组织成多层图结构:上层是稀疏长跳连接,用于快速逼近目标区域;下层是密集短连接,用于精确定位。查询时从顶层入口出发,逐层下探,每一步都跳到与目标向量更近的节点。HNSW 的优点是高召回、查询延迟稳定,缺点是索引占内存较大。
另一类常用方案是IVF(倒排文件)。它先把向量空间聚类成多个桶,查询时只搜索候选桶中的向量,大幅减少计算量。IVF 平替内存占用更低,配合 PQ(乘积量化)可以压缩向量存储,适合超大规模场景,但追求很高召回率时不如 HNSW 直观。
实际使用中,向量数据库还会配元数据过滤能力。比如搜索“和某图相似的图片,并且品牌属于 A 类”,就需要先按标量字段过滤,再做向量搜索。不同产品对过滤和向量检索的执行顺序不一样,测试时要重点看过滤后的延迟和召回率变化。
4. 时序数据库与向量数据库的对比
| 对比维度 | 时序数据库 | 向量数据库 |
|---|---|---|
| 数据维度 | 时间 + 标签 + 数值 | 向量的高维空间坐标 + 元数据 |
| 写入压力 | 极高,持续追加写 | 相对低频,索引构建有额外成本 |
| 更新操作 | 几乎不更新 | 支持更新,但频繁更新会影响索引质量 |
| 查询特征 | 时间范围 + 聚合函数 | 相似度距离 + TopK + 过滤 |
| 数据规模瓶颈 | 每天亿级写入,保留策略控制总量 | 向量总数、索引内存、召回速度 |
| 存储优化 | 列式压缩、时间分区、降采样 | 量化压缩、分片、索引参数调优 |
| 典型使用角色 | SRE、物联网平台、金融量化 | AI 应用、推荐系统、RAG 架构 |
一个更务实的观察是:两者的竞争关系非常弱。它们不是替代品,更多是“家谱里的远亲”——各自服务完全不同的数据形态。真正需要认真对比的是“该用专门的时序库还是继续用关系库”“该用专业向量库还是用带向量扩展的关系库”。
5. 常见产品与选型建议
5.1 时序数据库的选型
时序数据库领域比较有代表性的产品包括:
| 产品 | 特点 | 适合场景 |
|---|---|---|
| InfluxDB | 生态成熟,类 SQL 查询语法,插件多 | 轻量监控、IoT、中小规模时序分析 |
| TDengine | 国产开源,写入吞吐高,SQL 风格 | 物联网、工业大数据、大规模设备数据 |
| TimescaleDB | 基于 PostgreSQL 的时序扩展 | 已有 Postgres 体系、希望兼容 SQL 的团队 |
| Prometheus | 云原生监控标配,拉取模型 | Kubernetes 监控、服务告警 |
| VictoriaMetrics | 高压缩比,兼容 Prometheus | 大规模监控指标,追求运维简单 |
选型时可以看四点:写入吞吐是否匹配、查询接口是否满足业务聚合、是否支持灵活的保留策略、团队是否有意愿维护一套独立数据库。监控场景选 Prometheus 生态很自然;物联网设备量大、需要 SQL 分析,TDengine 这类更合适;团队不想引入新数据库,TimescaleDB 作为 Postgres 扩展可以降低迁移成本。
5.2 向量数据库的选型
| 产品 | 特点 | 适合场景 |
|---|---|---|
| Milvus | 分布式架构成熟,支持大规模 | 生产级 RAG、图像检索,需要横向扩展 |
| Qdrant | Rust 实现,接口简洁,过滤能力强 | 中小规模到中等规模,注重开发效率 |
| Weaviate | 内置模块多,支持多种模型接口 | 快速原型、与生成式 AI 框架集成 |
| Chroma | 轻量级,本地起步容易 | 学习、原型验证、个人项目 |
| pgvector | PostgreSQL 插件 | 已有 Postgres,向量量不大,希望少加组件 |
向量库选型最容易踩的坑是“拿 demo 规模估算生产规模”。几万条向量几乎什么库都能跑,几千万条向量时索引参数、分片策略、内存上限就会迅速暴露问题。更稳妥的判断是:先准备一个接近真实规模的测试集,再比较召回率、P95 延迟、内存占用这三项。
6. 本地验证流程:从启动到写入再到查询
由于没有统一的“时序库命令”和“向量库命令”,这里给出一套通用验证流程,具体命令需要按你选用的产品替换。验证的目标是跑通“部署—写入—查询—观察资源”这条链路。
6.1 时序数据库通用验证流程
第一步,启动。以 InfluxDB 为例,用容器启动最简单:
# 通用示例,具体版本和端口以官方文档为准 docker run -d \ --name influxdb \ -p 8086:8086 \ influxdb如果使用 TDengine,通常需要启动 taosd 服务,并用 taos 客户端连接。启动成功后的标准是:服务端口处于监听状态,日志无异常,能打开命令行或 Web 控制台。
第二步,写入测试数据。时序写入的数据通常由三部分组成:时间戳、标签、指标值。InfluxDB 1.x 的 Line Protocol 格式如下:
weather,city=beijing temperature=28.5,humidity=60 1700000000000000000含义分别是:measurement=weather,标签 city=beijing,字段 temperature=28.5 和 humidity=60,时间戳是纳秒。
TDengine 则直接用 SQL 建表写入:
CREATE DATABASE sensor; USE sensor; CREATE TABLE temp (ts TIMESTAMP, value FLOAT) TAGS (device_id INT); INSERT INTO temp VALUES ('2025-01-01 00:00:00', 25.3, 1);判断写入成功的标准是返回写入成功数量,且连续写入多行之后能用SELECT COUNT(*)看到行数递增。
第三步,查询验证。先验证基础时间范围查询:
SELECT AVG(temperature) FROM weather WHERE time >= now() - 1h再验证降采样查询:
SELECT AVG(temperature) FROM weather WHERE time >= now() - 1d GROUP BY time(1h)如果聚合查询返回了预期的桶数量,并且性能明显好于查原始明细,说明降采样或内存聚合逻辑正常。
6.2 向量数据库通用验证流程
以 Qdrant 为例,容器启动如下:
docker run -d \ --name qdrant \ -p 6333:6333 \ qdrant/qdrant启动后可以用浏览器访问 6333 端口的 Web UI,或直接用 curl 请求/collections。
操作上,先创建一个集合(Collection),集合需要设置向量维度。比如使用 OpenAI 的 text-embedding-3-small,维度通常是 1536,本地测试也可以用更小的维度,例如 8 维,这样方便快速验证:
curl -X PUT http://127.0.0.1:6333/collections/test_collection \ -H "Content-Type: application/json" \ -d '{ "vectors": { "size": 8, "distance": "Cosine" } }'写入向量时,每个点由 ID、向量、元数据三部分组成:
curl -X PUT http://127.0.0.1:6333/collections/test_collection/points \ -H "Content-Type: application/json" \ -d '{ "points": [ { "id": 1, "vector": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8], "payload": {"category": "demo"} } ] }'查询时调用/points/search:
curl -X POST http://127.0.0.1:6333/collections/test_collection/points/search \ -H "Content-Type: application/json" \ -d '{ "vector": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.9], "limit": 3 }'如果返回结果里带score,且和查询向量越接近的数据排序越靠前,说明相似度检索链路已经跑通。
7. 资源占用与性能观察
时序数据库和向量数据库的性能观察点不太一样,下面分别给出观察思路。具体数值会因数据规模、参数配置、硬件环境差异很大,这里不编造固定数字,更建议按“是否随数据增长线性变差”来判断。
7.1 时序数据库的资源观察
写入阶段重点看三个指标:写入吞吐、磁盘 IO、WAL 写入延迟。如果批量写入小,每条记录都单独提交,写入吞吐会被刷盘频率限制。建议尽量用批量写入接口,一次写几百到几千条。读取阶段重点看聚合查询耗时,如果时间范围扩大后查询时间显著变长,需要检查时间分区的裁剪是否生效,以及是否建了正确的降采样。
存储空间也要关注。时序库的存储管理依赖保留策略,不设保留策略会导致磁盘持续增长。观察方式是看数据文件的大小是否超过预期,以及压缩比是否正常。如果磁盘增长异常,可以考虑把采样频率从每 5 秒一条改成每 30 秒一条,或把超过 90 天的数据降采样后保存。
7.2 向量数据库的资源观察
向量数据库最直接的资源压力是内存。HNSW 索引需要把图的节点和连接信息加载到内存,向量维度越高、数量越大,内存消耗越大。观察方法是查询系统进程 RSS 和索引构建时的峰值内存。如果内存溢出,优先调整 HNSW 的M和efConstruction参数,这两个值越大,召回率越高,但内存和构建时间也越高。
查询性能方面,看 P95 延迟最有用。只需测试不同数据量下的 P95 延迟,如果从 10 万条涨到 100 万条时延迟翻了几倍,说明索引参数或分片策略需要调整。向量库还有一个容易被忽略的问题:频繁的删除和更新会让索引产生“坏点”,导致召回率逐渐下降,需要在批量任务里定期重建索引或离线重排。
8. 常见问题排查方法
| 问题现象 | 可能原因 | 排查方式 | 解决思路 |
|---|---|---|---|
| 时序库写入速度慢 | 单条写入、WAL 刷盘频繁、批量过小 | 查看写入日志和磁盘 IO 指标 | 改用批量写入,扩大批大小 |
| 时序查询时间跨度长后明显变慢 | 时间分区未生效,查询扫了全量数据 | 查看执行计划或查询耗时分布 | 确认表按时间分区,使用降采样聚合表 |
| 时序磁盘占用增长过快 | 未设置保留策略,或样本采集过密 | 统计总行数和存储文件大小 | 设置保留策略,离线降采样后清理明细 |
| 向量查询召回率低 | 索引参数不合适,距离度量选错 | 用少量已知相似样本测试 | 调大 HNSW 的 M 和 ef 参数,或改距离函数 |
| 向量库内存占用过高 | 索引常驻内存,向量维度过高 | 对比 ID 数量和 RSS | 降低索引参数,增加分片,或对向量做量化 |
| 带过滤条件的向量查询变慢 | 过滤器执行顺序导致扫描范围过大 | 测试带过滤和不过滤的 P95 延迟 | 给过滤字段建索引,或使用支持倒排过滤的向量库 |
| 两类库同时部署出现端口冲突 | 默认端口被占用 | 检查端口监听状态 | 修改容器映射端口,如把 6333 改成 16333 |
| API 调用偶尔超时 | 批量任务同时触发,索引构建占用 CPU | 观察请求日志和系统负载 | 控制并发,增加重试退避,低峰期构建索引 |
排查问题时有一个通用原则:先看日志,再看资源,最后才改参数。很多“查询慢”的问题并不是数据库不行,而是数据量还没有真实模型化、索引没有建对、查询语句没有走预期的执行路径。
9. 最佳实践:数据架构里怎么安排两类数据库
多数据库并存正在成为常态,不再是什么“架构复杂”的把柄。一组数据可以从三个维度决定放在哪里:数据结构、访问频率、查询模式。时序数据放时序库,向量数据放向量库,事务性数据放关系库,这本身就是合理分层。
实际落地时,下面这些经验可以少走弯路。
第一,先用最小规模验证算法,再用接近生产规模验证性能。很多团队在几千条向量上测出“秒回”,扩到千万条才发现索引构建内存不够。比较好的做法是把 10% 的真实数据灌进去,观察资源消耗和延迟,再做容量规划。
第二,不要让应用直连多个数据库。时序库、向量库、关系库如果被业务代码直接访问,后续切换和升级会非常痛苦。可以在上层加一个数据服务层,屏蔽底层存储差异。比如 AI 应用只调“语义检索”接口,内部再决定走向量库还是走带向量扩展的 Postgres。
第三,批量任务一定要设计重试和日志。无论向时序库批量写入监控数据,还是向向量库批量写入 Embedding,总会有部分请求失败。建议每个批任务记录成功条数、失败条数、耗时分布,失败数据单独落盘,定时重试。避免大批量任务中途失败后从头再来。
第四,所有上游数据接入都要做责任边界确认。如果向量库里的文本、图片、人脸特征来自真实用户或版权材料,必须确认数据来源合法、用途合规。尤其是人脸特征和声音特征,属于敏感个人信息,使用前要有明确授权,存储时要做脱敏和访问控制。时序数据如果涉及用户行为轨迹,同样不能无限制采集和长期留存。
第五,监控体系的访问边界要控制好。时序库暴露的 HTTP 接口如果绑到公网,非常容易被扫描和滥用。部署时建议绑定内网地址,加上身份认证,不要把管理端口暴露到外部。
10. 总结与下一步
这篇文章把时序数据库和向量数据库拆开做了梳理。时序数据库解决“时间序列数据持续写入、按时间聚合查询”的问题,核心优势在写入吞吐、压缩率和时间分区;向量数据库解决“高维语义表示下相似度检索”的问题,核心优势在 ANN 索引、海量向量召回和高并发查询延迟。
如果你刚开始接触这两类数据库,第一步值得验证的事情是:拿一批你自己的数据,分别跑通写入和查询。时序库先确认批量写入性能和聚合查询是否符合预期;向量库先确认相同召回率下延迟和内存是否可控。最先要避开的坑是拿几十万条测试数据去预估上亿级数据量的生产表现。
下一步可以做的事有很多:时序库可以继续研究降采样策略和高基数标签优化;向量库可以对比 HNSW 和 IVF 在不同规模下的表现,也可以测试带过滤条件的混合检索。更进一步,可以把时序库和向量库放到同一条数据处理链路里,比如 IoT 数据用时序库存储原始指标,再抽取设备特征向量到向量库做故障模式匹配——这正好是“数据库家谱”里两个分支协同工作的典型案例。
选择存储方案时,最重要的不是追新,而是先看清数据本身的“形状”:每条数据是不是都带时间戳且不断追加?每条数据是不是一个高维向量且需要按距离检索?回答清楚这两个问题,该用时序数据库还是向量数据库,其实没有悬念。