avatar

一条在知识海洋的咸鱼

这个家伙很懒,啥也没有留下😋

  • Linux
  • OCJP
  • Java核心技术卷
  • J2EE相关标准
  • 深入理解Java虚拟机
  • NIO与SOcket编程技术指南
  • Java多线程编程核心技术
  • Redis开发与运维
  • Spring Cloud Alibaba 微服务原理与实践
  • DevOps
  • Docker
  • MySQL必知必会
  • AI自学路线
  • Spring Boot 编程思想(核心篇)
  • 首页
主页 16 数据库准备
文章

16 数据库准备

发表于 昨天 更新于 最近
作者 Administrator
33~42 分钟 阅读

数据库准备

RAG 数据库准备的核心是把原始文档、文档片段、向量和任务状态分开存,让后面的上传、解析、切片、Embedding 和检索都有稳定的数据落点。

[TOC]

本节要准备什么

RAG 不是只有一个向量库。

至少要准备几类数据:

原始文档信息  
文件存储位置  
解析后的文本  
切片后的 chunkchunk embedding  
处理状态  
错误信息  

本节的目标是准备数据库结构。

先不急着做检索。

先让后面的流程有地方存数据。

RAG 数据落点可以先这样理解:

graph TD;  
 A["上传文件"] --> B["rag_document<br/>原始文档元数据"];  
 A --> C["文件系统 / 对象存储<br/>原始文件"];  
 B --> D["rag_document_text<br/>raw_text / cleaned_text"]; D --> E["rag_chunk<br/>chunk 文本 / metadata"]; E --> F["embedding 字段<br/>vector 类型"];  
 B --> G["rag_task<br/>解析 / 清洗 / 切片 / 向量化任务"];  
 G --> D; G --> E; E --> H["向量检索<br/>topK chunks"];  

数据库分工

学习阶段可以这样理解:

PostgreSQL:RAG 主库,存文档、chunk、向量  
pgvector:PostgreSQL 的向量扩展  
MySQL:业务系统已有数据时可继续使用  
Redis:缓存、任务进度、会话状态  

第一版 RAG Demo 建议:

PostgreSQL + pgvector 作为主线  
Redis 可选  
MySQL 暂时不强依赖  

原因是:

少一个组件,少一层复杂度  
pgvector 能同时存结构化字段和向量  
SQL 对 Java 后端更友好  

启动 PostgreSQL + pgvector

可以使用 Docker Compose。

创建 docker-compose.yml:

services:  
 postgres: image: pgvector/pgvector:pg16 container_name: ai-rag-postgres environment: POSTGRES_DB: ai_rag POSTGRES_USER: ai POSTGRES_PASSWORD: ai_password ports: - "5432:5432" volumes: - ai_rag_pg_data:/var/lib/postgresql/data  
volumes:  
 ai_rag_pg_data:  

启动:

docker compose up -d  

连接:

psql postgresql://ai:ai_password@127.0.0.1:5432/ai_rag```  
  
启用扩展:  
  
