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