1. 首页 > DB2教程 > 正文

DB2教程FG057-DB2教育系统库设计实战

风哥教程参考DB2官方文档Education Solutions、Data Management等内容,详细介绍教育系统库在DB2上的设计、学生管理、课程安排、成绩分析。更多视频教程www.fgedu.net.cn

目录大纲

Part01-教育系统特点

1.1 教育业务特点

教育系统具有以下特点:

  • 数据量大:学生、课程、成绩数据量大
  • 学期周期:按学期管理数据
  • 复杂关联:学生、课程、教师、成绩多层关联
  • 统计分析:成绩分析、排名、报表
  • 安全性:学生数据需要保护
  • 并发选课:选课期间并发量高

Part02-核心表结构设计

2.1 学生表设计

# 学生表
CREATE TABLE STUDENT (
STUDENT_ID VARCHAR(32) NOT NULL,
STUDENT_NO VARCHAR(50) NOT NULL,
NAME VARCHAR(100) NOT NULL,
GENDER VARCHAR(10),
BIRTH_DATE DATE,
ID_CARD VARCHAR(18),
NATIONALITY VARCHAR(50),
ETHNICITY VARCHAR(50),
POLITICAL_STATUS VARCHAR(20),
ADDRESS VARCHAR(500),
PHONE VARCHAR(20),
EMAIL VARCHAR(100),
GRADE VARCHAR(20),
CLASS_ID VARCHAR(20),
MAJOR_ID VARCHAR(20),
DEPT_ID VARCHAR(20),
ENROLL_DATE DATE,
GRADUATE_DATE DATE,
STUDENT_STATUS VARCHAR(10) NOT NULL,
CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
UPDATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
CONSTRAINT PK_STUDENT PRIMARY KEY (STUDENT_ID)
) ORGANIZE BY ROW;

# 教师表
CREATE TABLE TEACHER (
TEACHER_ID VARCHAR(32) NOT NULL,
TEACHER_NO VARCHAR(50) NOT NULL,
NAME VARCHAR(100) NOT NULL,
GENDER VARCHAR(10),
BIRTH_DATE DATE,
ID_CARD VARCHAR(18),
TITLE VARCHAR(50),
DEGREE VARCHAR(20),
DEPT_ID VARCHAR(20),
PHONE VARCHAR(20),
EMAIL VARCHAR(100),
TEACHER_STATUS VARCHAR(10) NOT NULL,
CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
UPDATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
CONSTRAINT PK_TEACHER PRIMARY KEY (TEACHER_ID)
) ORGANIZE BY ROW;

# 课程表
CREATE TABLE COURSE (
COURSE_ID VARCHAR(32) NOT NULL,
COURSE_CODE VARCHAR(50) NOT NULL,
COURSE_NAME VARCHAR(200) NOT NULL,
COURSE_TYPE VARCHAR(20),
CREDITS DECIMAL(3, 1),
HOURS INTEGER,
DEPT_ID VARCHAR(20),
COURSE_DESC CLOB,
COURSE_STATUS VARCHAR(10) NOT NULL,
CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
UPDATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
CONSTRAINT PK_COURSE PRIMARY KEY (COURSE_ID)
) ORGANIZE BY ROW;

# 创建索引
CREATE UNIQUE INDEX IDX_STUDENT_NO ON STUDENT(STUDENT_NO);
CREATE INDEX IDX_STUDENT_CLASS ON STUDENT(CLASS_ID, STUDENT_STATUS);
CREATE INDEX IDX_STUDENT_DEPT ON STUDENT(DEPT_ID, STUDENT_STATUS);
CREATE UNIQUE INDEX IDX_TEACHER_NO ON TEACHER(TEACHER_NO);
CREATE UNIQUE INDEX IDX_COURSE_CODE ON COURSE(COURSE_CODE);
CREATE INDEX IDX_COURSE_DEPT ON COURSE(DEPT_ID, COURSE_STATUS);

2.2 班级与专业表

