返回

Vercel 与 TiDB Cloud Starter:AI 应用全栈数据库实践

RSS TiDB Blog AI 逐段翻译 发布 2026-09-25 04:52 收录于 10-05

有效阅读仅保存在当前浏览器,用于「为你」推荐;暂停或清除记录。

DataHot 速览

文章介绍在 Vercel 上运行 AI 应用时,如何选择能适配 serverless 和 edge runtime 的数据库,并重点推荐 TiDB Cloud Starter。它指出边缘运行时会破坏传统 TCP 连接池,而 TiDB Cloud Starter 通过 HTTPS 连接;从 v0.dev 默认数据库迁移到 TiDB 只需改连接字符串。TiDB 提供原生 VECTOR 类型,可把 embeddings 与业务行数据放在一起,避免额外同步向量库;Vercel Marketplace 集成会自动写入连接环境变量。TiDB 是开源分布式 SQL 数据库,兼容 MySQL,TiDB Cloud Starter 为全托管、自动扩缩容版本,约一秒完成配置。

原收录理由(待核验):对数据从业者,本文具体讨论 serverless/edge 场景下数据库连接、向量存储与部署集成,涉及 AI 应用数据架构的选型和落地。

本文目录 14 节
  1. 关键要点
  2. 为什么 Vercel 应用需要一个为边缘构建的无服务器数据库
  3. 连接池是无服务器所暴露的问题
  4. 本指南涵盖的运行时
  5. 从 v0.dev 或 Lovable 原型到已部署的 Vercel 应用
  6. 启动你的 TiDB Cloud Starter 集群(你的 Vercel 数据库)
  7. 选择你的入口:Cloud、Starter 或 Zero
  8. 获取你的连接详细信息
  9. 为 AI 应用数据建模:会话、聊天日志、偏好设置和检索状态
  10. 使用 TiDB 向量搜索存储嵌入并驱动检索
  11. 从边缘连接:Vercel Edge Functions 和 Cloudflare Workers
  12. 使用 TiDB Cloud 集成在 Vercel 上部署
  13. TiDB Cloud Starter 与 Vercel Postgres、Neon 和 Supabase 对比
  14. 启动你的免费 TiDB Cloud Starter 集群

译文

AI 逐段翻译

关键要点

  • 边缘运行时不适合 TCP 连接池。TiDB Cloud Starter 转而通过 HTTPS 连接。
  • 把 v0.dev 起始模板的数据库换成 TiDB,只需更改连接字符串。
  • 原生 VECTOR 类型让嵌入向量与数据行放在一起,无需同步任何存储。
  • Vercel Marketplace 集成会为你写入连接变量。

你有一个运行在 Vercel 上的 AI 应用,或者一个由 v0.dev 在几分钟内生成的原型,现在它需要一个真正的数据库。这个选择比看起来更难,因为无服务器函数和边缘运行时打破了传统数据库赖以构建的假设:长寿命 TCP 连接、有界连接池,以及在请求之间保持温暖的进程。

本指南涵盖完整路径。选择一个能在无服务器和边缘运行时下存活的 Vercel 数据库,为 AI 应用实际存储的数据建模,把嵌入向量放在这些数据旁边而不是单独的向量存储中,从 Vercel Edge Functions 和 Cloudflare Workers 连接,并通过 Vercel Marketplace 集成进行部署,它会为你配置好环境变量。

TiDB 是一个开源分布式 SQL 数据库,在一个引擎中同时支持事务处理和分析处理。TiDB Cloud Starter 是其全托管、自动扩缩容的部署选项,兼容 MySQL,约一秒内即可完成配置。Vercel 是 Next.js 的创造者,也是大多数 AI 应用部署的平台。两者配合得很好,本文的其余部分将展示具体做法。

为什么 Vercel 应用需要一个为边缘构建的无服务器数据库

