Conversão ER → Esquema Relacional

Autor

Douglas Braga

Um diagrama ER é uma ferramenta conceitual. Para implementar o banco de dados, precisamos convertê-lo em esquemas relacionais (tabelas). As regras de conversão são sistemáticas.

Regra 1: Entidade Forte

Cada conjunto de entidades forte gera um schema com os mesmos atributos. A chave primária do ER torna-se a chave primária da relação.

As entidades fortes da UnDF geram diretamente suas relações:

centro(id_centro, sigla, nome_centro)
  PK: id_centro

escola(id_escola, sigla, nome_escola, id_centro)
  PK: id_escola

professor(id_prof, nome, id_escola, ch_semanal, salario)
  PK: id_prof

Regra 2: Entidade Fraca

Cada conjunto de entidades fraco gera um schema que inclui: - Todos os seus atributos (incluindo o discriminador) - A chave primária da entidade identificadora

A chave primária da relação é a união da PK da entidade identificadora com o discriminador.

Se turma fosse modelada como entidade fraca de disciplina com discriminador (ano, semestre, id_turma):

turma(id_disciplina, ano, semestre, id_turma, horario, sala)
  PK: (id_disciplina, ano, semestre, id_turma)
  FK: id_disciplina → disciplina(id_disciplina)

Regra 3: Atributo Composto

Atributos compostos são achatados (flattened): cria-se uma coluna separada para cada componente.

Se nome fosse composto em (primeiro_nome, nome_do_meio, sobrenome):

-- Em vez de: nome VARCHAR(100)
primeiro_nome VARCHAR(50)  NOT NULL,
nome_do_meio  VARCHAR(50),
sobrenome     VARCHAR(50)  NOT NULL

O prefixo do atributo composto pode ser omitido se não houver ambiguidade (usa-se primeiro_nome em vez de nome_primeiro_nome).

Regra 4: Atributo Multivalorado

Um atributo multivalorado \(M\) da entidade \(E\) gera um schema separado \(EM\) contendo: - A chave primária de \(E\) (como chave estrangeira) - O atributo \(M\)

A chave primária de \(EM\) é a combinação da PK de \(E\) com \(M\).

Se professor tiver atributo multivalorado telefone:

telefone_professor(id_prof, telefone)
  PK: (id_prof, telefone)
  FK: id_prof → professor(id_prof)

Cada número de telefone vira uma tupla separada.

Regra 5: Relacionamento N:N

Um relacionamento N:N gera um novo schema contendo: - A chave primária de cada entidade participante (como FKs) - Os atributos próprios do relacionamento

A chave primária é a união das PKs das entidades participantes.

O relacionamento ministra (N:N entre professor e disciplina):

ministra(id_disciplina, ano, semestre, turma, id_prof, horario, sala)
  PK: (id_disciplina, ano, semestre, turma)
  FK: id_disciplina → disciplina(id_disciplina)
  FK: id_prof → professor(id_prof)

Nota: como ministra tem atributos ano, semestre e turma, a PK inclui esses atributos para distinguir ofertas da mesma disciplina em semestres diferentes.

Regra 6: Relacionamento N:1 (e 1:N)

Em um relacionamento N:1 com participação total no lado N, em vez de criar um schema separado, adiciona-se a chave primária do lado “1” como atributo extra (FK) no schema do lado “N”.

Isso é mais eficiente e evita uma JOIN desnecessária.

O relacionamento lotado_em (professor N:1 escola) não precisa de tabela própria:

-- Sem otimização (schema separado):
lotado_em(id_prof, id_escola)

-- Com otimização (FK embutida em professor):
professor(id_prof, nome, id_escola, ch_semanal, salario)
  FK: id_escola → escola(id_escola)

O mesmo se aplica a pertence_a, ofertado_por, compoe e matriculado_em.

Aviso