# 院系表
CREATE TABLE DEPARTMENT (
DEPT_ID VARCHAR(20) NOT NULL,
DEPT_CODE VARCHAR(20) NOT NULL,
DEPT_NAME VARCHAR(100) NOT NULL,
PARENT_DEPT_ID VARCHAR(20),
DEPT_LEVEL INTEGER,
DEPT_TYPE VARCHAR(20),
DEPT_STATUS VARCHAR(10) NOT NULL,
CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
UPDATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
CONSTRAINT PK_DEPARTMENT PRIMARY KEY (DEPT_ID)
) ORGANIZE BY ROW;

# 专业表
CREATE TABLE MAJOR (
MAJOR_ID VARCHAR(20) NOT NULL,
MAJOR_CODE VARCHAR(20) NOT NULL,
MAJOR_NAME VARCHAR(100) NOT NULL,
DEPT_ID VARCHAR(20) NOT NULL,
MAJOR_DESC VARCHAR(500),
MAJOR_STATUS VARCHAR(10) NOT NULL,
CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
UPDATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
CONSTRAINT PK_MAJOR PRIMARY KEY (MAJOR_ID)
) ORGANIZE BY ROW;

# 班级表
CREATE TABLE CLASS (
CLASS_ID VARCHAR(20) NOT NULL,
CLASS_CODE VARCHAR(20) NOT NULL,
CLASS_NAME VARCHAR(100) NOT NULL,
GRADE VARCHAR(20),
MAJOR_ID VARCHAR(20),
DEPT_ID VARCHAR(20),
HEAD_TEACHER_ID VARCHAR(32),
CLASS_STATUS VARCHAR(10) NOT NULL,
CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
UPDATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
CONSTRAINT PK_CLASS PRIMARY KEY (CLASS_ID)
) ORGANIZE BY ROW;

# 创建索引
CREATE UNIQUE INDEX IDX_DEPT_CODE ON DEPARTMENT(DEPT_CODE);
CREATE UNIQUE INDEX IDX_MAJOR_CODE ON MAJOR(MAJOR_CODE);
CREATE INDEX IDX_MAJOR_DEPT ON MAJOR(DEPT_ID, MAJOR_STATUS);
CREATE UNIQUE INDEX IDX_CLASS_CODE ON CLASS(CLASS_CODE);
CREATE INDEX IDX_CLASS_MAJOR ON CLASS(MAJOR_ID, CLASS_STATUS);

Part03-选课与排课

3.1 排课表设计

# 学期表
CREATE TABLE SEMESTER (
SEMESTER_ID VARCHAR(20) NOT NULL,
SEMESTER_CODE VARCHAR(20) NOT NULL,
SEMESTER_NAME VARCHAR(100) NOT NULL,
START_DATE DATE NOT NULL,
END_DATE DATE NOT NULL,
SEMESTER_STATUS VARCHAR(10) NOT NULL,
CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
UPDATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
CONSTRAINT PK_SEMESTER PRIMARY KEY (SEMESTER_ID)
) ORGANIZE BY ROW;

# 开课表
CREATE TABLE COURSE_OFFERING (
OFFERING_ID VARCHAR(32) NOT NULL,
COURSE_ID VARCHAR(32) NOT NULL,
TEACHER_ID VARCHAR(32),
SEMESTER_ID VARCHAR(20) NOT NULL,
CLASS_TIME VARCHAR(200),
CLASSROOM VARCHAR(100),
MAX_STUDENTS INTEGER,
ENROLLED_COUNT INTEGER DEFAULT 0,
OFFERING_STATUS VARCHAR(10) NOT NULL,
CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
UPDATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
CONSTRAINT PK_COURSE_OFFERING PRIMARY KEY (OFFERING_ID)
) ORGANIZE BY ROW;

# 选课表
CREATE TABLE COURSE_SELECTION (
SELECTION_ID VARCHAR(32) NOT NULL,
STUDENT_ID VARCHAR(32) NOT NULL,
OFFERING_ID VARCHAR(32) NOT NULL,
SELECTION_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
SELECTION_STATUS VARCHAR(10) NOT NULL,
CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
CONSTRAINT PK_COURSE_SELECTION PRIMARY KEY (SELECTION_ID)
) ORGANIZE BY ROW;

