一括採点のデータベース設計
一括採点のデータベースには、現在50を超えるテーブルがあります (この記事の公開後も、OMRや成績算出などの機能追加とともに増えています)。 ここでは、その中でも中心となる主なテーブルが、どのような役割を持ち、どう関連しているかを解説します。
テーブルの関係図
下の図は、主なテーブルがどのように繋がっているかを示しています。 線で繋がっているテーブルは、外部キーで参照関係があります。

テーブル一覧
下の表は、主なテーブルの一覧です。 「リレーション先」は、そのテーブルが参照している他のテーブルです。
| テーブル名 | 役割 | リレーション先 |
|---|---|---|
| User | 採点者 | − |
| Class | 学級 | − |
| Student | 生徒 | − |
| StudentClassMembership | 生徒の学級所属 | Student, Class |
| Project | 試験プロジェクト | − |
| UserProject | 採点者とプロジェクトの紐づけ | User, Project |
| ProjectStudent | プロジェクトの参加生徒 | Project, Student |
| ProjectClass | プロジェクトの対象学級 | Project, Class |
| ProjectPage | 試験のページ | Project |
| MasterImage | 模範解答画像 | ProjectPage |
| StudentAnswerImage | 答案画像 | ProjectPage, Student |
| CropRegion | 採点枠 | ProjectPage |
| QuestionScore | 採点結果(採点者ごとの提案) | CropRegion, Student, User |
| ScoreDecision | 採点の確定(試験の持ち主による裁定) | CropRegion, Student, User |
| DrawingAnnotation | 答案への書き込み | QuestionScore, User |
| Subject | 教科 | − |
| SubtotalGroup | 小計グループ | − |
| Subtotal | 小計項目 | SubtotalGroup |
| SubjectSubtotalGroup | 教科と小計グループの紐づけ | Subject, SubtotalGroup |
| ProjectSubtotalGroup | プロジェクトの小計グループ | Project, SubtotalGroup |
| CropSubtotal | 採点枠と小計の紐づけ | CropRegion, Subtotal |
| ProjectMarkingFormat | 採点記号の設定 | Project |
| CropRegionMarkingOverride | 採点枠ごとの記号設定 | CropRegion |
| ProjectExportSettings | エクスポート設定 | Project |
| UserKeyboardShortcut | キーボードショートカット設定 | User |
| UserScoringPreference | 採点画面の設定 | User |
採点者・生徒・学級
User
採点者の情報を保存します。 ユーザー名、表示名、パスコードなどが含まれます。
Student
生徒の情報を保存します。 出席番号、氏名、ふりがななどが含まれます。
Class
学級の情報を保存します。 学級名や学年などが含まれます。
StudentClassMembership
→ Student, Classどの生徒がどの学級に所属しているかを管理します。 出席番号もここで管理します。
試験プロジェクト
Project
試験の基本情報を保存します。 試験名、実施日、教科などが含まれます。
UserProject
→ User, Projectどの採点者がどのプロジェクトに参加しているかを管理します。 所有者(作成者)と採点者の役割を区別します。
ProjectStudent
→ Project, Studentプロジェクトに参加している生徒を管理します。 参加状態や表示順序などが含まれます。
ProjectClass
→ Project, Classプロジェクトの対象学級を管理します。 統計集計の対象にするかどうかなどの設定も含まれます。
ページと画像
ProjectPage
→ Project試験のページを管理します。 1つのプロジェクトに複数のページがある場合(表と裏など)に対応します。
MasterImage
→ ProjectPage模範解答画像のファイルパスを保存します。 画像自体はファイルシステムに置かれ、ここにはその場所だけを記録します。
StudentAnswerImage
→ ProjectPage, Student答案画像のファイルパスを保存します。 画像自体はファイルシステムに置かれ、ここにはその場所だけを記録します。
採点枠と採点結果
CropRegion
→ ProjectPage採点枠を保存します。 問題番号、座標、配点などが含まれます。
QuestionScore
→ CropRegion, Student, User採点結果を保存します。 どの生徒の、どの採点枠に、何点をつけたかを、採点した先生ごとに記録します。 複数の先生で分担する協調採点では、ひとつの答案に対して採点者ごとの「提案」が並ぶことがあります。 採点データの中心となるテーブルです。
ScoreDecision
→ CropRegion, Student, User採点の「確定」を保存します。 協調採点で採点者ごとの提案が食い違ったとき、試験の持ち主(オーナー)が どの採点を採用するかを裁定した結果を、生徒×採点枠ごとに1行だけ記録します。 QuestionScore(提案)とは別のテーブルに分けることで、誰かの採点が黙って上書きされず、 どのパソコンで見ても同じ結論に落ち着くようにしています。
DrawingAnnotation
→ QuestionScore, User答案への書き込みを保存します。 線、四角、丸、テキストなどの図形を描画でき、座標・色・サイズを記録します。
小計設定
Subject
教科を保存します。 国語、数学などの教科名が含まれます。
SubtotalGroup
小計グループを保存します。 「知識・技能」「思考・判断・表現」などの観点別評価の分類に使います。
Subtotal
→ SubtotalGroup小計項目を保存します。 小計グループの中の個別項目です。
SubjectSubtotalGroup
→ Subject, SubtotalGroup教科と小計グループの紐づけを管理します。 教科ごとに使用する小計グループを設定できます。
ProjectSubtotalGroup
→ Project, SubtotalGroupプロジェクトで使用する小計グループを管理します。
CropSubtotal
→ CropRegion, Subtotal採点枠と小計項目の紐づけを管理します。 各問題がどの小計項目に属するかを設定します。
その他の設定
ProjectMarkingFormat
→ Projectプロジェクトごとの採点記号の設定を保存します。 ○×の色や形などをカスタマイズできます。
CropRegionMarkingOverride
→ CropRegion採点枠ごとの記号設定を保存します。 特定の問題だけ記号を変えたい場合に使います。
ProjectExportSettings
→ Projectエクスポート時の設定を保存します。
UserKeyboardShortcut
→ Userユーザーごとのキーボードショートカット設定を保存します。
UserScoringPreference
→ User採点画面の表示設定を保存します。 答案の並び順や表示サイズなどの好みを記憶します。
UUIDによるID管理
すべてのテーブルの主キーにUUID(Universally Unique Identifier)を使用しています。
model Student {
id String @id @default(uuid())
studentNumber String @unique
lastName String
...
}UUIDは36文字のランダムな文字列で、自動生成しても重複しません。 新しいレコードを作成するたびに、世界中で一意のIDが振られます。
しかし、これには落とし穴があります。
たとえば、A先生とB先生が別々のパソコンで一括採点を使っているとします。 A先生のパソコンには生徒データがまだ入っていないので、 「山田太郎」を新規登録しました。 このとき、UUID「a1b2c3d4-e5f6-...」が自動で振られます。
同じころ、B先生も自分のパソコンで「山田太郎」を新規登録しました。 B先生のパソコンでは、UUID「x9y8z7w6-v5u4-...」が振られます。
同じ「山田太郎」なのに、パソコンによってIDが異なります。
A先生が自分のパソコンだけで採点している限り、これは問題になりません。 「山田太郎」には常に同じID「a1b2c3d4-e5f6-...」が使われるからです。
しかし、A先生の採点データをB先生のパソコンに移そうとすると問題が起きます。 B先生のパソコンでは「山田太郎」のIDが「x9y8z7w6-v5u4-...」なので、 A先生のデータに含まれる「a1b2c3d4-e5f6-...」は「知らない生徒」として扱われてしまいます。 この問題をどう解決したかは、別の記事で解説します。
一括採点では、50を超えるテーブルが外部キーで繋がっています。 すべてのテーブルでUUIDを主キーとして使用しており、 データのエクスポート・インポートにも対応しています。