Se a participação do lado N for parcial (alguns podem não ter o relacionamento), a coluna FK adicionada pode conter NULL. Isso é semanticamente correto, mas deve ser documentado. Se NULL não for desejado, pode-se criar um schema separado para o relacionamento.

Regra 7: Relacionamento 1:1

Para relacionamentos 1:1, a chave primária de qualquer um dos dois lados pode ser adicionada como FK no outro. A escolha normalmente cai no lado com participação total (evita NULLs).

Esquema Completo da UnDF

Aplicando todas as regras ao diagrama ER da UnDF:

centro(id_centro, sigla, nome_centro)

escola(id_escola, sigla, nome_escola, id_centro)
  FK: id_centro → centro(id_centro)

curso(id_curso, sigla_curso, nome_curso, id_escola, n_semestres, carga_horaria, tipo_curso)
  FK: id_escola → escola(id_escola)

professor(id_prof, nome, id_escola, ch_semanal, salario)
  FK: id_escola → escola(id_escola)

aluno(id_aluno, nome, id_curso, ano_ingresso)
  FK: id_curso → curso(id_curso)

disciplina(id_disciplina, nome_disciplina, id_curso, semestre, carga_horaria)
  FK: id_curso → curso(id_curso)

ministra(id_disciplina, ano, semestre, turma, id_prof, horario, sala)
  PK: (id_disciplina, ano, semestre, turma)
  FK: id_disciplina → disciplina(id_disciplina)
  FK: id_prof → professor(id_prof)

prereq(id_disciplina, id_prereq)
  PK: (id_disciplina, id_prereq)
  FK: id_disciplina → disciplina(id_disciplina)
  FK: id_prereq → disciplina(id_disciplina)

matricula_disciplina(id_disciplina, ano, semestre, turma, id_aluno, nota, aprovado)
  PK: (id_disciplina, ano, semestre, turma, id_aluno)
  FK: (id_disciplina, ano, semestre, turma) → ministra(...)
  FK: id_aluno → aluno(id_aluno)

Para Praticar

1. Aplicar as regras. Dado o seguinte fragmento ER de uma biblioteca:

  • Entidade livro(ISBN, título, ano)
  • Entidade autor(id_autor, nome)
  • Relacionamento N:N escreve entre autor e livro, com atributo ordem (posição do autor na lista de autores)

Escreva o schema relacional resultante.

livro(ISBN, titulo, ano)
  PK: ISBN

autor(id_autor, nome)
  PK: id_autor

escreve(id_autor, ISBN, ordem)
  PK: (id_autor, ISBN)
  FK: id_autor → autor(id_autor)
  FK: ISBN → livro(ISBN)

O atributo ordem fica no schema de escreve, pois descreve a posição do autor naquele livro específico — não é propriedade do autor nem do livro isoladamente.


2. Redundância de schema. Por que o schema do relacionamento pertence_a entre escola e centro é redundante quando escola já tem o atributo centro?

O relacionamento pertence_a (N:1) foi absorvido pelo schema de escola pela Regra 6: adicionou-se a FK id_centro diretamente em escola. Um schema separado pertence_a(id_escola, id_centro) conteria exatamente a mesma informação já presente na tabela escola — seria uma duplicação. Por isso, o schema de pertence_a é redundante e deve ser descartado.


3. Atributo composto e consulta. Se endereco de aluno fosse decomposto em (rua, numero, cidade, cep), escreva uma consulta SQL que busca todos os alunos de Brasília. Compare com a versão onde endereco é uma coluna única.

Com decomposição:

SELECT nome FROM aluno WHERE cidade = 'Brasília';

Simples, eficiente, indexável.

Com coluna única:

SELECT nome FROM aluno WHERE endereco LIKE '%Brasília%';

Ineficiente (sem uso de índice), frágil (pode pegar “Rua Brasília” erroneamente), e dependente do formato da string armazenada.

A decomposição do atributo composto é sempre preferível quando buscas por partes do endereço são esperadas.