---
url: https://docs.nemo12.com/reference/data-dictionary/question-bank.md
description: >-
  Từ điển dữ liệu D1, domain Ngân hàng đề: 5 bảng, exam_attempt_answers tới
  target_schools; cột, kiểu, khoá ngoại, index.
---

# Data Dictionary · Ngân hàng đề

> ⚙️ **Trang này sinh tự động** từ source code bằng `scripts/gen-reference.mjs` — đừng sửa tay, sửa code rồi chạy `npm run gen:reference`.

Thuộc [Data Dictionary](../data-dictionary.md). 5 bảng, `exam_attempt_answers` tới `target_schools`.

## `exam_attempt_answers`

migration: `0004_exam_bank.sql`

| Cột | Kiểu | Ràng buộc / ghi chú |
| --- | --- | --- |
| `id` | TEXT | PRIMARY KEY |
| `attempt_id` | TEXT | NOT NULL REFERENCES exam_attempts(id) |
| `question_id` | TEXT | NOT NULL |
| `node_id` | TEXT | — |
| `selected_index` | INTEGER | NOT NULL |
| `correct` | INTEGER | NOT NULL |
| `points_awarded` | REAL | NOT NULL DEFAULT 0 |
| `created_at` | TEXT | NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')) |

**Khóa ngoại:** `attempt_id` → `exam_attempts`

**Index:** `idx_attempt_answers_attempt`(attempt_id)

## `exam_attempts`

migration: `0004_exam_bank.sql`

| Cột | Kiểu | Ràng buộc / ghi chú |
| --- | --- | --- |
| `id` | TEXT | PRIMARY KEY |
| `exam_id` | TEXT | NOT NULL REFERENCES exams(id) |
| `learner_id` | TEXT | NOT NULL REFERENCES learners(id) |
| `subject_id` | TEXT | NOT NULL |
| `status` | TEXT | NOT NULL DEFAULT 'in_progress' CHECK (status IN ('in_progress','completed','abandoned')) |
| `score` | REAL | — |
| `max_score` | REAL | — |
| `started_at` | TEXT | NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')) |
| `completed_at` | TEXT | — |

**Khóa ngoại:** `exam_id` → `exams` · `learner_id` → `learners`

**Index:** `idx_exam_attempts_learner`(learner_id)

## `exam_questions`

migration: `0004_exam_bank.sql`

| Cột | Kiểu | Ràng buộc / ghi chú |
| --- | --- | --- |
| `id` | TEXT | PRIMARY KEY |
| `exam_id` | TEXT | NOT NULL REFERENCES exams(id) |
| `ord` | INTEGER | NOT NULL |
| `node_id` | TEXT | — |
| `subject_id` | TEXT | NOT NULL |
| `prompt` | TEXT | NOT NULL |
| `options_json` | TEXT | NOT NULL |
| `correct_index` | INTEGER | NOT NULL |
| `points` | REAL | NOT NULL DEFAULT 1 |
| `item_ref` | TEXT | — |

**Khóa ngoại:** `exam_id` → `exams`

**Index:** `idx_exam_questions_exam`(exam_id, ord)

## `exams`

migration: `0004_exam_bank.sql`

