ErdDocs

Exemplos / Sistema escolar

Sistema escolar

O banco de dados de uma escola liga alunos e disciplinas pelas matrículas. Essa é a tabela associativa, e ela também guarda a nota. Os professores dão turmas de uma disciplina num período. A frequência depende da matrícula, com uma linha por aluno e por dia de aula.

Abaixo, o ErdDocs desenha este schema a partir do SQL, com todas as tabelas e relacionamentos. Na aba «Dicionário de dados» está a versão para imprimir, completa e grátis nesta página. O SQL fica mais abaixo.

Seu schema

Passe o mouse sobre uma tabela para destacar os relacionamentos e clique para fixá-los.

O que cada tabela faz

  • students / teachersTabelas separadas. Alunos e professores só compartilham o nome. Os dados e o ciclo de vida são diferentes.
  • coursesA disciplina da grade. CS-101 existe uma vez só, não importa quantas vezes seja oferecida.
  • sectionsA turma é uma disciplina num período, com um professor. É nela que o aluno de fato entra.
  • enrollmentsTabela associativa entre aluno e turma. Além das ligações, ela guarda a nota.
  • attendanceDepende da matrícula por uma chave estrangeira composta. Não dá para registrar presença numa turma em que o aluno não está matriculado.

Decisões de modelagem que vale copiar

  • Separar disciplina e turma é a base do schema. Se você matricula alunos direto nas disciplinas, tudo quebra assim que a disciplina é oferecida duas vezes. São dois períodos e dois professores, mas uma só coluna de nota, e já não fica claro a que ela se refere.
  • A frequência referencia a matrícula por uma chave estrangeira composta (student_id, section_id). Assim o próprio banco recusa presença de aluno não matriculado.
  • A nota aceita nulo em vez de ter valor padrão. Nota vazia quer dizer que o período ainda está em andamento, e não que o aluno tirou zero.

O SQL

Dialeto PostgreSQL. Este SQL já está na ferramenta acima, e você pode copiá-lo à vontade para o seu banco ou para uma migration.

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 'Código da disciplina, ex.: 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 'Uma disciplina oferecida num período por um professor; os alunos se matriculam em turmas, não em disciplinas';

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 até o fim do período';

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)
);

Perguntas frequentes

Onde entram pais ou responsáveis?

Numa tabela guardians e numa associativa student_guardians. É um relacionamento muitos para muitos, porque irmãos compartilham responsáveis e um aluno pode ter vários.

Por que não colocar teacher_id em courses?

Porque a mesma disciplina é dada por professores diferentes em períodos diferentes. O professor pertence à turma, não à disciplina da grade.

Mais exemplos