# 创建索引
CREATE UNIQUE INDEX IDX_SEMESTER_CODE ON SEMESTER(SEMESTER_CODE);
CREATE INDEX IDX_COURSE_OFFERING_COURSE ON COURSE_OFFERING(COURSE_ID, SEMESTER_ID);
CREATE INDEX IDX_COURSE_OFFERING_TEACHER ON COURSE_OFFERING(TEACHER_ID, SEMESTER_ID);
CREATE UNIQUE INDEX IDX_COURSE_SELECTION_STUDENT ON COURSE_SELECTION(STUDENT_ID, OFFERING_ID);
CREATE INDEX IDX_COURSE_SELECTION_OFFERING ON COURSE_SELECTION(OFFERING_ID);

3.2 选课存储过程

# 选课存储过程
CREATE OR REPLACE PROCEDURE SP_SELECT_COURSE(
IN p_student_id VARCHAR(32),
IN p_offering_id VARCHAR(32),
OUT p_result_code VARCHAR(10),
OUT p_result_msg VARCHAR(200)
)
LANGUAGE SQL
BEGIN
DECLARE v_max_students INTEGER;
DECLARE v_enrolled_count INTEGER;
DECLARE v_count INTEGER;

SET p_result_code = ‘SUCCESS’;
SET p_result_msg = ‘选课成功’;

SELECT MAX_STUDENTS, ENROLLED_COUNT INTO v_max_students, v_enrolled_count
FROM COURSE_OFFERING
WHERE OFFERING_ID = p_offering_id
WITH RS USE AND KEEP UPDATE LOCKS;

SELECT COUNT(*) INTO v_count
FROM COURSE_SELECTION
WHERE STUDENT_ID = p_student_id AND OFFERING_ID = p_offering_id;

IF v_count > 0 THEN
SET p_result_code = ‘FAIL’;
SET p_result_msg = ‘已选择该课程’;
RETURN;
END IF;

IF v_enrolled_count >= v_max_students THEN
SET p_result_code = ‘FAIL’;
SET p_result_msg = ‘课程人数已满’;
RETURN;
END IF;

INSERT INTO COURSE_SELECTION (
SELECTION_ID, STUDENT_ID, OFFERING_ID, SELECTION_STATUS
) VALUES (
‘SEL’ || TO_CHAR(CURRENT TIMESTAMP, ‘YYYYMMDDHH24MISSFF6’),
p_student_id,
p_offering_id,
‘SELECTED’
);

UPDATE COURSE_OFFERING
SET ENROLLED_COUNT = ENROLLED_COUNT + 1,
UPDATE_TIME = CURRENT TIMESTAMP
WHERE OFFERING_ID = p_offering_id;

END;

# 退课存储过程
CREATE OR REPLACE PROCEDURE SP_DROP_COURSE(
IN p_student_id VARCHAR(32),
IN p_offering_id VARCHAR(32),
OUT p_result_code VARCHAR(10),
OUT p_result_msg VARCHAR(200)
)
LANGUAGE SQL
BEGIN
DECLARE v_count INTEGER;

SET p_result_code = ‘SUCCESS’;
SET p_result_msg = ‘退课成功’;

SELECT COUNT(*) INTO v_count
FROM COURSE_SELECTION
WHERE STUDENT_ID = p_student_id AND OFFERING_ID = p_offering_id;

IF v_count = 0 THEN
SET p_result_code = ‘FAIL’;
SET p_result_msg = ‘未选择该课程’;
RETURN;
END IF;

DELETE FROM COURSE_SELECTION
WHERE STUDENT_ID = p_student_id AND OFFERING_ID = p_offering_id;

UPDATE COURSE_OFFERING
SET ENROLLED_COUNT = ENROLLED_COUNT – 1,
UPDATE_TIME = CURRENT TIMESTAMP
WHERE OFFERING_ID = p_offering_id;

END;

Part04-成绩与分析

4.1 成绩表设计

# 成绩表
CREATE TABLE SCORE (
SCORE_ID VARCHAR(32) NOT NULL,
STUDENT_ID VARCHAR(32) NOT NULL,
OFFERING_ID VARCHAR(32) NOT NULL,
USUAL_SCORE DECIMAL(5, 2),
MIDTERM_SCORE DECIMAL(5, 2),
FINAL_SCORE DECIMAL(5, 2),
TOTAL_SCORE DECIMAL(5, 2) NOT NULL,
GRADE VARCHAR(10),
GPA DECIMAL(3, 2),
SCORE_STATUS VARCHAR(10) NOT NULL,
CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
UPDATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
CONSTRAINT PK_SCORE PRIMARY KEY (SCORE_ID)
) ORGANIZE BY ROW;