```sql  
CREATE EXTENSION IF NOT EXISTS vector;  

检查:

SELECT extname, extversion  
FROM pg_extension  
WHERE extname = 'vector';  

文档表

文档表存一份原始文件的元数据。

CREATE TABLE rag_document (  
 id uuid PRIMARY KEY, original_name varchar(512) NOT NULL, storage_path varchar(1024) NOT NULL, content_type varchar(128), file_size bigint NOT NULL, sha256 varchar(128), status varchar(32) NOT NULL, error_message text, created_at timestamp NOT NULL DEFAULT now(), updated_at timestamp NOT NULL DEFAULT now());  

字段含义:

id:文档 IDoriginal_name:用户上传时的文件名  
storage_path:服务端保存路径  
content_type:文件类型  
file_size:文件大小  
sha256:文件 hash,用于去重  
status:处理状态  
error_message:失败原因  
created_at / updated_at:时间  

状态可以先定义:

UPLOADED:已上传  
PARSED:已解析  
CLEANED:已清洗  
CHUNKED:已切片  
EMBEDDED:已向量化  
FAILED:处理失败  

解析文本表

解析后的全文可以单独存。

CREATE TABLE rag_document_text (  
 document_id uuid PRIMARY KEY REFERENCES rag_document(id) ON DELETE CASCADE, raw_text text NOT NULL, cleaned_text text, metadata jsonb NOT NULL DEFAULT '{}'::jsonb, created_at timestamp NOT NULL DEFAULT now(), updated_at timestamp NOT NULL DEFAULT now());  

为什么不全塞进 rag_document?

因为原始文档信息和大段文本生命周期不一样。

分开后更清楚:

rag_document:文件级元数据  
rag_document_text:解析和清洗后的文本  

Chunk 表

Chunk 表存切片结果。

CREATE TABLE rag_chunk (  
 id uuid PRIMARY KEY, document_id uuid NOT NULL REFERENCES rag_document(id) ON DELETE CASCADE, chunk_index int NOT NULL, content text NOT NULL, title_path text, page_start int, page_end int, char_start int, char_end int, token_count int, metadata jsonb NOT NULL DEFAULT '{}'::jsonb, created_at timestamp NOT NULL DEFAULT now(), updated_at timestamp NOT NULL DEFAULT now(), UNIQUE (document_id, chunk_index));  

字段含义:

chunk_index:当前文档里的第几个片段  
content:片段正文  
title_path:标题路径,比如 产品手册 > 上传限制  
page_start / page_end:页码范围  
char_start / char_end:字符位置  
token_count:估算 token 数  
metadata:扩展信息  

先把 chunk 文本存好。

Embedding 可以后面再补。

向量字段

如果已经确定 embedding 维度,可以在 chunk 表加向量字段。

示例:

ALTER TABLE rag_chunk  
ADD COLUMN embedding vector(1536);  

注意:

1536 只是示例维度  
真实维度必须和你使用的 Embedding 模型一致  

如果模型维度是 1024,就要用:

ALTER TABLE rag_chunk  
ADD COLUMN embedding vector(1024);  

维度不一致,插入会失败。

学习阶段可以先不加 embedding,等后面确认模型后再加。

如果想先准备好,就在文档里标注清楚:

TODO:根据 Embedding 模型确认 vector 维度  

向量索引

pgvector 常见相似度:

L2 distance  
Inner product  
Cosine distance  

RAG 文本检索里常用 cosine。

HNSW 索引示例:

CREATE INDEX rag_chunk_embedding_hnsw_idx  
ON rag_chunk  
USING hnsw (embedding vector_cosine_ops);  

注意:

先有 embedding 字段  
再建索引  
大批量导入时,通常先导入数据,再建索引  

如果数据量很小,不建索引也能跑。

但学习阶段可以提前知道索引写法。

Metadata 过滤索引

RAG 常常需要按文档、用户、知识库过滤。

可以先给常用字段建索引:

CREATE INDEX rag_chunk_document_id_idx  
ON rag_chunk (document_id);  

如果 metadata 里存很多查询条件,可以用 GIN:

CREATE INDEX rag_chunk_metadata_gin_idx  
ON rag_chunk  
USING gin (metadata);  

但第一版不要把所有东西都塞进 metadata。

能结构化成字段的,就用字段。

metadata 适合放扩展信息:

section  
language  
parser  
source_page_label  

任务表

文档上传后,解析、清洗、切片、Embedding 可能是异步任务。

可以准备任务表:

CREATE TABLE rag_ingest_task (  
 id uuid PRIMARY KEY, document_id uuid NOT NULL REFERENCES rag_document(id) ON DELETE CASCADE, task_type varchar(64) NOT NULL, status varchar(32) NOT NULL, error_message text, started_at timestamp, finished_at timestamp, created_at timestamp NOT NULL DEFAULT now(), updated_at timestamp NOT NULL DEFAULT now());  

任务类型:

PARSE  
CLEAN  
CHUNK  
EMBED  

任务状态:

PENDING  
RUNNING  
SUCCESS  
FAILED  

第一版也可以同步处理。

但提前知道任务表怎么设计,后面更容易扩展。

Redis 用在哪里

Redis 在第一版不是必须。

适合放:

短期任务进度  
接口限流计数  
会话缓存  
热点问答缓存  
分布式锁  

Docker Compose 可选加入:

 redis: image: redis:7 container_name: ai-rag-redis ports: - "6379:6379"```  
  
但如果你现在只想跑通 RAG 主链路,可以先不用 Redis。  
  
## MySQL 用在哪里  
  
