llmbackend/doc/db.md
2024-12-04 11:24:47 +08:00

268 lines
No EOL
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# LLM API 转发平台数据库规格书
---
## 目录
1. [简介](#1-简介)
2. [数据库概览](#2-数据库概览)
3. [MySQL 数据库设计](#3-mysql-数据库设计)
- [3.1 管理员表admins](#31-管理员表admins)
- [3.2 客户用户表clients](#32-客户用户表clients)
- [3.3 LLM 提供商表llm_providers](#33-llm-提供商表llm_providers)
- [3.4 认证令牌表auth_tokens](#34-认证令牌表auth_tokens)
- [3.5 管理员与客户用户关联表admin_client](#35-管理员与客户用户关联表admin_client)
- [3.6 操作日志表operation_logs](#36-操作日志表operation_logs)
4. [Redis 缓存设计](#4-redis-缓存设计)
- [4.1 访问令牌存储](#41-访问令牌存储)
- [4.2 令牌注销机制](#42-令牌注销机制)
5. [数据库关系图](#5-数据库关系图)
6. [总结](#6-总结)
---
## 1. 简介
本规格书旨在基于之前的系统设计,详细设计 LLM API 转发平台的数据库结构。数据库采用 **MySQL** 作为主要的数据存储,**Redis** 用于缓存短期有效的访问令牌和支持动态注销功能。
---
## 2. 数据库概览
- **MySQL**持久化存储管理员、客户用户、LLM 提供商、认证令牌等信息。
- **Redis**:缓存短期访问令牌,实现高效验证和支持令牌的动态注销。
---
## 3. MySQL 数据库设计
### 3.1 管理员表(`admins`
**描述**:存储超级管理员和管理员的信息。
**字段**
| 字段名 | 数据类型 | 允许为空 | 默认值 | 描述 |
|-----------------|-----------------|----------|--------|----------------------|
| `id` | BIGINT UNSIGNED | 否 | 自增 | 主键 |
| `username` | VARCHAR(50) | 否 | | 用户名 |
| `password` | VARCHAR(255) | 否 | | 加密后的密码 |
| `email` | VARCHAR(100) | 是 | NULL | 邮箱 |
| `role` | ENUM('super', 'admin') | 否 | 'admin' | 角色,'super'为超级管理员,'admin'为管理员 |
| `created_at` | TIMESTAMP | 否 | 当前时间 | 创建时间 |
| `updated_at` | TIMESTAMP | 否 | 当前时间 | 更新时间 |
**索引**
- `UNIQUE INDEX``username`
- `INDEX``email`
### 3.2 客户用户表(`clients`
**描述**:存储客户用户的信息。
**字段**
| 字段名 | 数据类型 | 允许为空 | 默认值 | 描述 |
|-----------------------|-----------------|----------|--------|------------------------------|
| `id` | BIGINT UNSIGNED | 否 | 自增 | 主键 |
| `name` | VARCHAR(100) | 否 | | 客户用户名称 |
| `llm_provider_id` | BIGINT UNSIGNED | 否 | | 外键,关联到 `llm_providers.id` |
| `created_at` | TIMESTAMP | 否 | 当前时间 | 创建时间 |
| `updated_at` | TIMESTAMP | 否 | 当前时间 | 更新时间 |
**索引**
- `INDEX``llm_provider_id`
**外键约束**
- `llm_provider_id` 引用 `llm_providers.id`,级联更新和删除。
### 3.3 LLM 提供商表(`llm_providers`
**描述**:存储 LLM 提供商的信息。
**字段**
| 字段名 | 数据类型 | 允许为空 | 默认值 | 描述 |
|------------------|-----------------|----------|--------|------------------------------|
| `id` | BIGINT UNSIGNED | 否 | 自增 | 主键 |
| `name` | VARCHAR(100) | 否 | | 提供商名称 |
| `service_name` | VARCHAR(100) | 否 | | 服务名称,用于后端调用逻辑 |
| `api_url` | VARCHAR(255) | 否 | | 提供商的 API 接口地址 |
| `api_token` | VARCHAR(255) | 否 | | 调用提供商 API 所需的令牌 |
| `created_at` | TIMESTAMP | 否 | 当前时间 | 创建时间 |
| `updated_at` | TIMESTAMP | 否 | 当前时间 | 更新时间 |
**索引**
- `UNIQUE INDEX``name`
- `INDEX``service_name`
### 3.4 认证令牌表(`auth_tokens`
**描述**:存储客户用户的长期认证令牌。
**字段**
| 字段名 | 数据类型 | 允许为空 | 默认值 | 描述 |
|-----------------|-----------------|----------|--------|--------------------------------|
| `id` | BIGINT UNSIGNED | 否 | 自增 | 主键 |
| `client_id` | BIGINT UNSIGNED | 否 | | 外键,关联到 `clients.id` |
| `token` | CHAR(64) | 否 | | 认证令牌随机生成的64位字符串 |
| `expires_at` | TIMESTAMP | 是 | NULL | 过期时间NULL表示永久有效 |
| `created_at` | TIMESTAMP | 否 | 当前时间 | 创建时间 |
| `updated_at` | TIMESTAMP | 否 | 当前时间 | 更新时间 |
**索引**
- `UNIQUE INDEX``token`
- `INDEX``client_id`
**外键约束**
- `client_id` 引用 `clients.id`,级联删除。
### 3.5 管理员与客户用户关联表(`admin_client`
**描述**:存储管理员与客户用户的多对多关系。
**字段**
| 字段名 | 数据类型 | 允许为空 | 默认值 | 描述 |
|--------------|-----------------|----------|--------|-----------------------------|
| `admin_id` | BIGINT UNSIGNED | 否 | | 外键,关联到 `admins.id` |
| `client_id` | BIGINT UNSIGNED | 否 | | 外键,关联到 `clients.id` |
| `assigned_at`| TIMESTAMP | 否 | 当前时间 | 分配时间 |
**索引**
- `PRIMARY KEY`(`admin_id`, `client_id`)
- `INDEX``client_id`
**外键约束**
- `admin_id` 引用 `admins.id`,级联删除。
- `client_id` 引用 `clients.id`,级联删除。
### 3.6 操作日志表(`operation_logs`
**描述**:记录管理员和客户用户的操作日志。
**字段**
| 字段名 | 数据类型 | 允许为空 | 默认值 | 描述 |
|-----------------|-----------------|----------|--------|------------------------------|
| `id` | BIGINT UNSIGNED | 否 | 自增 | 主键 |
| `user_type` | ENUM('admin', 'client') | 否 | | 用户类型 |
| `user_id` | BIGINT UNSIGNED | 否 | | 用户ID关联管理员或客户用户 |
| `operation` | VARCHAR(255) | 否 | | 操作描述 |
| `ip_address` | VARCHAR(45) | 是 | NULL | IP地址支持IPv6 |
| `created_at` | TIMESTAMP | 否 | 当前时间 | 操作时间 |
**索引**
- `INDEX``user_type`, `user_id`
---
## 4. Redis 缓存设计
### 4.1 访问令牌存储
**描述**:存储客户用户的短期访问令牌,实现高效的令牌验证和自动过期。
- **Key 格式**`access_token:{token}`
- **Value 内容**:序列化的令牌信息,包括`client_id`、`expires_at`等。
**示例**
- **Key**`access_token:a1b2c3d4e5f6...`
- **Value**
```json
{
"client_id": 12345,
"expires_at": "2023-10-01T12:00:00Z"
}
```
- **过期策略**:设置 `TTL`,令牌将在 `expires_at` 到达时自动过期。
### 4.2 令牌注销机制
**描述**:支持访问令牌的即时注销,防止被滥用。
- **方案**:当需要注销令牌时,直接从 Redis 中删除对应的 `access_token:{token}` 键。
- **实现步骤**
1. 调用 Redis 的 `DEL` 命令删除指定的令牌键。
2. 后续的令牌验证中,如令牌不存在或已过期,则拒绝访问。
---
## 5. 数据库关系图
```
+----------------+ +----------------+ +----------------+
| admins | | clients | | llm_providers |
+----------------+ +----------------+ +----------------+
| id |<----->| id | | id |
| username | | name | | name |
| password | | llm_provider_id|<----->| service_name |
| role | | | | api_url |
+----------------+ +----------------+ | api_token |
^ ^ +----------------+
| |
| +---------------+
| |
+-----------------+
| admin_client |
+-----------------+
| admin_id |
| client_id |
+-----------------+
+----------------+
| auth_tokens |
+----------------+
| id |
| client_id |
| token |
+----------------+
```
**说明**
- `admins``clients` 之间是多对多关系,通过 `admin_client` 关联。
- `clients``llm_providers` 是多对一关系,`clients.llm_provider_id` 外键引用 `llm_providers.id`
- `clients``auth_tokens` 是一对多关系,一个客户用户可以有多个认证令牌。
---
## 6. 总结
以上是基于系统设计的数据库规格书,详细描述了 MySQL 中的表结构和 Redis 中的缓存设计。
- **MySQL**
- **管理员表**:存储超级管理员和管理员的信息。
- **客户用户表**:存储客户用户的信息,并绑定 LLM 提供商。
- **LLM 提供商表**:存储 LLM 提供商的配置和调用信息。
- **认证令牌表**:存储客户用户的长期认证令牌。
- **管理员与客户用户关联表**:实现管理员和客户用户的多对多关系。
- **操作日志表**:记录系统的操作日志,便于审计和追踪。
- **Redis**
- **访问令牌存储**:高效存储和验证短期访问令牌,支持自动过期和动态注销。
**注意事项**
- 所有涉及敏感信息的字段如密码、令牌、API Token在存储时应进行加密或哈希处理确保数据安全。
- 数据库的外键约束和索引设计应充分考虑性能和数据完整性。
- Redis 中的令牌管理应注意内存占用和过期策略,防止缓存过期造成的认证问题。
---
如有任何疑问或需要进一步的修改和完善,请随时联系数据库设计团队。