769 lines
24 KiB
Markdown
769 lines
24 KiB
Markdown
---
|
||
epoch: 1762310155258
|
||
modelKey: "deepseek-chat|3rd party (openai-format)"
|
||
topic: "NOT NULL 约束含义"
|
||
|
||
|
||
tags:
|
||
- copilot-conversation
|
||
---
|
||
|
||
**user**: NOT NULL是否代表必须得填写进去内容?
|
||
[Context: Notes: 知识图谱/知识图谱数据库设计.md]
|
||
[Timestamp: 2025/11/05 10:35:55]
|
||
|
||
**ai**: 是的,`NOT NULL` 在数据库设计中表示**该字段在插入新记录时必须填写内容**,不能为空值(NULL)。
|
||
|
||
在你的知识图谱数据库设计中:
|
||
|
||
## NOT NULL 字段示例
|
||
|
||
**必须填写的字段:**
|
||
- `knowledge.name` - 知识点名称
|
||
- `problem.content` - 题目内容
|
||
- `student.name` - 学生姓名
|
||
- `learning_record.student_id` - 学生ID
|
||
- `learning_record.problem_id` - 题目ID
|
||
- `learning_record.knowledge_id` - 知识点ID
|
||
- `learning_record.is_correct` - 是否正确
|
||
- `learning_record.max_score` - 满分值
|
||
|
||
## 可以留空的字段:
|
||
- `method_id` - 方法ID(可选,因为有些题目可能不涉及特定方法)
|
||
- `definition` - 定义内容(有些知识点可能不需要详细定义)
|
||
- `common_errors` - 常见错误(可能暂时没有收集到)
|
||
|
||
## 实际效果:
|
||
|
||
```sql
|
||
-- ✅ 正确的插入
|
||
INSERT INTO knowledge (id, name) VALUES ('K1-1-01', '集合的概念');
|
||
|
||
-- ❌ 错误的插入(会报错)
|
||
INSERT INTO knowledge (id) VALUES ('K1-1-02'); -- 缺少name字段
|
||
```
|
||
|
||
这样设计的好处是确保数据的完整性,避免出现"无名知识点"或"无内容题目"等数据质量问题。
|
||
[Timestamp: 2025/11/05 10:36:09]
|
||
|
||
**user**: 那我是否可以填写''
|
||
[Context: Notes: 知识图谱/知识图谱数据库设计.md]
|
||
[Timestamp: 2025/11/05 10:36:14]
|
||
|
||
**ai**: 不可以,`''`(空字符串)和 `NULL` 是不同的概念:
|
||
|
||
## 区别说明:
|
||
|
||
**NULL** - 表示"没有值"或"未知"
|
||
**''** - 表示"空字符串",是一个具体的值
|
||
|
||
## 在数据库中的表现:
|
||
|
||
```sql
|
||
-- 对于 NOT NULL 字段:
|
||
INSERT INTO knowledge (id, name) VALUES ('K1-1-01', ''); -- ✅ 允许
|
||
INSERT INTO knowledge (id, name) VALUES ('K1-1-02', NULL); -- ❌ 报错
|
||
```
|
||
|
||
## 在你的设计中:
|
||
|
||
虽然技术上允许插入空字符串 `''`,但**逻辑上不建议**这样做,因为:
|
||
|
||
1. **knowledge.name = ''** - 知识点名称为空,没有意义
|
||
2. **problem.content = ''** - 题目内容为空,无法做题
|
||
3. **student.name = ''** - 学生姓名为空,无法识别学生
|
||
|
||
## 建议的解决方案:
|
||
|
||
### 1. 应用层验证
|
||
在代码层面检查,确保不插入空字符串:
|
||
```javascript
|
||
if (!name.trim()) {
|
||
throw new Error('知识点名称不能为空');
|
||
}
|
||
```
|
||
|
||
### 2. 数据库约束(推荐)
|
||
添加 CHECK 约束:
|
||
```sql
|
||
CREATE TABLE knowledge (
|
||
id VARCHAR(20) PRIMARY KEY,
|
||
name VARCHAR(100) NOT NULL CHECK (name <> ''),
|
||
-- ... 其他字段
|
||
);
|
||
```
|
||
|
||
### 3. 默认值策略
|
||
对于某些字段可以设置默认值:
|
||
```sql
|
||
type VARCHAR(20) DEFAULT '概念'
|
||
```
|
||
|
||
**总结:** 虽然数据库允许 `''`,但为了数据质量,应该在应用层或数据库层面进行额外验证,确保关键字段既有值又有实际内容。
|
||
[Timestamp: 2025/11/05 10:36:31]
|
||
|
||
**user**: knowledge_mastery 和method_mastery这两个表的设计,是否会有很多的一对多的情况,造成混乱?200个知识点、200个学生,那么就有40000条记录?
|
||
[Context: Notes: 知识图谱/知识图谱数据库设计.md]
|
||
[Timestamp: 2025/11/05 10:43:38]
|
||
|
||
**ai**: 你的担忧很有道理!确实会出现大量记录的情况,但这是**正常且必要的设计**。
|
||
|
||
## 数据量分析
|
||
|
||
- **200个知识点 × 200个学生 = 40,000条记录**
|
||
- **100个方法 × 200个学生 = 20,000条记录**
|
||
|
||
总计约60,000条记录,对于现代数据库来说**完全在可接受范围内**。
|
||
|
||
## 为什么这样设计是合理的?
|
||
|
||
### 1. **数据稀疏性**
|
||
实际上,学生不会同时学习所有知识点:
|
||
- 高一学生:可能只涉及80个知识点
|
||
- 高二学生:可能涉及120个知识点
|
||
- 高三学生:可能涉及150个知识点
|
||
|
||
**实际记录数 ≈ 200 × 平均100个知识点 = 20,000条**
|
||
|
||
### 2. **查询效率优化**
|
||
```sql
|
||
-- 查询某个学生的所有知识点掌握情况(极快)
|
||
SELECT * FROM knowledge_mastery WHERE student_id = 'S001';
|
||
|
||
-- 查询某个知识点的所有学生掌握情况(较快)
|
||
SELECT * FROM knowledge_mastery WHERE knowledge_id = 'K3-1-1-01';
|
||
```
|
||
|
||
### 3. **索引设计保证性能**
|
||
```sql
|
||
-- 复合主键索引
|
||
PRIMARY KEY (student_id, knowledge_id)
|
||
|
||
-- 这样查询时可以直接走索引,性能很好
|
||
```
|
||
|
||
## 替代方案对比
|
||
|
||
### 方案A:当前设计(推荐)
|
||
```sql
|
||
knowledge_mastery (student_id, knowledge_id, mastery_score, ...)
|
||
```
|
||
**优点:**
|
||
- 查询直接,性能好
|
||
- 数据清晰,易于维护
|
||
- 支持复杂的统计分析
|
||
|
||
### 方案B:JSON存储(不推荐)
|
||
```sql
|
||
student_mastery (
|
||
student_id VARCHAR(20) PRIMARY KEY,
|
||
knowledge_scores JSON, -- {"K3-1-1-01": 85, "K3-1-1-02": 72}
|
||
method_scores JSON
|
||
)
|
||
```
|
||
**缺点:**
|
||
- 查询特定知识点需要解析JSON,性能差
|
||
- 难以做跨学生的统计分析
|
||
- 更新单个知识点需要重写整个JSON
|
||
|
||
## 性能优化建议
|
||
|
||
如果确实担心数据量,可以:
|
||
|
||
### 1. **分区表**
|
||
```sql
|
||
-- 按学生ID分区
|
||
PARTITION BY HASH(student_id) PARTITIONS 10;
|
||
```
|
||
|
||
### 2. **定期归档**
|
||
```sql
|
||
-- 归档一年前的历史数据
|
||
CREATE TABLE knowledge_mastery_archive LIKE knowledge_mastery;
|
||
```
|
||
|
||
### 3. **只记录活跃数据**
|
||
```sql
|
||
-- 只记录有学习记录的知识点
|
||
-- 而不是预先为所有学生创建所有知识点的记录
|
||
```
|
||
|
||
## 实际应用场景
|
||
|
||
```sql
|
||
-- 个性化推荐(需要这种结构)
|
||
SELECT km.knowledge_id, k.name
|
||
FROM knowledge_mastery km
|
||
JOIN knowledge k ON km.knowledge_id = k.id
|
||
WHERE km.student_id = 'S001'
|
||
AND km.mastery_score < 60 -- 薄弱知识点
|
||
ORDER BY k.importance DESC
|
||
LIMIT 5;
|
||
```
|
||
|
||
**结论:** 虽然看起来记录数多,但这种"学生-知识点"的矩阵结构是学习分析系统的**标准做法**,数据库能够很好地处理这种规模的数据。
|
||
[Timestamp: 2025/11/05 10:44:10]
|
||
|
||
**user**: [[知识图谱分层方法]] 如果一道题目有多个知识点,那么在学习纪录表中如何记录?
|
||
[Context: Notes: 知识图谱/知识图谱分层方法.md, 知识图谱/知识图谱数据库设计.md]
|
||
[Timestamp: 2025/11/05 10:46:24]
|
||
|
||
**ai**: 是的,这是一个很好的问题!当一道题目有多个知识点时,在 `learning_record` 表中需要**为每个知识点创建一条独立的记录**。
|
||
|
||
## 记录方式示例
|
||
|
||
以题目 `T3-1-1-E02` 为例:
|
||
```sql
|
||
-- 题目:已知函数 f(x)=√(x+3)+1/(x+2)
|
||
-- (1) 求函数的定义域
|
||
-- (2) 求 f(-3), f(2/3) 的值
|
||
-- (3) 当 a≥0 时,求 f(a), f(a-1) 的值
|
||
```
|
||
|
||
### 正确的记录方式:
|
||
|
||
```sql
|
||
-- 学生S001做第(1)小题,涉及多个知识点
|
||
INSERT INTO learning_record (student_id, problem_id, knowledge_id, question_part, is_correct, score, max_score, exam_id)
|
||
VALUES
|
||
('S001', 'T3-1-1-E02', 'K3-1-1-02', '小题1', TRUE, 5, 5, 'EX001'), -- 定义域
|
||
('S001', 'T3-1-1-E02', 'K3-1-1-04', '小题1', TRUE, 5, 5, 'EX001'), -- 区间表示法
|
||
('S001', 'T3-1-1-E02', 'K1-3-01', '小题1', TRUE, 5, 5, 'EX001'); -- 集合的交集
|
||
|
||
-- 学生S001做第(2)小题
|
||
INSERT INTO learning_record (student_id, problem_id, knowledge_id, question_part, is_correct, score, max_score, exam_id)
|
||
VALUES
|
||
('S001', 'T3-1-1-E02', 'K3-1-1-06', '小题2', TRUE, 3, 3, 'EX001'); -- 求函数值
|
||
|
||
-- 学生S001做第(3)小题
|
||
INSERT INTO learning_record (student_id, problem_id, knowledge_id, question_part, is_correct, score, max_score, exam_id)
|
||
VALUES
|
||
('S001', 'T3-1-1-E02', 'K3-1-1-06', '小题3', TRUE, 4, 4, 'EX001'), -- 求函数值
|
||
('S001', 'T3-1-1-E02', 'K3-1-1-07', '小题3', TRUE, 4, 4, 'EX001'); -- 含参数的函数值
|
||
```
|
||
|
||
## 为什么这样设计?
|
||
|
||
### 1. **数据完整性**
|
||
- 每个知识点的掌握情况都被独立记录
|
||
- 可以精确分析学生在每个知识点上的表现
|
||
|
||
### 2. **统计分析**
|
||
```sql
|
||
-- 查询学生在"定义域"知识点上的表现
|
||
SELECT COUNT(*) as 总次数,
|
||
SUM(CASE WHEN is_correct THEN 1 ELSE 0 END) as 正确次数,
|
||
AVG(score/max_score) as 平均得分率
|
||
FROM learning_record
|
||
WHERE student_id = 'S001' AND knowledge_id = 'K3-1-1-02';
|
||
```
|
||
|
||
### 3. **个性化推荐**
|
||
```sql
|
||
-- 找出学生薄弱的知识点
|
||
SELECT knowledge_id,
|
||
AVG(score/max_score) as 掌握度
|
||
FROM learning_record
|
||
WHERE student_id = 'S001'
|
||
GROUP BY knowledge_id
|
||
HAVING 掌握度 < 0.6;
|
||
```
|
||
|
||
## 实际应用场景
|
||
|
||
假设学生做对了第(1)小题但做错了第(2)小题:
|
||
|
||
```sql
|
||
-- 第(1)小题正确
|
||
INSERT INTO learning_record VALUES
|
||
('S001', 'T3-1-1-E02', 'K3-1-1-02', '小题1', TRUE, 5, 5, 'EX001'),
|
||
('S001', 'T3-1-1-E02', 'K3-1-1-04', '小题1', TRUE, 5, 5, 'EX001'),
|
||
('S001', 'T3-1-1-E02', 'K1-3-01', '小题1', TRUE, 5, 5, 'EX001');
|
||
|
||
-- 第(2)小题错误
|
||
INSERT INTO learning_record VALUES
|
||
('S001', 'T3-1-1-E02', 'K3-1-1-06', '小题2', FALSE, 0, 3, 'EX001');
|
||
```
|
||
|
||
这样系统就能准确知道:
|
||
- 学生在"定义域"相关知识点上掌握良好
|
||
- 但在"求函数值"知识点上存在问题
|
||
|
||
## 总结
|
||
|
||
**多知识点题目的记录原则:**
|
||
- 每个知识点创建一条独立记录
|
||
- 相同的 `student_id`、`problem_id`、`question_part`
|
||
- 不同的 `knowledge_id`
|
||
- 相同的得分和满分(因为得分是针对整个小题的)
|
||
|
||
这种设计虽然会增加记录数量,但为后续的精准分析和个性化推荐提供了完整的数据基础。
|
||
[Timestamp: 2025/11/05 10:47:11]
|
||
|
||
**user**: 基于数据库表和 [[知识图谱分层方法]] 请给我写一个项目设计概要,用于给项目开发人员开发后端应用使用
|
||
[Context: Notes: 知识图谱/知识图谱分层方法.md, 知识图谱/知识图谱数据库设计.md]
|
||
[Timestamp: 2025/11/05 10:48:54]
|
||
|
||
**ai**: # 高中数学知识图谱系统 - 后端项目设计概要
|
||
|
||
## 项目概述
|
||
|
||
基于三层架构(Knowledge-Method-Problem)的高中数学知识图谱系统,结合学生个性化学习评分功能,为开发团队提供完整的后端技术方案。
|
||
|
||
---
|
||
|
||
## 一、系统架构设计
|
||
|
||
### 1.1 整体架构
|
||
```
|
||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||
│ 前端应用层 │ │ 后端API层 │ │ 数据存储层 │
|
||
│ (Web/Mobile) │◄──►│ (RESTful API) │◄──►│ (MySQL/Redis) │
|
||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||
│
|
||
┌─────────────────┐
|
||
│ 业务逻辑层 │
|
||
│ (Service层) │
|
||
└─────────────────┘
|
||
│
|
||
┌─────────────────┐
|
||
│ 数据访问层 │
|
||
│ (DAO/ORM) │
|
||
└─────────────────┘
|
||
```
|
||
|
||
### 1.2 技术栈推荐
|
||
- **后端框架**: Spring Boot 3.x / Node.js + Express
|
||
- **数据库**: MySQL 8.0 + Redis
|
||
- **ORM**: MyBatis / Sequelize
|
||
- **API文档**: Swagger/OpenAPI 3.0
|
||
- **任务调度**: Quartz / node-cron
|
||
- **缓存**: Redis
|
||
- **部署**: Docker + Kubernetes
|
||
|
||
---
|
||
|
||
## 二、数据库设计(7张核心表)
|
||
|
||
### 2.1 知识图谱相关表
|
||
|
||
#### **knowledge(知识点表)**
|
||
```sql
|
||
CREATE TABLE knowledge (
|
||
id VARCHAR(20) PRIMARY KEY, -- K3-1-1-01
|
||
name VARCHAR(100) NOT NULL, -- 函数的三要素
|
||
type VARCHAR(20), -- 概念/定理/公式
|
||
definition TEXT, -- 定义内容
|
||
core_features JSON, -- ["任意性", "唯一性"]
|
||
prerequisites JSON, -- ["K1-1-01", "K1-2-01"]
|
||
importance VARCHAR(10), -- 核心/重要/基础
|
||
textbook_location VARCHAR(100), -- 必修1 P62
|
||
created_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
```
|
||
|
||
#### **method(方法表)**
|
||
```sql
|
||
CREATE TABLE method (
|
||
id VARCHAR(20) PRIMARY KEY, -- M3-1-1-01
|
||
name VARCHAR(100) NOT NULL, -- 分式型定义域求解法
|
||
type VARCHAR(20), -- 解题方法/计算技巧
|
||
scenario VARCHAR(200), -- 适用场景
|
||
steps JSON, -- ["识别分母", "令≠0", ...]
|
||
supported_knowledge JSON, -- ["K3-1-1-02"]
|
||
common_errors JSON, -- ["遗漏分母"]
|
||
difficulty_level INT, -- 1-5
|
||
created_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
```
|
||
|
||
#### **problem(题目表)**
|
||
```sql
|
||
CREATE TABLE problem (
|
||
id VARCHAR(20) PRIMARY KEY, -- T3-1-1-E02
|
||
problem_type VARCHAR(20), -- 例题/练习题/习题
|
||
content TEXT NOT NULL, -- 完整题目内容
|
||
knowledge_mapping JSON, -- {"小题1": ["K3-1-1-02"], ...}
|
||
method_mapping JSON, -- {"小题1": ["M3-1-1-01"], ...}
|
||
problem_category VARCHAR(50), -- 函数基础
|
||
difficulty INT, -- 1-5
|
||
source VARCHAR(100), -- 必修1 P65 例2
|
||
created_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
```
|
||
|
||
### 2.2 学生评分相关表
|
||
|
||
#### **student(学生表)**
|
||
```sql
|
||
CREATE TABLE student (
|
||
id VARCHAR(20) PRIMARY KEY, -- S001
|
||
name VARCHAR(50) NOT NULL,
|
||
grade VARCHAR(10), -- 高一/高二/高三
|
||
created_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
```
|
||
|
||
#### **learning_record(学习记录表 - 核心流水表)**
|
||
```sql
|
||
CREATE TABLE learning_record (
|
||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||
student_id VARCHAR(20) NOT NULL,
|
||
problem_id VARCHAR(20) NOT NULL, -- T3-1-1-E02
|
||
knowledge_id VARCHAR(20) NOT NULL, -- K3-1-1-02
|
||
method_id VARCHAR(20), -- M3-1-1-01 (可选)
|
||
question_part VARCHAR(10), -- 小题1/小题2/整体
|
||
is_correct BOOLEAN NOT NULL, -- 正确/错误
|
||
score DECIMAL(5,2), -- 得分(0-100)
|
||
max_score DECIMAL(5,2) NOT NULL, -- 该题/该小题的满分
|
||
exam_id VARCHAR(20) NOT NULL, -- 该场考试的id或名称
|
||
exam_date DATE, -- 考试/练习日期
|
||
created_at TIMESTAMP DEFAULT NOW(),
|
||
|
||
FOREIGN KEY (student_id) REFERENCES student(id),
|
||
FOREIGN KEY (problem_id) REFERENCES problem(id),
|
||
FOREIGN KEY (knowledge_id) REFERENCES knowledge(id),
|
||
FOREIGN KEY (method_id) REFERENCES method(id)
|
||
);
|
||
```
|
||
|
||
#### **knowledge_mastery(知识点掌握度表)**
|
||
```sql
|
||
CREATE TABLE knowledge_mastery (
|
||
student_id VARCHAR(20),
|
||
knowledge_id VARCHAR(20),
|
||
mastery_score DECIMAL(5,2) DEFAULT 100.0, -- 掌握度分数(0-100)
|
||
total_attempts INT DEFAULT 0, -- 总尝试次数
|
||
correct_attempts INT DEFAULT 0, -- 正确次数
|
||
avg_response_time DECIMAL(8,2), -- 平均答题时间
|
||
last_practiced DATE, -- 最后练习日期
|
||
confidence_level DECIMAL(3,2), -- 置信度(0-1)
|
||
updated_at TIMESTAMP DEFAULT NOW(),
|
||
|
||
PRIMARY KEY (student_id, knowledge_id),
|
||
FOREIGN KEY (student_id) REFERENCES student(id),
|
||
FOREIGN KEY (knowledge_id) REFERENCES knowledge(id)
|
||
);
|
||
```
|
||
|
||
#### **method_mastery(方法掌握度表)**
|
||
```sql
|
||
CREATE TABLE method_mastery (
|
||
student_id VARCHAR(20),
|
||
method_id VARCHAR(20),
|
||
mastery_score DECIMAL(5,2) DEFAULT 100.0,
|
||
total_usage INT DEFAULT 0, -- 总使用次数
|
||
successful_usage INT DEFAULT 0, -- 成功使用次数
|
||
updated_at TIMESTAMP DEFAULT NOW(),
|
||
|
||
PRIMARY KEY (student_id, method_id),
|
||
FOREIGN KEY (student_id) REFERENCES student(id),
|
||
FOREIGN KEY (method_id) REFERENCES method(id)
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## 三、API接口设计
|
||
|
||
### 3.1 知识图谱管理API
|
||
|
||
#### **知识点管理**
|
||
```http
|
||
GET /api/knowledge # 获取知识点列表
|
||
POST /api/knowledge # 创建知识点
|
||
GET /api/knowledge/{id} # 获取知识点详情
|
||
PUT /api/knowledge/{id} # 更新知识点
|
||
DELETE /api/knowledge/{id} # 删除知识点
|
||
GET /api/knowledge/{id}/prerequisites # 获取前置知识点
|
||
GET /api/knowledge/{id}/related-problems # 获取相关题目
|
||
```
|
||
|
||
#### **方法管理**
|
||
```http
|
||
GET /api/methods # 获取方法列表
|
||
POST /api/methods # 创建方法
|
||
GET /api/methods/{id} # 获取方法详情
|
||
PUT /api/methods/{id} # 更新方法
|
||
GET /api/methods/{id}/applicable-problems # 获取适用题目
|
||
```
|
||
|
||
#### **题目管理**
|
||
```http
|
||
GET /api/problems # 获取题目列表(支持筛选)
|
||
POST /api/problems # 创建题目
|
||
GET /api/problems/{id} # 获取题目详情
|
||
PUT /api/problems/{id} # 更新题目
|
||
GET /api/problems/recommendations # 个性化题目推荐
|
||
```
|
||
|
||
### 3.2 学习记录API
|
||
|
||
#### **答题记录**
|
||
```http
|
||
POST /api/learning-records # 提交答题记录
|
||
GET /api/students/{id}/learning-records # 获取学生学习记录
|
||
GET /api/learning-records/statistics # 学习统计
|
||
```
|
||
|
||
#### **批量记录处理**
|
||
```http
|
||
POST /api/learning-records/batch # 批量提交答题记录
|
||
```
|
||
|
||
### 3.3 掌握度分析API
|
||
|
||
#### **知识点掌握度**
|
||
```http
|
||
GET /api/students/{id}/knowledge-mastery # 获取知识点掌握情况
|
||
GET /api/students/{id}/weak-knowledge # 获取薄弱知识点
|
||
GET /api/knowledge/{id}/student-mastery # 获取知识点学生掌握情况
|
||
```
|
||
|
||
#### **方法掌握度**
|
||
```http
|
||
GET /api/students/{id}/method-mastery # 获取方法掌握情况
|
||
```
|
||
|
||
### 3.4 个性化推荐API
|
||
|
||
#### **题目推荐**
|
||
```http
|
||
GET /api/students/{id}/recommendations/problems # 推荐题目
|
||
GET /api/students/{id}/recommendations/knowledge # 推荐知识点
|
||
GET /api/students/{id}/learning-path # 学习路径规划
|
||
```
|
||
|
||
---
|
||
|
||
## 四、核心业务逻辑
|
||
|
||
### 4.1 掌握度计算服务
|
||
|
||
```java
|
||
@Service
|
||
public class MasteryCalculationService {
|
||
|
||
/**
|
||
* 计算知识点掌握度
|
||
*/
|
||
public BigDecimal calculateKnowledgeMastery(String studentId, String knowledgeId) {
|
||
// 基于学习记录计算掌握度分数
|
||
// 考虑因素:正确率、答题次数、最近表现等
|
||
}
|
||
|
||
/**
|
||
* 批量更新掌握度
|
||
*/
|
||
@Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点执行
|
||
public void batchUpdateMastery() {
|
||
// 批量更新所有学生的知识点和方法掌握度
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4.2 个性化推荐引擎
|
||
|
||
```java
|
||
@Service
|
||
public class RecommendationService {
|
||
|
||
/**
|
||
* 基于掌握度推荐题目
|
||
*/
|
||
public List<Problem> recommendProblems(String studentId, int count) {
|
||
// 1. 获取学生薄弱知识点
|
||
// 2. 基于知识点关联度推荐题目
|
||
// 3. 考虑题目难度梯度
|
||
// 4. 避免重复推荐
|
||
}
|
||
|
||
/**
|
||
* 学习路径规划
|
||
*/
|
||
public LearningPath generateLearningPath(String studentId, String targetKnowledgeId) {
|
||
// 基于知识图谱的前置关系规划学习路径
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4.3 数据统计服务
|
||
|
||
```java
|
||
@Service
|
||
public class StatisticsService {
|
||
|
||
/**
|
||
* 学习进度统计
|
||
*/
|
||
public LearningProgress getLearningProgress(String studentId) {
|
||
// 统计已学习知识点、掌握程度、学习时长等
|
||
}
|
||
|
||
/**
|
||
* 班级统计分析
|
||
*/
|
||
public ClassStatistics getClassStatistics(String classId) {
|
||
// 班级整体掌握情况、薄弱环节分析
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 五、数据流与定时任务
|
||
|
||
### 5.1 数据流向
|
||
```
|
||
学生答题 → learning_record (实时记录)
|
||
↓
|
||
定时任务 → knowledge_mastery (每日汇总)
|
||
↓
|
||
推荐引擎 → 个性化推荐 (实时计算)
|
||
```
|
||
|
||
### 5.2 定时任务配置
|
||
|
||
```yaml
|
||
# 定时任务配置
|
||
scheduled-tasks:
|
||
mastery-calculation:
|
||
cron: "0 0 2 * * ?" # 每天凌晨2点
|
||
description: "计算学生掌握度"
|
||
|
||
data-backup:
|
||
cron: "0 0 4 * * ?" # 每天凌晨4点
|
||
description: "数据备份"
|
||
|
||
cache-refresh:
|
||
cron: "0 */30 * * * ?" # 每30分钟
|
||
description: "刷新缓存"
|
||
```
|
||
|
||
---
|
||
|
||
## 六、性能优化策略
|
||
|
||
### 6.1 数据库优化
|
||
- **索引设计**: 为所有外键和查询字段建立索引
|
||
- **分区表**: 对learning_record按时间分区
|
||
- **读写分离**: 主从数据库配置
|
||
|
||
### 6.2 缓存策略
|
||
```java
|
||
@Service
|
||
@CacheConfig(cacheNames = "knowledge")
|
||
public class KnowledgeService {
|
||
|
||
@Cacheable(key = "#id")
|
||
public Knowledge getKnowledge(String id) {
|
||
// 获取知识点,自动缓存
|
||
}
|
||
|
||
@CacheEvict(key = "#id")
|
||
public void updateKnowledge(String id, Knowledge knowledge) {
|
||
// 更新知识点,清除缓存
|
||
}
|
||
}
|
||
```
|
||
|
||
### 6.3 异步处理
|
||
```java
|
||
@Async
|
||
public void processLearningRecord(LearningRecord record) {
|
||
// 异步处理学习记录,不影响用户响应
|
||
masteryCalculationService.updateMastery(record);
|
||
recommendationService.updateRecommendations(record.getStudentId());
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 七、安全与权限设计
|
||
|
||
### 7.1 权限控制
|
||
```java
|
||
@PreAuthorize("hasRole('TEACHER') or #studentId == authentication.principal.id")
|
||
public StudentProgress getStudentProgress(String studentId) {
|
||
// 学生只能查看自己的进度,教师可以查看所有
|
||
}
|
||
```
|
||
|
||
### 7.2 数据验证
|
||
```java
|
||
@Validated
|
||
public class LearningRecordDTO {
|
||
@NotNull
|
||
private String studentId;
|
||
|
||
@NotNull
|
||
private String problemId;
|
||
|
||
@Min(0)
|
||
@Max(100)
|
||
private BigDecimal score;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 八、部署与监控
|
||
|
||
### 8.1 部署架构
|
||
```
|
||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||
│ Load Balancer │───►│ API Servers │───►│ MySQL Cluster │
|
||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||
│ │
|
||
┌─────────────────┐ ┌─────────────────┐
|
||
│ Redis Cluster │ │ File Storage │
|
||
└─────────────────┘ └─────────────────┘
|
||
```
|
||
|
||
### 8.2 监控指标
|
||
- **应用性能**: QPS、响应时间、错误率
|
||
- **数据库**: 连接数、慢查询、锁等待
|
||
- **业务指标**: 日活跃用户、题目完成率、掌握度分布
|
||
|
||
---
|
||
|
||
## 九、开发里程碑
|
||
|
||
### Phase 1: 基础功能 (4周)
|
||
- [ ] 数据库表结构创建
|
||
- [ ] 基础CRUD API
|
||
- [ ] 学习记录录入
|
||
- [ ] 基础掌握度计算
|
||
|
||
### Phase 2: 核心业务 (6周)
|
||
- [ ] 个性化推荐引擎
|
||
- [ ] 学习路径规划
|
||
- [ ] 数据统计分析
|
||
- [ ] 缓存和性能优化
|
||
|
||
### Phase 3: 高级功能 (4周)
|
||
- [ ] 批量数据处理
|
||
- [ ] 报表导出
|
||
- [ ] 系统监控
|
||
- [ ] 压力测试
|
||
|
||
---
|
||
|
||
## 十、技术风险与应对
|
||
|
||
### 10.1 数据量风险
|
||
- **风险**: learning_record表数据量快速增长
|
||
- **应对**: 分区表、归档策略、读写分离
|
||
|
||
### 10.2 计算复杂度
|
||
- **风险**: 实时推荐计算资源消耗大
|
||
- **应对**: 缓存策略、异步计算、定时预计算
|
||
|
||
### 10.3 数据一致性
|
||
- **风险**: 掌握度数据与学习记录不一致
|
||
- **应对**: 事务控制、数据校验、定期修复任务
|
||
|
||
---
|
||
|
||
**此设计概要为开发团队提供了完整的技术方案,可直接用于项目开发。** 🚀
|
||
[Timestamp: 2025/11/05 10:51:22] |