Files
K12Study/docs/architecture/modules/01-课程学习/er图.drawio

113 lines
13 KiB
Plaintext
Raw Normal View History

2026-04-16 11:30:30 +08:00
<mxfile host="65bd71144e">
<diagram id="course-er" name="ER图">
<mxGraphModel dx="1312" dy="773" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1800" pageHeight="1200" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="2" value="01 课程学习 - ER图含知识点掌握与图谱/向量同步关联)" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=22;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="20" y="20" width="360" height="30" as="geometry"/>
</mxCell>
<mxCell id="3" value="课程主数据 + 学习过程数据分层;业务主库为 PostgreSQL知识检索能力由 Milvus + NebulaGraph/Neo4j 承担" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#666666;" parent="1" vertex="1">
<mxGeometry x="20" y="52" width="1100" height="24" as="geometry"/>
</mxCell>
<mxCell id="10" value="cl_course&lt;br&gt;PK course_id&lt;br&gt;title, subject_code, grade_code&lt;br&gt;difficulty_level, status&lt;br&gt;tenant_id, adcode, created_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="50" y="130" width="250" height="130" as="geometry"/>
</mxCell>
<mxCell id="12" value="cl_course_lesson&lt;br&gt;PK lesson_id&lt;br&gt;FK chapter_id -&gt; cl_course_chapter.chapter_id&lt;br&gt;lesson_no, lesson_title, duration_sec&lt;br&gt;tenant_id, created_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="650" y="300" width="270" height="130" as="geometry"/>
</mxCell>
<mxCell id="13" value="cl_knowledge_point&lt;br&gt;PK kp_id&lt;br&gt;kp_code, kp_name, subject_code, grade_code&lt;br&gt;tenant_id, created_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1">
<mxGeometry x="1030" y="10" width="260" height="120" as="geometry"/>
</mxCell>
<mxCell id="14" value="cl_course_knowledge_rel&lt;br&gt;PK (course_id, kp_id)&lt;br&gt;FK course_id -&gt; cl_course.course_id&lt;br&gt;FK kp_id -&gt; cl_knowledge_point.kp_id&lt;br&gt;weight, tenant_id" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="1680" y="190" width="280" height="130" as="geometry"/>
</mxCell>
<mxCell id="15" value="cl_course_resource&lt;br&gt;PK resource_id&lt;br&gt;FK lesson_id -&gt; cl_course_lesson.lesson_id&lt;br&gt;resource_type(pdf/video/doc), resource_url&lt;br&gt;tenant_id, created_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="640" y="560" width="290" height="130" as="geometry"/>
</mxCell>
<mxCell id="16" value="cl_course_tag&lt;br&gt;PK tag_id&lt;br&gt;tag_name, tag_type&lt;br&gt;tenant_id, created_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1">
<mxGeometry x="50" y="420" width="230" height="110" as="geometry"/>
</mxCell>
<mxCell id="17" value="cl_course_tag_rel&lt;br&gt;PK (course_id, tag_id)&lt;br&gt;FK course_id -&gt; cl_course.course_id&lt;br&gt;FK tag_id -&gt; cl_course_tag.tag_id&lt;br&gt;tenant_id" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="330" y="410" width="270" height="120" as="geometry"/>
</mxCell>
<mxCell id="18" value="cl_learning_session&lt;br&gt;PK session_id&lt;br&gt;FK user_id -&gt; tb_sys_user.user_id&lt;br&gt;FK course_id -&gt; cl_course.course_id&lt;br&gt;status(STARTED/PAUSED/COMPLETED)&lt;br&gt;started_at, ended_at, tenant_id" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="950" y="450" width="300" height="140" as="geometry"/>
</mxCell>
<mxCell id="19" value="cl_learning_progress&lt;br&gt;PK progress_id&lt;br&gt;FK session_id -&gt; cl_learning_session.session_id&lt;br&gt;FK lesson_id -&gt; cl_course_lesson.lesson_id&lt;br&gt;progress_pct, last_position_sec&lt;br&gt;mastery_level, tenant_id, updated_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="1880" y="295" width="320" height="140" as="geometry"/>
</mxCell>
<mxCell id="20" value="cl_learning_event&lt;br&gt;PK event_id&lt;br&gt;FK session_id -&gt; cl_learning_session.session_id&lt;br&gt;event_type(start/pause/seek/finish)&lt;br&gt;event_time, payload_json, tenant_id" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="950" y="750" width="300" height="130" as="geometry"/>
</mxCell>
<mxCell id="21" value="设计方法与原因&lt;br&gt;1) 聚合根Course / LearningSession&lt;br&gt;2) 状态机Session状态驱动进度写入&lt;br&gt;3) 标签与知识点解耦,支持多维检索&lt;br&gt;4) 事件明细单表追加,兼顾审计与回放&lt;br&gt;5) 知识点/学习画像变化可通过 ai.tb_ai_knowledge_sync_task 异步同步" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" parent="1" vertex="1">
<mxGeometry x="10" y="850" width="840" height="120" as="geometry"/>
</mxCell>
<mxCell id="22" value="外部同步依赖ai&lt;br&gt;ai.tb_ai_knowledge_file&lt;br&gt;ai.tb_ai_knowledge_sync_task&lt;br&gt;ai.tb_ai_graph_entity / ai.tb_ai_graph_relation" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;" parent="1" vertex="1">
<mxGeometry x="1320" y="760" width="330" height="150" as="geometry"/>
</mxCell>
<mxCell id="23" value="cl_kp_prerequisite_rel&lt;br&gt;PK (kp_id, pre_kp_id)&lt;br&gt;FK kp_id -&gt; cl_knowledge_point.kp_id&lt;br&gt;FK pre_kp_id -&gt; cl_knowledge_point.kp_id&lt;br&gt;tenant_id, created_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="1320" y="150" width="340" height="120" as="geometry"/>
</mxCell>
<mxCell id="24" value="cl_kp_material_rel&lt;br&gt;PK (kp_id, resource_id)&lt;br&gt;FK kp_id -&gt; cl_knowledge_point.kp_id&lt;br&gt;FK resource_id -&gt; cl_course_resource.resource_id&lt;br&gt;tenant_id, created_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="1350" y="565" width="360" height="120" as="geometry"/>
</mxCell>
<mxCell id="25" value="cl_student_kp_mastery&lt;br&gt;PK mastery_id&lt;br&gt;FK kp_id -&gt; cl_knowledge_point.kp_id&lt;br&gt;student_id, mastery_level, mastery_score&lt;br&gt;last_practiced_at, tenant_id, updated_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="1320" y="420" width="360" height="120" as="geometry"/>
</mxCell>
<mxCell id="100" value="1:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;exitPerimeter=1;entryPerimeter=1;" parent="1" source="10" target="11" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="101" value="1:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;exitPerimeter=1;entryPerimeter=1;" parent="1" source="11" target="12" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="102" value="1:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;exitPerimeter=1;entryPerimeter=1;" parent="1" source="12" target="15" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="103" value="1:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;exitPerimeter=1;entryPerimeter=1;" parent="1" source="10" target="14" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="104" value="1:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;exitPerimeter=1;entryPerimeter=1;" parent="1" source="13" target="14" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="105" value="1:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;exitPerimeter=1;entryPerimeter=1;" parent="1" source="11" target="17" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="106" value="1:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;exitPerimeter=1;entryPerimeter=1;" parent="1" source="16" target="17" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="107" value="1:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;exitPerimeter=1;entryPerimeter=1;" parent="1" source="10" target="18" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="108" value="1:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;exitPerimeter=1;entryPerimeter=1;" parent="1" source="18" target="19" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="109" value="1:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;exitPerimeter=1;entryPerimeter=1;" parent="1" source="12" target="19" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="110" value="1:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;exitPerimeter=1;entryPerimeter=1;" parent="1" source="18" target="20" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="112" value="1:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;exitPerimeter=1;entryPerimeter=1;" parent="1" source="13" target="23" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="113" value="1:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;exitPerimeter=1;entryPerimeter=1;" parent="1" source="13" target="24" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="114" value="1:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;exitPerimeter=1;entryPerimeter=1;" parent="1" source="15" target="24" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="115" value="1:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;exitPerimeter=1;entryPerimeter=1;" parent="1" source="13" target="25" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="116" value="1:N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;jettySize=auto;html=1;endArrow=block;endFill=1;exitPerimeter=1;entryPerimeter=1;" parent="1" source="19" target="25" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="11" value="cl_course_chapter&lt;br&gt;PK chapter_id&lt;br&gt;FK course_id -&gt; cl_course.course_id&lt;br&gt;chapter_no, chapter_title&lt;br&gt;tenant_id, created_at" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="340" y="240" width="250" height="130" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>