Files
CICD/docs/architecture/001_database_schema_design.md
SpecialX e7c902e8e1
Some checks failed
CI / build-and-test (push) Failing after 1m31s
CI / deploy (push) Has been skipped
Module Update
2025-12-30 14:42:30 +08:00

4.9 KiB
Raw Permalink Blame History

架构决策记录 (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) - 核心

这是最复杂的领域,需要支持无限层级嵌套和富文本内容。

实体定义:

  1. questions (题目表):
    • id: CUID2。
    • content: JSON 类型。存储结构化内容(如 SlateJS 节点),支持富文本、图片和公式混排。
    • parentId: 自引用 (Self-Reference)
      • 若为 NULL: 独立题目 或 “大题干” (Parent)。
      • 若有值: 子题目 (Child)例如一篇阅读理解下的第1小题
    • type: 枚举 (single_choice, text, composite 等)。
  2. knowledge_points (知识点表):
    • 通过 parentId 实现树状结构。
    • 支持无限层级 (学科 -> 章 -> 节 -> 知识点)。
  3. 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 关系定义