Vercel 以无服务器函数和边缘函数的形式运行你的后端,而不是长期运行的服务器,这改变了数据库必须支持的内容。无服务器函数按需执行,自动扩缩容,并在请求完成时终止。传统 API 则在请求-响应接口背后保持进程存活,维持其连接池开放,并在多个请求之间复用连接。

选择数据库时,有三点差异很重要:

  • 生命周期。无服务器函数响应事件而运行特定的一段代码,然后退出。传统 API 则常驻并管理自己的基础设施。
  • 可移植性。无服务器函数绑定到某个平台运行时。传统 API 则可以在任何能够托管进程的地方运行。
  • 部署速度。无服务器函数以更短的周期发布,因为无需配置基础设施,这正是 AI 应用在其上迭代的原因。

连接池是无服务器所暴露的问题

每次函数调用都会打开自己的数据库连接。在突发流量下,几百个并发调用就会变成几百个连接,传统的 MySQL 或 Postgres 实例开始拒绝它们。团队通常的应对是添加外部连接池器,这增加了一跳、一个需要运维的组件,以及一种新的故障模式。

TiDB Cloud Starter 采取了不同的路径,使用 TiDB Cloud 无服务器驱动,它通过 HTTPS 而非 TCP 与数据库通信。由于路径中没有持久连接,也就没有连接池会被耗尽。每次调用发起一个 HTTPS 请求,获取结果,然后结束。

本指南涵盖的运行时

以下所有内容都适用于三个目标:Vercel 无服务器函数(Node.js 运行时)、Vercel Edge Functions 和 Cloudflare Workers。边缘运行时是最严格的情况,因为它们完全不允许原始 TCP 套接字。在那里,使用 HTTPS 的驱动不是一种优化,而是唯一能连接的方式。

从 v0.dev 或 Lovable 原型到已部署的 Vercel 应用

像 v0.dev 和 Lovable 这样的 AI 构建器能在几分钟内搭建出一个可运行的 Next.js 应用,然后交给你一个期望数据库 URL、并自带通用 Postgres 或 SQLite 起始模板的项目。把这个起始模板换成 TiDB Cloud Starter 需要三步:原型、连接、部署。

原型。照常生成应用。输出是一个标准的 Next.js 项目,带有一个 API 层、一个数据访问文件,以及一个期望 .env 或 .env.local 中 DATABASE_URL 的文件。

连接。找到生成的应用读取该变量的位置。在 Prisma 项目中,它是 datasource 块中的 prisma/schema.prisma。在 Drizzle 或 Kysely 项目中,它是客户端初始化文件。将其指向 TiDB Cloud Starter 连接字符串:

DATABASE_URL='mysql://<user>:<password>@<host>:4000/<database>?sslaccept=strict'

如果脚手架假设的是 Postgres,请将 provider 改为 mysql 并重新生成客户端。TiDB 使用 MySQL 有线协议,因此任何 MySQL 驱动、ORM 或迁移工具都可以不加修改地使用。

部署。推送到 GitHub 并将仓库导入 Vercel,或使用本文后面介绍的 Marketplace 集成,它会在部署期间设置连接变量。

在原型阶段而不是更晚进行替换的原因:生成应用自带的起始数据库是按演示规模配置的。TiDB Cloud Starter 在同一 MySQL 兼容接口上水平扩缩容,因此原型和生产系统针对同一引擎运行相同的代码。

启动你的 TiDB Cloud Starter 集群(你的 Vercel 数据库)

配置数据库只需不到一分钟。登录 TiDB Cloud,按照屏幕上的说明创建一个免费的 TiDB Cloud Starter 集群,然后点击集群名称将其打开。

选择你的入口:Cloud、Starter 或 Zero

