Files
blogweb/数据库设计说明.md
T
2025-12-26 13:42:22 +08:00

155 lines
6.8 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.
# 🗃️ 项目数据库设计说明
本文档描述了本 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"