Ejemplos / Sistema escolar
Sistema escolar
La base de datos de una escuela une alumnos y materias mediante las inscripciones. Es la tabla intermedia, y además guarda la calificación. Los profesores imparten grupos de una materia en un periodo concreto. La asistencia depende de la inscripción, con una fila por alumno y por día de clase.
Abajo, ErdDocs dibuja este esquema a partir de su SQL, con todas las tablas y relaciones. En la pestaña «Diccionario de datos» tienes la versión imprimible, completa y gratis en esta página. El SQL está más abajo.
Pasa el cursor sobre una tabla para resaltar sus relaciones y haz clic para fijarlas.
Qué hace cada tabla
- students / teachersTablas separadas. Alumnos y profesores solo comparten el nombre. Sus datos y su ciclo de vida son distintos.
- coursesLa materia del plan de estudios. CS-101 existe una sola vez, se imparta las veces que se imparta.
- sectionsEl grupo es una materia en un periodo, con un profesor. Es lo que el alumno realmente cursa.
- enrollmentsTabla intermedia entre alumno y grupo. Además de los enlaces, guarda la calificación.
- attendanceDepende de la inscripción mediante una clave foránea compuesta. No se puede registrar asistencia en un grupo en el que el alumno no está inscrito.
Decisiones de diseño que vale la pena copiar
- Separar materia y grupo es la idea central del esquema. Si inscribes alumnos directamente en materias, todo se rompe en cuanto la materia se imparte dos veces. Hay dos periodos y dos profesores, pero una sola columna de calificación, y ya no está claro a qué se refiere.
- La asistencia referencia la inscripción con una clave foránea compuesta (student_id, section_id). Así la propia base rechaza la asistencia de alumnos no inscritos.
- La calificación admite nulos en lugar de llevar un valor por defecto. Si falta, significa que el periodo sigue en curso, no que el alumno sacó un cero.
El SQL
Dialecto PostgreSQL. Este SQL ya está en la herramienta de arriba, y puedes copiarlo libremente a tu base de datos o a una migración.
CREATE TABLE students (
id bigserial PRIMARY KEY,
student_no varchar(20) NOT NULL UNIQUE,
full_name varchar(120) NOT NULL,
enrolled_on date NOT NULL
);
CREATE TABLE teachers (
id bigserial PRIMARY KEY,
full_name varchar(120) NOT NULL,
department varchar(80) NOT NULL
);
CREATE TABLE courses (
id bigserial PRIMARY KEY,
code varchar(12) NOT NULL UNIQUE,
title varchar(160) NOT NULL,
credits int NOT NULL
);
COMMENT ON COLUMN courses.code IS 'Clave de la materia, p. ej. CS-101';
CREATE TABLE sections (
id bigserial PRIMARY KEY,
course_id bigint NOT NULL REFERENCES courses(id),
teacher_id bigint NOT NULL REFERENCES teachers(id),
term varchar(20) NOT NULL,
room varchar(20)
);
COMMENT ON TABLE sections IS 'Una materia que un profesor imparte en un periodo; los alumnos se inscriben en grupos, no en materias';
CREATE TABLE enrollments (
student_id bigint NOT NULL REFERENCES students(id),
section_id bigint NOT NULL REFERENCES sections(id),
grade varchar(2),
PRIMARY KEY (student_id, section_id)
);
COMMENT ON COLUMN enrollments.grade IS 'NULL hasta que termina el periodo';
CREATE TABLE attendance (
student_id bigint NOT NULL,
section_id bigint NOT NULL,
class_date date NOT NULL,
present boolean NOT NULL,
PRIMARY KEY (student_id, section_id, class_date),
FOREIGN KEY (student_id, section_id) REFERENCES enrollments(student_id, section_id)
);Preguntas frecuentes
¿Dónde van los padres o tutores?
En una tabla guardians y una intermedia student_guardians. Es una relación muchos a muchos, porque los hermanos comparten tutores y un alumno puede tener varios.
¿Por qué no poner teacher_id en courses?
Porque la misma materia la dan profesores distintos en periodos distintos. El profesor pertenece al grupo, no a la materia del plan.