| Cột | Kiểu | Ràng buộc / ghi chú |
| --- | --- | --- |
| `id` | TEXT | PRIMARY KEY |
| `subject_id` | TEXT | NOT NULL |
| `exam_type` | TEXT | NOT NULL CHECK (exam_type IN ('semester','selective')) |
| `title_vi` | TEXT | NOT NULL |
| `grade` | INTEGER | — |
| `target_school_id` | TEXT | REFERENCES target_schools(id) |
| `province` | TEXT | — |
| `year` | INTEGER | — |
| `difficulty_tier` | TEXT | NOT NULL DEFAULT 'basic' CHECK (difficulty_tier IN ('basic','standard','advanced')) |
| `duration_minutes` | INTEGER | NOT NULL DEFAULT 45 |
| `status` | TEXT | NOT NULL DEFAULT 'published' CHECK (status IN ('draft','published','archived')) |
| `source` | TEXT | NOT NULL DEFAULT 'generated' |
| `created_at` | TEXT | NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')) |
| `term` | TEXT | CHECK (term IN ('giua_ki_1','cuoi_ki_1','giua_ki_2','cuoi_ki_2')) — thêm ở 0015_exam_metadata.sql |
| `exam_round` | TEXT | CHECK (exam_round IN ('dieu_kien','chuyen')) — thêm ở 0015_exam_metadata.sql |
| `specialist_subject` | TEXT |  — thêm ở 0015_exam_metadata.sql |
| `exam_system` | TEXT |  — thêm ở 0015_exam_metadata.sql |
| `school_year` | TEXT |  — thêm ở 0015_exam_metadata.sql |
| `exam_date` | TEXT |  — thêm ở 0015_exam_metadata.sql |
| `source_ref` | TEXT |  — thêm ở 0015_exam_metadata.sql |
| `verified` | INTEGER | NOT NULL DEFAULT 0 — thêm ở 0015_exam_metadata.sql |
| `source_url` | TEXT |  — thêm ở 0035_exam_provenance.sql |
| `source_kind` | TEXT | CHECK (source_kind IN ('generated','real')) — thêm ở 0035_exam_provenance.sql |
| `provenance_json` | TEXT |  — thêm ở 0035_exam_provenance.sql |
| `immutable_after_publish` | INTEGER | NOT NULL DEFAULT 0 — thêm ở 0035_exam_provenance.sql |
| `solution_authored_by` | TEXT |  — thêm ở 0035_exam_provenance.sql |
| `paper_code` | TEXT |  — thêm ở 0041_exam_terms.sql |

**Khóa ngoại:** `target_school_id` → `target_schools`

**Index:** `idx_exams_subject`(subject_id, exam_type, grade) · `idx_exams_source_kind`(source_kind, status) · `idx_exams_term`(subject_id, grade, term, paper_code)

## `target_schools`

Migration 0004 — Exam Bank. SDD-011 §3-4, REQ-EXAM-01..04. Turtle: đề học kỳ (semester, generic). Shark: đề theo trường (selective, target_school).

migration: `0004_exam_bank.sql`

| Cột | Kiểu | Ràng buộc / ghi chú |
| --- | --- | --- |
| `id` | TEXT | PRIMARY KEY |
| `name` | TEXT | NOT NULL |
| `province` | TEXT | — |
| `kind` | TEXT | NOT NULL DEFAULT 'chuyen' CHECK (kind IN ('chuyen','chon','thuong')) |
| `source` | TEXT | NOT NULL DEFAULT 'chuyenchon' |
| `slug` | TEXT |  — thêm ở 0047_school_registry.sql |
| `short_name` | TEXT |  — thêm ở 0047_school_registry.sql |
| `managed_by` | TEXT |  — thêm ở 0047_school_registry.sql |
| `website` | TEXT |  — thêm ở 0047_school_registry.sql |
| `established_year` | INTEGER |  — thêm ở 0047_school_registry.sql |
| `summary` | TEXT |  — thêm ở 0047_school_registry.sql |
| `description` | TEXT |  — thêm ở 0047_school_registry.sql |
| `logo_media_id` | TEXT |  — thêm ở 0047_school_registry.sql |
| `hero_media_id` | TEXT |  — thêm ở 0047_school_registry.sql |
| `status` | TEXT | NOT NULL DEFAULT 'draft' — thêm ở 0047_school_registry.sql |
| `display_order` | INTEGER | NOT NULL DEFAULT 100 — thêm ở 0047_school_registry.sql |
| `updated_at` | TEXT |  — thêm ở 0047_school_registry.sql |

**Index:** `idx_target_schools_slug`(slug) UNIQUE · `idx_target_schools_public`(status, province, display_order)
