155 lines
6.8 KiB
Markdown
155 lines
6.8 KiB
Markdown
# 🗃️ 项目数据库设计说明
|
||
|
||
本文档描述了本 FastAPI 练手网站的数据库实体(表)结构与关系设计。
|
||
所有用户相关数据均通过 `user_id` 外键关联,实现**多用户数据隔离**。
|
||
数据库使用 **SQLite(开发阶段)**,ORM 框架推荐 **SQLModel**(兼容 Pydantic + SQLAlchemy)。
|
||
|
||
> 💡 **注**:天气查询功能调用第三方 API,**不持久化存储**,故无对应表。
|
||
|
||
---
|
||
|
||
## 📚 实体列表
|
||
|
||
| 表名 | 用途说明 |
|
||
|------------------|------------------------------|
|
||
| `users` | 用户账户信息 |
|
||
| `todos` | 待办事项列表 |
|
||
| `posts` | 博客文章 |
|
||
| `transactions` | 个人记账记录 |
|
||
| `media` | 书影音收藏条目 |
|
||
| `tags` | 媒体标签(用于分类/打标) |
|
||
| `media_tags` | `media` 与 `tags` 的多对多关联表 |
|
||
| `chat_messages` | 聊天室消息记录 |
|
||
| `uploads` | 用户上传的文件元数据 |
|
||
|
||
---
|
||
|
||
## 🔍 详细表结构
|
||
|
||
### 1. `users` — 用户表
|
||
|
||
| 字段名 | 类型 | 约束/说明 |
|
||
|-------------------|----------------|-------------------------------|
|
||
| `id` | INTEGER | 主键 (PK) |
|
||
| `username` | VARCHAR(50) | 唯一,非空 |
|
||
<|`email`|VARCHAR(100)|唯一,可为空|
|
||
| `hashed_password` | TEXT | bcrypt 哈希后的密码 |
|
||
| `created_at` | DATETIME | 默认当前时间 |
|
||
|
||
---
|
||
|
||
### 2. `todos` — 待办事项
|
||
|
||
| 字段名 | 类型 | 约束/说明 |
|
||
|--------------|-------------|--------------------------|
|
||
| `id` | INTEGER | PK |
|
||
| `title` | VARCHAR(200)| 非空 |
|
||
| `done` | BOOLEAN | 默认 `FALSE` |
|
||
| `created_at` | DATETIME | 默认当前时间 |
|
||
| `user_id` | INTEGER | 外键 → `users.id` |
|
||
|
||
---
|
||
|
||
### 3. `posts` — 博客文章
|
||
|
||
| 字段名 | 类型 | 约束/说明 |
|
||
|---------------|-------------|----------------------------------------|
|
||
| `id` | INTEGER | PK |
|
||
| `title` | VARCHAR(200)| 非空 |
|
||
| `slug` | VARCHAR(200)| URL 友好标识,建议 `(user_id, slug)` 唯一 |
|
||
| `content` | TEXT | 支持 Markdown |
|
||
| `created_at` | DATETIME | 默认当前时间 |
|
||
| `updated_at` | DATETIME | 可为空 |
|
||
| `user_id` | INTEGER | 外键 → `users.id` |
|
||
|
||
---
|
||
|
||
### 4. `transactions` — 记账记录
|
||
|
||
| 字段名 | 类型 | 约束/说明 |
|
||
|---------------|----------------|----------------------------------|
|
||
| `id` | INTEGER | PK |
|
||
| `amount` | NUMERIC(10,2) | 正数为收入,负数为支出 |
|
||
| `category` | VARCHAR(50) | 如“餐饮”、“交通”、“工资”等 |
|
||
| `description` | VARCHAR(200) | 可为空 |
|
||
| `date` | DATE | 交易发生日期 |
|
||
| `user_id` | INTEGER | 外键 → `users.id` |
|
||
|
||
---
|
||
|
||
### 5. `media` — 书影音收藏
|
||
|
||
| 字段名 | 类型 | 约束/说明 |
|
||
|----------------|-------------|------------------------------------------------|
|
||
| `id` | INTEGER | PK |
|
||
| `title` | VARCHAR(200)| 非空 |
|
||
| `media_type` | VARCHAR(20) | 枚举值:`book` / `movie` / `music` |
|
||
| `rating` | FLOAT | 0.0 ~ 5.0 |
|
||
| `comment` | TEXT | 用户短评 |
|
||
| `external_id` | VARCHAR(100)| 如 ISBN、IMDb ID(用于对接外部 API) |
|
||
| `cover_url` | VARCHAR(300)| 封面图片 URL(可缓存) |
|
||
| `created_at` | DATETIME | 默认当前时间 |
|
||
| `user_id` | INTEGER | 外键 → `users.id` |
|
||
|
||
---
|
||
|
||
### 6. `tags` — 媒体标签
|
||
|
||
| 字段名 | 类型 | 约束/说明 |
|
||
|----------|-------------|---------------|
|
||
| `id` | INTEGER | PK |
|
||
| `name` | VARCHAR(50) | 唯一,非空 |
|
||
|
||
---
|
||
|
||
### 7. `media_tags` — 媒体-标签关联表(多对多)
|
||
|
||
| 字段名 | 类型 | 约束/说明 |
|
||
|-------------|----------|-----------------------------|
|
||
| `media_id` | INTEGER | 外键 → `media.id` |
|
||
| `tag_id` | INTEGER | 外键 → `tags.id` |
|
||
| (联合主键)| — | `(media_id, tag_id)` 唯一 |
|
||
|
||
---
|
||
|
||
### 8. `chat_messages` — 聊天消息
|
||
|
||
| 字段名 | 类型 | 约束/说明 |
|
||
|-------------|----------|-----------------------------------|
|
||
| `id` | INTEGER | PK |
|
||
| `content` | TEXT | 非空 |
|
||
| `sent_at` | DATETIME | 默认当前时间 |
|
||
| `user_id` | INTEGER | 外键 → `users.id`(发送者) |
|
||
| `room` | VARCHAR(50)| 聊天室名称(如 `"main"`) |
|
||
|
||
---
|
||
|
||
### 9. `uploads` — 文件上传记录
|
||
|
||
| 字段名 | 类型 | 约束/说明 |
|
||
|----------------|-------------|--------------------------------------------|
|
||
| `id` | INTEGER | PK |
|
||
| `filename` | VARCHAR(200)| 原始文件名 |
|
||
| `stored_path` | VARCHAR(300)| 服务器存储路径(如 `/uploads/abc.jpg`) |
|
||
| `file_size` | INTEGER | 字节数 |
|
||
| `mime_type` | VARCHAR(100)| 如 `image/jpeg`, `application/pdf` |
|
||
| `uploaded_at` | DATETIME | 默认当前时间 |
|
||
| `expires_at` | DATETIME | 可为空(表示永不过期) |
|
||
| `user_id` | INTEGER | 外键 → `users.id` |
|
||
|
||
> ⚠️ **安全提示**:前端不应直接访问 `stored_path`,应通过受控路由(如 `/download/{id}`)提供下载,并验证用户权限。
|
||
|
||
---
|
||
|
||
## 🔗 实体关系图(ERD)
|
||
|
||
```mermaid
|
||
erDiagram
|
||
users ||--o{ todos : "1:N"
|
||
users ||--o{ posts : "1:N"
|
||
users ||--o{ transactions : "1:N"
|
||
users ||--o{ media : "1:N"
|
||
users ||--o{ chat_messages : "1:N"
|
||
users ||--o{ uploads : "1:N"
|
||
|
||
media }o--o{ tags : "N:M via media_tags" |