# 创建索引
CREATE UNIQUE INDEX IDX_SCORE_STUDENT_OFFERING ON SCORE(STUDENT_ID, OFFERING_ID);
CREATE INDEX IDX_SCORE_OFFERING ON SCORE(OFFERING_ID);

# 成绩统计MQT
CREATE TABLE MQT_SCORE_STAT AS (
SELECT
OFFERING_ID,
COUNT(*) AS STUDENT_COUNT,
MIN(TOTAL_SCORE) AS MIN_SCORE,
MAX(TOTAL_SCORE) AS MAX_SCORE,
AVG(TOTAL_SCORE) AS AVG_SCORE,
STDDEV(TOTAL_SCORE) AS STDDEV_SCORE
FROM SCORE
GROUP BY OFFERING_ID
) DATA INITIALLY DEFERRED REFRESH DEFERRED;

REFRESH TABLE MQT_SCORE_STAT;

# 学生成绩查询
SELECT
s.STUDENT_ID,
s.STUDENT_NO,
s.NAME,
c.COURSE_NAME,
t.NAME AS TEACHER_NAME,
sc.TOTAL_SCORE,
sc.GRADE,
sc.GPA
FROM SCORE sc
INNER JOIN STUDENT s ON sc.STUDENT_ID = s.STUDENT_ID
INNER JOIN COURSE_OFFERING o ON sc.OFFERING_ID = o.OFFERING_ID
INNER JOIN COURSE c ON o.COURSE_ID = c.COURSE_ID
LEFT JOIN TEACHER t ON o.TEACHER_ID = t.TEACHER_ID
WHERE s.STUDENT_ID = ‘S001’
ORDER BY c.COURSE_NAME;

# 课程成绩排名
SELECT
s.STUDENT_ID,
s.STUDENT_NO,
s.NAME,
sc.TOTAL_SCORE,
RANK() OVER (ORDER BY sc.TOTAL_SCORE DESC) AS RANK
FROM SCORE sc
INNER JOIN STUDENT s ON sc.STUDENT_ID = s.STUDENT_ID
WHERE sc.OFFERING_ID = ‘O001’
ORDER BY RANK;

# 班级成绩统计
SELECT
c.CLASS_ID,
c.CLASS_NAME,
COUNT(*) AS STUDENT_COUNT,
AVG(sc.TOTAL_SCORE) AS AVG_SCORE,
MIN(sc.TOTAL_SCORE) AS MIN_SCORE,
MAX(sc.TOTAL_SCORE) AS MAX_SCORE
FROM SCORE sc
INNER JOIN STUDENT s ON sc.STUDENT_ID = s.STUDENT_ID
INNER JOIN CLASS c ON s.CLASS_ID = c.CLASS_ID
WHERE sc.OFFERING_ID = ‘O001’
GROUP BY c.CLASS_ID, c.CLASS_NAME
ORDER BY AVG_SCORE DESC;

Part05-风哥经验总结与分享

5.1 教育库设计要点

  • 按学期管理课程和成绩
  • 选课操作要加锁防止冲突
  • 学生、课程、教师关联要合理
  • 成绩统计使用MQT预计算
  • 学生数据要注意隐私保护
  • 选课期间要优化并发性能

5.2 性能优化建议

场景 优化方案
选课操作 行级锁,短事务
成绩查询 学生+课程索引,合理分区
成绩统计 MQT预计算,定期刷新
历史数据 按学期归档,分表存储

5.3 运维要点

  • 选课期间做好性能监控
  • 定期RUNSTATS和REORG
  • 完善的备份和恢复方案
  • 学生数据要加密保护
  • 按学期归档历史数据
  • 建立成绩修改审计日志
更多视频教程www.fgedu.net.cn
学习交流加群风哥微信: itpux-com
风哥Oracle/MySQL/PostgreSQL/Greenplum/DB2/Redis等数据库培训课程,10年一线实战经验,企业级培训,真正掌握数据库核心技术!

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息