如果现有业务系统已经用 MySQL,可以继续让 MySQL 存:  
  
```text  
用户  
权限  
订单  
业务配置  
菜单  
审计记录  

RAG 的文档、chunk、embedding 可以放 PostgreSQL。

也可以全放 PostgreSQL。

第一版不要强行同时用两个关系型数据库。

系统越简单,越容易把 RAG 主链路跑通。

初始化脚本

建议把 SQL 放到:

db/init/001_rag_schema.sql  

内容顺序:

CREATE EXTENSION IF NOT EXISTS vector;  
  
CREATE TABLE rag_document (...);  
  
CREATE TABLE rag_document_text (...);  
  
CREATE TABLE rag_chunk (...);  
  
CREATE TABLE rag_ingest_task (...);  
  
CREATE INDEX ...;  

后面可以用 Flyway 或 Liquibase 管理。

学习阶段先用 SQL 文件手动执行也可以。

常见问题

为什么不用纯向量数据库

可以用。

但学习阶段 PostgreSQL + pgvector 更容易理解:

结构化字段  
SQL 查询  
metadata 过滤  
向量搜索  
都在一个数据库里  

后面数据量大了,再评估 Milvus、Qdrant 等专业向量库。

embedding 维度不知道怎么办

先不要建 vector 字段。

等后面确定 Embedding 模型后再加。

维度必须匹配模型输出。

文档原文件存数据库还是文件系统

第一版建议原文件存文件系统。

数据库存路径和元数据。

原因:

实现简单  
数据库压力小  
后面换对象存储也方便  

正式项目可以用对象存储,比如 MinIO、OSS、S3。

是否要存 raw_text 和 cleaned_text

建议存。

这样方便排查:

解析是否丢内容  
清洗是否误删  
切片是否合理  

RAG 调试离不开中间结果。

练习清单

完成几件事情:

启动 PostgreSQL + pgvector创建 ai_rag 数据库  
启用 vector 扩展  
创建 rag_document 表  
创建 rag_document_text 表  
创建 rag_chunk 表  
创建 rag_ingest_task 表  
了解 embedding vector 维度要求  
了解 HNSW cosine 索引写法  
能解释 Redis 在 RAG 里的可选作用  

建议目录:

ai-agent-study  
├── db  
│   └── init  
│       └── 001_rag_schema.sql  
├── docker-compose.yml  
└── docs  
 └── database-prepare.md  

小结

本节的结论:

RAG 数据库要先把文档、文本、chunk、向量和任务状态分清楚,后面的流程才不会乱。

最小数据链路:

rag_document  
 -> rag_document_text -> rag_chunk -> embedding vector  

第一版优先跑通 PostgreSQL + pgvector。

Redis 和 MySQL 可以按业务需要再接。

参考资料

  • pgvector GitHub
  • PostgreSQL Documentation
  • Spring AI Vector Databases
AI自学路线
AI
许可协议: 
分享

相关文章

6月 12, 2026

16_01PostgreSQL 介绍

PostgreSQL 介绍 PostgreSQL 在 AI 项目里的价值,不只是“又一个关系型数据库”,而是它可以把文档、chunk、metadata、embedding 向量、检索条件和任务状态&#

6月 11, 2026

16 数据库准备

数据库准备 RAG 数据库准备的核心是把原始文档、文档片段、向量和任务状态分开存,让后面的上传、解析、切片、Embedding 和੹

6月 10, 2026

15 RAG 原理

RAG 原理RAG 的核心是先从知识库检索相关内容,再把检索结果作为上下文交给大模型回答,从而减少模型胡编,并让模型能回答私有文档里的问题。RAG 原理RAG 是什么为什么需要 RAGRAG 和普通 Chat 的区别RAG 基本流程核心组件Document 和 ChunkEmbedding 是什么V

下一篇

16_01PostgreSQL 介绍

上一篇

15 RAG 原理

最近更新

  • 16_01PostgreSQL 介绍
  • 16 数据库准备
  • 15 RAG 原理
  • 14 阶段交付
  • 13 Java + Python 联调

热门标签

java基础 微服务 maven Spring Tomcat DDD Linux Linux基础 SQL基础 数据结构算法

目录

©2026 一条在知识海洋的咸鱼. 保留部分权利。

使用 Halo 主题 Chirpy