4.9 KiB
4.9 KiB
架构决策记录 (ADR): 数据库 Schema 设计方案 v1.0
状态: 已实施 (IMPLEMENTED)
日期: 2025-12-23
作者: 首席系统架构师
背景: Next_Edu 平台 - K12 智慧教育管理系统
1. 概述 (Overview)
本文档详细记录了 Next_Edu 平台的数据库 Schema 架构设计。本设计优先考虑 可扩展性 (Scalability)、灵活性 (Flexibility)(针对复杂的嵌套内容)以及 严格的类型安全 (Strict Type Safety),并完全符合 PRD 中规定的领域驱动设计 (DDD) 原则。
2. 技术栈决策 (Technology Stack Decisions)
| 组件 | 选择 | 理由 |
|---|---|---|
| 数据库 | MySQL 8.0+ | 强大的关系型支持,完善的 JSON 能力,行业标准。 |
| ORM | Drizzle ORM | 轻量级,零运行时开销 (Zero-runtime overhead),业界一流的 TypeScript 类型推断。 |
| ID 策略 | CUID2 | 分布式友好 (k-sortable),安全(防连续猜测攻击),比 UUID 更短。 |
| 认证方案 | Auth.js v5 | 标准化的 OAuth 流程,支持自定义数据库适配器。 |
3. 核心 Schema 领域模型 (Core Schema Domains)
物理文件位于 src/shared/db/schema.ts,逻辑上分为三大领域。
3.1 身份与访问管理 (IAM)
我们采用了 Auth.js 标准表 与 自定义 RBAC 相结合的混合模式。
- 标准表:
users,accounts(OAuth),sessions,verificationTokens。 - RBAC 扩展:
roles: 定义系统角色(例如:grade_head年级主任,teacher老师)。users_to_roles: 多对多关联表。- 设计目标: 解决“一人多职”问题(例如:一个老师同时也是年级主任),避免在
users表中堆砌字段。
3.2 智能题库中心 (Intelligent Question Bank) - 核心
这是最复杂的领域,需要支持无限层级嵌套和富文本内容。
实体定义:
questions(题目表):id: CUID2。content: JSON 类型。存储结构化内容(如 SlateJS 节点),支持富文本、图片和公式混排。parentId: 自引用 (Self-Reference)。- 若为 NULL: 独立题目 或 “大题干” (Parent)。
- 若有值: 子题目 (Child)(例如:一篇阅读理解下的第1小题)。
type: 枚举 (single_choice,text,composite等)。
knowledge_points(知识点表):- 通过
parentId实现树状结构。 - 支持无限层级 (学科 -> 章 -> 节 -> 知识点)。
- 通过
questions_to_knowledge_points:- 多对多关联。一道题可考察多个知识点;一个知识点可关联数千道题。
3.3 教务教学流 (Academic Teaching Flow)
将物理世界的教学过程映射为数字实体。
textbooks&chapters: 标准的教材大纲映射。chapters同样支持通过parentId进行嵌套。exams: 考试/作业的聚合实体。exam_submissions: 代表一名学生的单次答题记录。submission_answers: 细粒度的答题详情,记录每道题的答案,支持自动评分 (score) 和人工反馈 (feedback)。
4. 关键设计模式 (Key Design Patterns)
4.1 无限嵌套 ("Composite" Pattern)
我们没有为“题干”和“题目”创建单独的表,而是在 questions 表上使用 自引用 (Self-Referencing) 模式。
- 优点:
- 统一的查询接口 (
db.query.questions.findFirst({ with: { children: true } }))。 - 递归逻辑可统一应用。
- 当内容结构变化时,迁移更简单。
- 统一的查询接口 (
- 缺点:
- 需要处理递归查询逻辑(已通过 Drizzle Relations 解决)。
4.2 CUID2 优于 自增 ID
- 安全性: 防止 ID 枚举攻击(猜测下一个用户 ID)。
- 分布式: 支持在客户端或多服务器节点生成,无碰撞风险。
- 性能:
k-sortable特性保证了比随机 UUID v4 更好的索引局部性。
4.3 JSON 存储内容
- 教育内容不仅仅是“文本”。它包含格式、LaTeX 公式和图片引用。
- 使用
JSON存储允许前端 (Next.js) 直接渲染富组件,无需解析复杂的 HTML 字符串。
5. 安全与索引策略 (Security & Indexing Strategy)
索引 (Indexes)
- 外键: 所有外键列 (
author_id,parent_id等) 均显式建立索引。 - 性能:
parent_id_idx: 对树形结构的遍历性能至关重要。email_idx: 登录查询的核心索引。
类型安全 (Type Safety)
- 严格的 TypeScript 定义直接从
src/shared/db/schema.ts导出。 - Zod Schema (待生成) 将与这些 Drizzle 定义保持 1:1 对齐。
6. 目录结构 (Directory Structure)
src/shared/db/
├── index.ts # 单例数据库连接池
├── schema.ts # 物理表结构定义
└── relations.ts # 逻辑 Drizzle 关系定义