跳转到内容

Drizzle ORM 数据库建模与 Repository 模式

学习目标

理解 LobeHub 如何用 Drizzle ORM 进行数据库建模,包括 schema 定义、relations 配置、repository 层封装和 Paradedb 全文搜索集成。

前置知识

本章无通用知识前置,直接聚焦 LobeHub 的工程实践。

项目实践

Schema 定义

LobeHub 在 packages/database/src/schemas/ 下定义了 30+ 数据表:

分类说明
Agent 核心agentagentSkillagentCronJobagentOperationsAgent 定义、技能、定时任务、操作记录
对话messagesessiontopic消息、会话、话题
多 AgentchatGroupAgent 群组
记忆userMemories/*用户记忆(多层)
任务taskasyncTaskAgent 任务
文档agentDocumentsdocumentHistoryAgent 文档树和历史
文件file文件管理
认证betterAuthnextauthoidc认证和 OAuth
模型aiInfrallmGenerationTracing模型基础设施和追踪
评估agentEvalsragEvalsAgent 和 RAG 评估
其他userapiKeynotificationrbac用户、API 密钥、通知、权限

Relations 配置

LobeHub 使用 Drizzle 的 relations 定义外键关系:

// 伪代码:Drizzle relations
export const agentRelations = relations(agent, ({ many, one }) => ({
skills: many(agentSkill),
cronJobs: many(agentCronJob),
owner: one(user, { fields: [agent.ownerId], references: [user.id] }),
}));

Repository 模式

数据库操作通过 repository 层封装,不直接在业务代码中使用 Drizzle query:

// 伪代码:Repository 模式
class AgentRepository {
async findById(id: string): Promise<Agent | null> { ... }
async create(data: CreateAgentInput): Promise<Agent> { ... }
async update(id: string, data: UpdateAgentInput): Promise<Agent> { ... }
async findByOwnerId(userId: string): Promise<Agent[]> { ... }
}

优势

  • 业务逻辑不感知数据库查询细节
  • 便于单元测试(可以 mock repository)
  • 数据库迁移只影响 repository 层

Paradedb 全文搜索

用户记忆模块使用 Paradedb 全文搜索替代普通的 LIKE 查询:

// 伪代码:Paradedb 搜索
// 使用 paradedb.match(...) 而非硬编码 normalizer
// 以获得更好的搜索相关性
paradedb.match(memories.content, searchQuery)

陷阱:Paradedb 是 PostgreSQL 的扩展,需要数据库中安装 paradedb 插件。本地开发环境需要配置。

Migration 管理

LobeHub 使用 drizzle-kit 管理迁移:

Terminal window
npm run db:generate # drizzle-kit generate + DBML 生成
npm run db:migrate # 运行迁移脚本
npm run db:studio # drizzle-kit studio(可视化数据库)

问题与规避

问题场景规避策略
Paradedb 未安装本地开发环境Docker Compose 包含 Paradedb 容器
复杂查询性能差Drizzle 自动生成的 SQL 不如手写优化复杂查询使用 .executeRaw() 手写 SQL
Migration 冲突多人同时修改 schema使用 canary 分支,避免并行 migration
Relations N+1循环中查询关联数据使用 .with() 预加载关联

设计取舍

为什么用 Drizzle 而非 Prisma?

Drizzle 是 TypeScript-first 的 ORM,查询直接映射到 SQL,没有 Prisma 的中间层。

优势

  • 更轻量的运行时
  • SQL 透明度高(可以直接看到生成的 SQL)
  • 对 PostgreSQL 特性支持更好(如 Paradedb)

代价

  • 学习曲线(需要了解 SQL)
  • 无内置 Prisma Studio(但 drizzle-kit studio 提供类似功能)

参考来源

  • LobeHub database schemas — packages/database/src/schemas/
  • LobeHub database repositories — packages/database/src/repositories/
  • Drizzle ORM 文档