存在三种入口,正确的选择取决于你要构建什么。

  • TiDB Cloud Zero通过一次 API 调用配置一个临时实例,无需注册,也无需账单信息。实例会在 30 天后过期,除非你认领它们,而认领会将其转换为持久的 TiDB Cloud Starter 实例,数据与模式会自动迁移。Zero 是为智能体驱动的工作流、演示和 CI 而构建的,目前处于公开预览阶段,网址为 zero.tidbcloud.com。
  • TiDB Cloud Starter 是 TiDB Cloud 内免费的全托管无服务器层级。对于需要持久化真实数据的 Vercel 应用,这是默认选择。
  • TiDB Cloud 是完整平台。Starter 位于其中,而随着应用成长,Essential 和 Dedicated 会增加容量、隔离性和企业级控制。

如果由代理或脚本执行预配,请从 Zero 开始。如果是由人工构建一个需要持续运行超过一周的应用,请从 Starter 开始。

获取你的连接详细信息

在集群视图中,点击 Connect 以打开连接详细信息,并记下 Host、Port 和 User 的值。你将使用它们来构建 ORM 读取的连接字符串。

将这些值存储为 Vercel 环境变量,而不是将它们提交到代码中。在 Vercel 仪表盘中,转到 Settings > Environment Variables,添加 DATABASE_URL,并将其作用域限定为需要它的环境。在本地,将其保存在 .env.local 中,Next.js 默认会将其从 git 中排除。

在继续之前验证连接性:

mysql --connect-timeout 15 -u '<user>' -h '<host>' -P 4000 -D '<database>' \
  --ssl-mode=VERIFY_IDENTITY --ssl-ca=/etc/ssl/certs/ca-certificates.crt -p

为 AI 应用数据建模:会话、聊天日志、偏好设置和检索状态

AI 应用存储一组可预测的内容:对话会话、其中的消息、代理执行的操作,以及塑造未来响应的偏好设置。Prisma 可以干净地为所有这些建模,其机制与任何 Prisma 项目使用的机制相同。

安装适配器、无服务器驱动程序和 Prisma CLI:

npm install @tidbcloud/prisma-adapter @tidbcloud/serverless
npm install prisma --save-dev

在 prisma/schema.prisma 中启用驱动程序适配器并定义模型:

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["driverAdapters"]
}

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

model Session {
  id        String        @id @default(uuid())
  userId    String        @map("user_id") @db.VarChar(64)
  title     String?       @db.VarChar(255)
  createdAt DateTime      @default(now()) @map("created_at")
  messages  Message[]
  actions   AgentAction[]

  @@index([userId, createdAt])
  @@map("sessions")
}

model Message {
  id         BigInt   @id @default(autoincrement())
  sessionId  String   @map("session_id") @db.VarChar(36)
  role       String   @db.VarChar(16)
  content    String   @db.Text
  tokenCount Int?     @map("token_count")
  createdAt  DateTime @default(now()) @map("created_at")
  session    Session  @relation(fields: [sessionId], references: [id])

  @@index([sessionId, createdAt])
  @@map("messages")
}

model AgentAction {
  id        BigInt   @id @default(autoincrement())
  sessionId String   @map("session_id") @db.VarChar(36)
  tool      String   @db.VarChar(64)
  input     Json?
  output    Json?
  status    String   @db.VarChar(16)
  createdAt DateTime @default(now()) @map("created_at")
  session   Session  @relation(fields: [sessionId], references: [id])

  @@index([sessionId, status])
  @@map("agent_actions")
}

model UserPreference {
  userId    String   @id @map("user_id") @db.VarChar(64)
  settings  Json
  updatedAt DateTime @updatedAt @map("updated_at")

  @@map("user_preferences")
}

导出连接字符串并推送 schema:

export DATABASE_URL='mysql://<user>:<password>@<host>:4000/<database>?sslaccept=strict'
npx prisma db push
npx prisma generate

关于适配器行为有两点说明。prisma db push、Prisma Migrate 和内省使用传统 TCP 连接,因此请从你的机器或 CI 运行它们,而不是从边缘函数运行。Prisma Client 查询通过适配器经 HTTPS 进行。每个模块初始化一次客户端:

import { PrismaTiDBCloud } from '@tidbcloud/prisma-adapter';
import { PrismaClient } from '@prisma/client';

const adapter = new PrismaTiDBCloud({ url: process.env.DATABASE_URL });
const prisma = new PrismaClient({ adapter });

对于早于 v6.6.0 的适配器版本,请先使用 connect()(来自 @tidbcloud/serverless)构建连接,并将其传递给 new PrismaTiDBCloud(connection)。TiDB Cloud 无服务器驱动程序和 Prisma 集成文章更深入地介绍了适配器、事务以及与 TCP 路径的差异。

使用 TiDB 向量搜索存储嵌入并驱动检索

TiDB 具有原生 VECTOR 数据类型,因此嵌入与其所属的会话和消息存储在同一个数据库中。无需预配第二个系统,无需同步作业,也不存在向量存储与应用程序数据库不一致的窗口期。

添加一个包含固定维度向量列和 HNSW 索引的文档表。维度必须与你的嵌入模型匹配,1536 与 OpenAI 的 text-embedding-3-small 匹配:

CREATE TABLE documents (
  id BIGINT PRIMARY KEY AUTO_RANDOM,
  session_id VARCHAR(36),
  content TEXT,
  embedding VECTOR(1536),
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  VECTOR INDEX idx_embedding ((VEC_COSINE_DISTANCE(embedding)))
);

Prisma 没有对 VECTOR 的原生映射,因此请使用原始 SQL 创建该列,并通过无服务器驱动程序或 $queryRaw 查询它。检索就是一条普通的 SQL 查询:

import { connect } from '@tidbcloud/serverless';

const conn = connect({ url: process.env.DATABASE_URL });

const results = await conn.execute(
  `SELECT id, content, VEC_COSINE_DISTANCE(embedding, ?) AS distance
   FROM documents
   ORDER BY distance
   LIMIT 10`,
  [JSON.stringify(queryEmbedding)]
);

当你需要按租户、会话或用户进行过滤时,请先运行最近邻搜索再过滤结果,因为置于向量排序之前的 WHERE 子句可能会阻止索引被使用:

SELECT * FROM (
  SELECT id, session_id, content,
         VEC_COSINE_DISTANCE(embedding, '[0.1, 0.2, ...]') AS distance
  FROM documents
  ORDER BY distance
  LIMIT 50
) t
WHERE session_id = '<session-id>'
ORDER BY distance
LIMIT 10;

收益体现在写入时。将消息、其嵌入和代理操作存储在一起的插入会作为一个事务提交,因此检索状态和应用状态保持一致。有关距离函数、索引行为以及结合全文的混合搜索,请参阅 TiDB 向量搜索文档。

从边缘连接:Vercel Edge Functions 和 Cloudflare Workers

边缘运行时是数据库选择受到考验的地方,因为它们禁止原始 TCP 套接字。任何基于 TCP 连接构建的驱动程序在那里都会失败,无论其如何配置。TiDB Cloud 无服务器驱动程序通过 HTTPS 连接,@tidbcloud/prisma-adapter v5.11.0 及更高版本可在 Vercel Edge Functions 和 Cloudflare Workers 中工作。

在边缘运行的路由处理程序看起来就像普通的 Prisma 查询:

// app/api/messages/route.ts
export const runtime = 'edge';

import { PrismaTiDBCloud } from '@tidbcloud/prisma-adapter';
import { PrismaClient } from '@prisma/client';

const adapter = new PrismaTiDBCloud({ url: process.env.DATABASE_URL });
const prisma = new PrismaClient({ adapter });

export async function GET(request: Request) {
  const sessionId = new URL(request.url).searchParams.get('session');

  const messages = await prisma.message.findMany({
    where: { sessionId: sessionId ?? undefined },
    orderBy: { createdAt: 'asc' },
    take: 50,
  });

  return Response.json(messages);
}

