offdataai
Education · data model template

K-12 School Information System (Ed-Fi inspired) data model

Third-normal-form mirror of the Ed-Fi K-12 entities as they would land from an Ed-Fi ODS or an SIS export. Lookups carry the descriptor codes (grade level, term, subject area, attendance, discipline action, enrollment status), normal tables carry the organizational and student-family records, and outcome tables (attendance, grade, assessment, discipline) reference student + section + term. Student and parent PII (names, DOB, SSN, address, contact info) are FERPA + COPPA restricted; the self-referencing course and school parents are modeled as plain bigint keys without a relationship.

Normalized replica of a K-12 student information system aligned to the Ed-Fi Unifying Data Model — Local Education Agency (district), School, Course, Section, Staff, Student, Parent/Guardian, plus the outcome events of Enrollment, Attendance, Grade, Assessment, and Discipline. Suitable as a warehouse staging layer for SIS exports (PowerSchool, Infinite Campus, Skyward) and Ed-Fi ODS replicas. It is a normalized (3NF) relational model that mirrors the source system, suited to operational databases and to landing source data faithfully.

3NFEducationFERPACOPPA
21
tables
186
columns
33
relationships
16
PII columns

Opening the template creates a project with the ERD, platform-native DDL, a dbt project and documentation already generated (recommended platform: PostgreSQL). Edit it in plain English or on the canvas, then ship it to any supported warehouse.

Subject areas

education_organizationstudents_familiesoutcomesmaster_data

