> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fim.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 数据库

> 为您的部署选择并配置正确的数据库后端

FIM One 支持两个数据库后端：**SQLite**（默认，零配置）和 **PostgreSQL**（推荐用于生产环境）。后端由 `DATABASE_URL` 环境变量决定。

```bash theme={null}
# SQLite (default — no configuration needed)
DATABASE_URL=sqlite+aiosqlite:///./data/fim_one.db

# PostgreSQL (production)
DATABASE_URL=postgresql+asyncpg://user:pass@localhost:5432/fim_one
```

表会在首次启动时自动创建 — 无需手动迁移步骤。

***

## SQLite vs PostgreSQL

|              | SQLite                 | PostgreSQL      |
| ------------ | ---------------------- | --------------- |
| **设置**       | 零配置，基于文件               | 需要单独的服务器        |
| **并发性**      | 单写入器（全局锁）              | 完整 MVCC，行级锁定    |
| **多工作进程**    | 不支持（`WORKERS` 必须为 `1`） | 完全支持            |
| **SSE 流式传输** | 流式传输期间保持的连接可能会阻止其他请求   | 并发读写不受影响        |
| **备份**       | 复制 `.db` 文件            | `pg_dump` 或流式复制 |
| **最适合**      | 开发、单用户、演示              | 生产、多用户、团队       |

<Tip>
  **本地开发：** SQLite 开箱即用 — 无需数据库服务器、无需 Redis、无需配置任何内容。直接开始编码。

  **生产环境：** 使用 Docker Compose 部署，PostgreSQL + Redis 会自动配置。无需手动设置数据库。
</Tip>

***

## 已知限制：SQLite 并发流式传输

<Warning>
  **SQLite 在并发负载下可能成为瓶颈。**

  FIM One 使用服务器发送事件 (SSE) 来流式传输 AI 响应。在流式传输期间，每个活跃的 SSE 连接在流式传输期间会占用连接池中的一个数据库连接。SQLite 强制执行全局写入锁，这意味着一次只能进行一个写入操作——所有其他写入操作都排队等待。

  尽管连接池支持最多 30 个并发连接（`pool_size=20` + `max_overflow=10`），但瓶颈是锁本身，而不是连接池。当多个用户同时聊天时，他们的写入操作（保存消息、更新令牌计数）会相互序列化。

  **您可能观察到的症状：**

  * 当另一个用户正在流式传输时，对话列表加载缓慢
  * 在活跃聊天会话期间，设置页面感觉反应迟缓
  * 当多个流处于活跃状态时，API 响应延迟

  **建议：** 如果您有 2-3 个以上的并发用户，请切换到 PostgreSQL。PostgreSQL 使用 MVCC（多版本并发控制）和行级锁定，因此并发读取和写入可以独立进行，不会相互阻塞。
</Warning>

***

## 连接池配置

FIM One 为每个后端内部配置 SQLAlchemy 连接池设置。这些是经过调整的默认值，不需要环境变量 — 它们会根据 `DATABASE_URL` 方案自动应用。了解它们有助于解释运行时行为。

### SQLite 连接池设置

| 设置             | 值        | 描述                                     |
| -------------- | -------- | -------------------------------------- |
| `pool_size`    | `20`     | 连接池中的基础持久连接数                           |
| `max_overflow` | `10`     | 在负载下创建的额外连接（总计最多 30 个）                 |
| WAL 日志模式       | 已启用      | 预写日志允许在写入进行时进行并发读取，显著降低锁争用             |
| `busy_timeout` | `30s`    | 当写入锁被持有时，其他写入者最多等待 30 秒后才会抛出错误，而不是立即失败 |
| `synchronous`  | `NORMAL` | 与 WAL 模式兼容；提供比默认 `FULL` 更好的写入吞吐量       |

WAL 模式和 30 秒忙碌超时通过 SQLite PRAGMA 在每个新连接上设置。这种组合确保短期读取（加载对话列表、获取设置）不会被长时间运行的写入事务阻止，并且并发写入会优雅地排队而不是失败。

### PostgreSQL 连接池设置

| 设置             | 值       | 描述                                         |
| -------------- | ------- | ------------------------------------------ |
| `pool_size`    | `10`    | 连接池中持久连接的基础数量                              |
| `max_overflow` | `20`    | 在负载下创建的额外连接（总计最多 30 个）                     |
| `pool_timeout` | `30s`   | 从连接池等待可用连接的最长时间，超时后抛出错误                    |
| `pool_recycle` | `1800s` | 连接每 30 分钟回收一次，以防止陈旧连接（对于会关闭空闲连接的云托管数据库很重要） |

PostgreSQL 通过 MVCC 原生处理并发，因此连接池设置主要控制资源使用而非竞争。30 分钟的回收间隔可以避免防火墙、负载均衡器或托管数据库服务无声地丢弃空闲 TCP 连接的问题。

***

## 切换到 PostgreSQL

### 第 1 步：启动 PostgreSQL 实例

最快的方式是使用 Docker：

```bash theme={null}
docker run -d \
  --name postgres \
  -e POSTGRES_PASSWORD=secret \
  -e POSTGRES_DB=fim_one \
  -p 5432:5432 \
  postgres:16-alpine
```

### 第 2 步：设置 DATABASE\_URL

在你的 `.env` 文件中添加或更新以下行：

```bash theme={null}
DATABASE_URL=postgresql+asyncpg://postgres:secret@localhost:5432/fim_one
```

### 第 3 步：重启 FIM One

```bash theme={null}
# Local development
./start.sh portal

# Or restart your process manager / systemd service
```

表会在首次启动时自动创建。无需手动进行架构迁移。

<Note>
  **现有 SQLite 数据不会自动迁移。** 将 `DATABASE_URL` 从 SQLite 切换到 PostgreSQL 会使用全新数据库启动。如果您在 SQLite 中有需要保留的现有对话、智能体或连接器，请参阅下面的[数据迁移](#data-migration)部分。
</Note>

### Docker Compose（推荐用于生产环境）

如果使用 Docker Compose 部署，**PostgreSQL 和 Redis 已包含并自动配置** — 无需额外设置。`docker-compose.yml` 在内部设置 `DATABASE_URL` — 你的 `.env` 值会被覆盖：

```yaml theme={null}
environment:
  DATABASE_URL: postgresql+asyncpg://fim:fim@postgres:5432/fim_one
```

使用 Docker Compose 时无需额外的数据库设置。

***

## 数据迁移

SQLite 到 PostgreSQL 没有内置的迁移工具。对于大多数部署，推荐的方法取决于您的情况：

**全新部署（无现有数据）：** 只需将 `DATABASE_URL` 设置为您的 PostgreSQL 连接字符串并启动 FIM One。所有表都会自动创建。

**必须保留现有数据：** 需要手动导出/导入。一般方法：

1. 使用 `sqlite3` CLI 或 Python 脚本等工具从 SQLite 导出数据
2. 根据需要转换数据（SQLite 和 PostgreSQL 有细微的类型差异）
3. 使用 `psql`、`pg_restore` 或应用级别的插入脚本导入到 PostgreSQL

<Tip>
  对于大多数从开发设置升级到生产环境的用户，使用 PostgreSQL 重新开始会更简单，并通过 UI 重新创建您的智能体和连接器。对话历史通常不重要到足以保证手动迁移的必要性。
</Tip>