由于每次调用都会发出自己的 HTTPS 请求,突发的流量会产生一批独立请求,而不是对共享连接池的争用。冷启动时没有预热惩罚,也无需设置连接池大小。

在部署前进行本地测试:

npm run dev

打开 http://localhost:3000/api/messages?session=<session-id> 并确认你能获得返回的行。如果响应为空但没有出现错误,则说明连接正常且表为空,这正是 prisma db push 之后的预期状态。

使用 TiDB Cloud 集成在 Vercel 上部署

手动配置开发、预览和生产环境既缓慢又容易出错,尤其是在连接详细信息发生变化时。Vercel Marketplace 上的 TiDB Cloud 集成只需点击几下即可处理,并且该演示应用已发布为 TiDB Cloud Starter Template。

  1. 打开模板并点击 Deploy。Vercel 会提示你创建一个 GitHub 仓库。给它起个名字,如果它不存在,Vercel 会创建它。
  2. 在 Add Integrations 部分中,添加 TiDB Cloud。在弹出的窗口中,选择目标 Vercel 项目,然后选择 TiDB Organization、Project 和 Cluster。对于首次部署,默认值即可。
  3. 选择 Prisma 作为框架,然后点击 Add Integration。Vercel 会将你带回集成屏幕,并显示正在进行的部署。
  4. 部署完成后,点击 Continue to Dashboard,然后点击 Visit 以确认应用已上线。
  5. 检查 Settings > Environment Variables。集成已经写入了连接详细信息,因此无需手动粘贴任何内容。

最后一步值得验证而不是假设。预览部署和生产环境读取相同的变量,这正是防止分支部署指向错误数据库的原因。

TiDB Cloud Starter 与 Vercel Postgres、Neon 和 Supabase 对比

大多数 Vercel 开发者在 Vercel Postgres(现通过 Marketplace 为 Neon)、Supabase 和 TiDB Cloud Starter 之间进行选择。这三者都是托管的,都能缩容到零,并且都为边缘运行时提供 HTTP 驱动程序。对 AI 应用重要的差异体现在扩展模型、向量处理和分析方面。

TiDB Cloud StarterVercel Postgres / NeonSupabase
线路协议MySQLPostgreSQLPostgreSQL
写入扩展跨节点水平扩展,无需手动分片在单个主节点上垂直扩展,读取使用只读副本在单个主节点上垂直扩展,读取使用只读副本
边缘连接性HTTPS 无服务器驱动程序,Prisma 和 Kysely 适配器HTTP 驱动程序(@neondatabase/serverless)通过 PostgREST 使用 HTTP,或使用 Supavisor 进行池化 TCP
向量搜索原生 VECTOR 类型,在同一数据库中带 HNSW 索引pgvector 扩展pgvector 扩展
对实时数据进行分析HTAP:在同一系统中实现行存储加列式副本分析查询命中同一个行存储分析查询命中同一个行存储
超越数据库仅数据库仅数据库身份验证、存储、实时、边缘函数

按照你的应用所需而非按行数来读取表。有关各层级和限制的更多详情,请参阅 TiDB Cloud Starter 产品页面。

启动你的免费 TiDB Cloud Starter 集群

现在你已拥有完整路径:一个连接到真实数据库的原型、用于会话和代理状态的 schema、与所描述的行一起存储的嵌入、通过 HTTPS 的边缘连接,以及一个可自行配置的一键部署。

启动一个免费的 TiDB Cloud Starter 集群并将你的 Vercel 应用指向它。该演示应用的完整源代码位于 GitHub 上的演示仓库。

文章 Vercel 和 TiDB Cloud Starter:AI 应用的全栈实战手册 首次发表于 TiDB。

这篇内容对你有用吗?

反馈只用于改善内容筛选,不等同于收藏

分享这条资讯
分享海报
保存图片
iOS 也可以长按图片保存