Design decisions

  • Student-section association as the class-enrollment grain

    Ed-Fi separates StudentSectionAssociation (a student's enrollment in a specific class) from StudentSchoolAssociation (enrollment in a school + grade level over time). Replicating both keeps schedule churn (drops, adds, swaps) distinct from school-level enrollment history.

  • Separate student_enrollment entity for school/grade history

    A student's school and grade level change across years and mid-year transfers; modeling student_enrollment as its own entity preserves the begin/end-dated history that Ed-Fi StudentSchoolAssociation captures.

  • Parent ↔ student many-to-many via a link table

    Ed-Fi models the parent-student relationship as StudentParentAssociation because one student can have multiple guardians (and one guardian multiple children); a link table avoids duplicating parent rows per child and carries the relationship_type and custody_status.

  • FERPA / COPPA restricted PII on student identifiers and addresses

    FERPA restricts disclosure of personally identifiable information from education records; SSN, date of birth, and home address are tagged restricted, and student/parent names + email are marked PII so the governance report surfaces them up-front.

  • Course prerequisite chain modeled as a plain self-referencing key

    Course prerequisites form a directed acyclic graph (Algebra II requires Algebra I, etc.); keeping parent_course_key as a plain bigint without a declared relationship avoids cyclic FK dependencies during DDL topo-sort while still letting the catalog walk the chain in SQL.

Tables in the K-12 School Information System (Ed-Fi inspired) model

Every table with its grain, columns, types and keys. PK marks a primary key, BK a business key and PII a column classified as personal data, which gets a masking strategy by default.

Tables (14)

local_education_agency

Grain: one row per LEA / district

Ed-Fi LocalEducationAgency — district-level organization.

ColumnTypeKeys
local_education_agency_keybigintPK
lea_idvarcharBK
district_namevarchar
statevarchar
district_typevarchar
enrollment_size_bandvarchar
superintendent_namevarcharPII

school

Grain: one row per Ed-Fi School

Ed-Fi School — campus-level organization.

ColumnTypeKeys
school_keybigintPK
local_education_agency_keybigint
school_idvarcharBK
school_namevarchar
school_typevarchar
low_grade_levelvarchar
high_grade_levelvarchar
principal_namevarcharPII
parent_school_keybigint
is_charterboolean
is_title_oneboolean

staff

Grain: one row per staff member

Ed-Fi Staff — teachers, principals, counselors, aides, administrators.

ColumnTypeKeys
staff_keybigintPK
school_keybigint
staff_idvarcharBK
first_namevarcharPII
last_namevarcharPII
rolevarchar
subject_area_primaryvarchar
hire_datedate
employment_statusvarchar
certificationvarchar
emailvarcharPII

course

Grain: one row per course offering in the catalog

Ed-Fi Course — district course catalog entry.

ColumnTypeKeys
course_keybigintPK
subject_area_keybigint
course_codevarcharBK
course_titlevarchar
credit_hoursdecimal
course_levelvarchar
grade_level_minvarchar
grade_level_maxvarchar
parent_course_keybigint

section

Grain: one row per section (a class period of a course)

Ed-Fi Section — a specific scheduled offering of a course.

ColumnTypeKeys
section_keybigintPK
course_keybigint
school_keybigint
school_year_keybigint
term_keybigint
staff_keybigint
section_idvarcharBK
section_numbervarchar
classroom_idvarchar
periodvarchar
max_studentsinteger
meeting_patternvarchar
is_activeboolean

student

Grain: one row per student

Ed-Fi Student — the central learner entity.

ColumnTypeKeys
student_keybigintPK
student_idvarcharBK
first_namevarcharPII
last_namevarcharPII
date_of_birthdatePII
gendervarchar
ethnicityvarchar
racevarchar
primary_languagevarchar
ell_statusvarchar
iep_504_statusvarchar
free_reduced_lunch_statusvarchar
ssn_maskedvarcharPII
addressvarcharPII
emailvarcharPII
parent_student_idvarchar
enrollment_datedate
is_activeboolean

parent_guardian

Grain: one row per parent or guardian

Ed-Fi Parent — parent/guardian contact record.

ColumnTypeKeys
parent_guardian_keybigintPK
parent_idvarcharBK
first_namevarcharPII
last_namevarcharPII
relationshipvarchar
emailvarcharPII
phonevarcharPII
is_primary_contactboolean
lives_with_studentboolean

student_parent_link

Grain: one row per student↔parent association

Ed-Fi StudentParentAssociation — M:N student-to-parent linker.

ColumnTypeKeys
student_parent_link_keybigintPK
student_keybigint
parent_guardian_keybigint
link_idvarcharBK
relationship_typevarchar
custody_statusvarchar

student_enrollment

Grain: one row per student enrollment in a school/grade/year

Ed-Fi StudentSchoolAssociation — school + grade-level enrollment over time.

ColumnTypeKeys
student_enrollment_keybigintPK
student_keybigint
school_keybigint
school_year_keybigint
grade_level_keybigint
enrollment_status_keybigint
enrollment_idvarcharBK
entry_datedate
exit_datedate
entry_grade_levelvarchar
exit_reasonvarchar

student_section_association

Grain: one row per student↔section enrollment

Ed-Fi StudentSectionAssociation — enrollment in a specific class.

ColumnTypeKeys
student_section_association_keybigintPK
student_keybigint
section_keybigint
term_keybigint
association_idvarcharBK
begin_datedate
end_datedate
enrollment_statusvarchar

attendance_event

Grain: one row per attendance event per student/section/day

Ed-Fi StudentSectionAttendanceEvent.

ColumnTypeKeys
attendance_event_keybigintPK
student_keybigint
section_keybigint
attendance_code_keybigint
attendance_event_idvarcharBK
attendance_datedate
periodvarchar
was_tardy_minutesinteger
recorded_byvarcharPII

grade

Grain: one row per student/section/term grade

Ed-Fi Grade — reported grade for a student in a section.

ColumnTypeKeys
grade_keybigintPK
student_keybigint
section_keybigint
term_keybigint
grade_level_keybigint
grade_idvarcharBK
grading_periodvarchar
letter_gradevarchar
numeric_gradedecimal
grade_pointsdecimal
is_finalboolean
is_passingboolean

assessment_result

Grain: one row per student assessment result

Ed-Fi StudentAssessment — standardized assessment results.

ColumnTypeKeys
assessment_result_keybigintPK
student_keybigint
school_year_keybigint
subject_area_keybigint
assessment_result_idvarcharBK
assessment_namevarchar
administered_datedate
scale_scoredecimal
performance_levelvarchar
percentile_rankdecimal
accommodations_usedvarchar

discipline_incident

Grain: one row per discipline incident

Ed-Fi DisciplineIncident — discipline event with assigned action.

ColumnTypeKeys
discipline_incident_keybigintPK
student_keybigint
school_keybigint
school_year_keybigint
discipline_action_keybigint
staff_keybigint
incident_idvarcharBK
incident_datedate
behavior_codevarchar
days_assignedinteger
location_in_schoolvarchar
reporter_rolevarchar

Lookup tables (7)

school_year

Grain: one row per school year

Ed-Fi SchoolYearType — academic year reference.

ColumnTypeKeys
school_year_keybigintPK
school_year_idvarcharBK
year_labelvarchar
start_datedate
end_datedate
is_currentboolean

grade_level

Grain: one row per grade level

Ed-Fi GradeLevelDescriptor.

ColumnTypeKeys
grade_level_keybigintPK
grade_level_idvarcharBK
grade_labelvarchar
age_typicalinteger
is_elementaryboolean
is_middleboolean
is_highboolean

term

Grain: one row per academic term within a school year

Ed-Fi TermDescriptor.

ColumnTypeKeys
term_keybigintPK
term_idvarcharBK
term_namevarchar
start_datedate
end_datedate
school_year_idvarchar
is_quarterboolean
is_semesterboolean

subject_area

Grain: one row per academic subject area

Ed-Fi AcademicSubjectDescriptor.

ColumnTypeKeys
subject_area_keybigintPK
subject_area_idvarcharBK
subject_namevarchar
subject_categoryvarchar

attendance_code

Grain: one row per attendance event code

Ed-Fi AttendanceEventCategoryDescriptor.

ColumnTypeKeys
attendance_code_keybigintPK
attendance_code_idvarcharBK
descriptionvarchar
counts_as_presentboolean
counts_as_absentboolean

discipline_action

Grain: one row per discipline action type

Ed-Fi DisciplineActionDescriptor.

ColumnTypeKeys
discipline_action_keybigintPK
discipline_action_idvarcharBK
descriptionvarchar
severity_levelinteger
days_typicalinteger

enrollment_status

Grain: one row per enrollment status code

Ed-Fi StudentEnrollmentStatusDescriptor.

ColumnTypeKeys
enrollment_status_keybigintPK
status_idvarcharBK
descriptionvarchar
is_active_enrollmentboolean

Relationships

Each relationship is a foreign key on the first table referencing the second.

  • school.local_education_agency_key → local_education_agency (many-to-one)
  • staff.school_key → school (many-to-one)
  • course.subject_area_key → subject_area (many-to-one)
  • section.course_key → course (many-to-one)
  • section.school_key → school (many-to-one)
  • section.school_year_key → school_year (many-to-one)
  • section.term_key → term (many-to-one)
  • section.staff_key → staff (many-to-one)
  • student_parent_link.student_key → student (many-to-one)
  • student_parent_link.parent_guardian_key → parent_guardian (many-to-one)
  • student_enrollment.student_key → student (many-to-one)
  • student_enrollment.school_key → school (many-to-one)
  • student_enrollment.school_year_key → school_year (many-to-one)
  • student_enrollment.grade_level_key → grade_level (many-to-one)
  • student_enrollment.enrollment_status_key → enrollment_status (many-to-one)
  • student_section_association.student_key → student (many-to-one)
  • student_section_association.section_key → section (many-to-one)
  • student_section_association.term_key → term (many-to-one)
  • attendance_event.student_key → student (many-to-one)
  • attendance_event.section_key → section (many-to-one)
  • attendance_event.attendance_code_key → attendance_code (many-to-one)
  • grade.student_key → student (many-to-one)
  • grade.section_key → section (many-to-one)
  • grade.term_key → term (many-to-one)
  • grade.grade_level_key → grade_level (many-to-one)
  • assessment_result.student_key → student (many-to-one)
  • assessment_result.school_year_key → school_year (many-to-one)
  • assessment_result.subject_area_key → subject_area (many-to-one)
  • discipline_incident.student_key → student (many-to-one)
  • discipline_incident.school_key → school (many-to-one)
  • discipline_incident.school_year_key → school_year (many-to-one)
  • discipline_incident.discipline_action_key → discipline_action (many-to-one)
  • discipline_incident.staff_key → staff (many-to-one)

Related templates

All templates →
Start for $1

From requirements to AI-ready context, in one platform.

Describe your business in a conversation, start from a template or connect your own database. Your first model is ready in minutes.

Get startedBook a demo

Plans from $1/month · cancel any time