Diagramas (DER)

Antes de criar as tabelas, ajuda muito desenhar o banco: quais são as tabelas, que colunas cada uma tem e como elas se ligam. Esse desenho se chama diagrama de entidade-relacionamento, ou DER. Um DER bem feito cabe numa folha e conta, de relance, a história que você levaria parágrafos para explicar: "um cliente faz vários pedidos", "cada produto tem uma categoria". Nesta aula você aprende a ler e desenhar um DER, com a notação mais usada hoje — o pé de galinha — e vê o DER completo da Loja Aurora.

Você vai aprender
  • O que são entidades (as caixas) e atributos (as colunas), e como marcar a PK e a FK.
  • O que é cardinalidade: um, muitos, zero-ou-um, um-ou-muitos.
  • A notação pé de galinha (os three risquinhos que parecem um pé de ave).
  • Como o muitos-para-muitos aparece no diagrama, com a tabela de ligação no meio.
  • O DER completo da Loja Aurora.
  • Como "ler o diagrama" direto do banco, com pragma_foreign_key_list.

Os desenhos desta aula são SVG (um formato de imagem feito de linhas e texto), pensados para ficarem nítidos no tema claro e no escuro. As consultas rodam de verdade no editor, contra a Loja Aurora.


A ideia: a planta da casa

Ninguém constrói uma casa sem a planta: ela mostra os cômodos e as portas entre eles antes de assentar o primeiro tijolo. O DER é a planta do banco. As entidades são os cômodos (as tabelas); os relacionamentos são as portas (as ligações por chave estrangeira). Desenhar primeiro evita descobrir tarde demais que faltou uma parede — ou uma tabela.


1. A entidade: uma caixa com atributos

Cada entidade é uma tabela, desenhada como uma caixa: o nome no topo e os atributos (as colunas) listados embaixo. A chave primária (aula PRIMARY KEY) vem marcada com PK; uma chave estrangeira (aula FOREIGN KEY), com FK.

A entidade clientes como uma caixa: nome no topo, e os atributos id (PK), nome, email, cidade e vip embaixo. clientes id PK nome email cidade vip chave colunas
O topo
O nome da tabela, clientes, em destaque.
id PK
A chave primária: o número único de cada linha.
nome, email, cidade, vip
Os demais atributos. Num DER enxuto, você lista só os principais e põe "…" no resto.

2. O relacionamento e a cardinalidade

Uma linha entre duas caixas diz que elas se ligam. Mas "quantos de cada lado"? Isso é a cardinalidade. As três perguntas que ela responde, nas pontas da linha: no mínimo zero ou no mínimo um? e no máximo um ou no máximo muitos?

A notação pé de galinha

Os símbolos ficam na ponta da linha, perto de cada caixa. O nome "pé de galinha" vem do símbolo de "muitos", que se abre em três riscos, como a pegada de uma ave:

Os quatro símbolos de ponta: um e só um (dois riscos), muitos (pé de galinha), zero ou um (círculo e risco), um ou muitos (risco e pé de galinha). um e só um (1) muitos (N) zero ou um (0..1) um ou muitos (1..N) Os dois riscos = "um". O círculo = "zero". O pé de galinha = "muitos".
Símbolo na pontaQuer dizer
dois riscos ||um, e exatamente um
pé de galinha <muitos
círculo + risco o|zero ou um (opcional)
risco + pé de galinha |<um ou muitos (pelo menos um)

Um-para-muitos: cliente e pedidos

Na Loja Aurora, um cliente faz vários pedidos, e cada pedido é de um cliente só. No diagrama, o lado de pedidos ganha o pé de galinha (muitos) e o lado de clientes, os dois riscos (um):

clientes um-para-muitos pedidos: a linha sai de clientes com o símbolo de um e chega em pedidos com o pé de galinha de muitos. clientes id PK pedidos cliente_id FK um cliente … muitos pedidos

Leia a linha nos dois sentidos: da esquerda, "um cliente tem muitos pedidos"; da direita, "um pedido pertence a um cliente". A chave estrangeira pedidos.cliente_id é o que faz a ligação.


3. O muitos-para-muitos no diagrama

Um pedido tem vários produtos, e um produto está em vários pedidos (aula Relação Muitos-para-Muitos). No DER, isso não é uma linha direta entre pedidos e produtos com pé de galinha dos dois lados — é uma caixa no meio, a tabela de ligação itens_pedido, com um-para-muitos para cada lado:

pedidos e produtos ligados pela tabela de ligação itens_pedido, no meio, com pé de galinha dos dois lados apontando para itens_pedido. pedidos id PK itens_pedido pedido_id FK produto_id FK produtos id PK

A caixa do meio tem as duas chaves estrangeiras (pedido_id e produto_id) e, em geral, a chave primária é o par das duas (aula PRIMARY KEY): cada combinação pedido+produto aparece uma vez só. Sempre que você vir uma caixa pequena no meio, com duas FKs e pé de galinha dos dois lados, é um muitos-para-muitos.


4. O DER completo da Loja Aurora

Juntando tudo, este é o banco inteiro. Cada caixa é uma tabela; cada linha liga uma chave estrangeira (ponta com pé de galinha, do lado "muitos") à chave primária que ela referencia (ponta com os dois riscos, do lado "um"). Repare na seta de funcionarios para ela mesma: é o self-join do chefe_id.

DER da Loja Aurora: produtos liga-se a categorias e fornecedores; itens_pedido (tabela de ligação) liga-se a produtos e pedidos; pedidos liga-se a clientes e funcionarios; funcionarios liga-se a ela mesma pelo chefe_id. O lado de muitos tem o pé de galinha. categorias fornecedores itens_pedido produtos pedidos funcionarios clientes id PK nome id PK nome, cidade… pedido_id FK produto_id FK quantidade preco_unitario id PK categoria_id FK fornecedor_id FK nome, preco… id PK cliente_id FK funcionario_id FK data, frete… id PK chefe_id FK id PK nome, email…

Esse único desenho resume o que você estudou em várias aulas: as sete tabelas, as sete chaves estrangeiras e a tabela de ligação itens_pedido no coração do banco. Guarde-o como mapa quando for montar as suas consultas com JOIN.

Chaves que podem ser nulas

No DER, a ponta "zero ou um" (com o círculo) marca uma ligação opcional. No Aurora, funcionarios.chefe_id é assim: a gerente não tem chefe, então o valor é NULL. Já pedidos.cliente_id é NOT NULL: todo pedido tem dono. A aula NOT NULL cuida dessa diferença.


5. Lendo o diagrama direto do banco

Você não precisa ter o desenho à mão: o próprio banco sabe as suas ligações, e dá para "ler o DER" com uma consulta. A função pragma_foreign_key_list lista as chaves estrangeiras de uma tabela; juntando-a com a lista de tabelas, saem todas as setas do diagrama:

SELECT m.name AS tabela, f."table" AS aponta_para
FROM sqlite_schema AS m
JOIN pragma_foreign_key_list(m.name) AS f
WHERE m.type = 'table'
ORDER BY m.name, f."table";

São as sete setas do desenho, em texto: de itens_pedido saem duas (para pedidos e produtos), de pedidos duas, de produtos duas, e a de funcionarios para ela mesma. É o DER contado pelo banco.


Referência rápida

No diagramaQuer dizer
CaixaUma entidade (tabela)
Linha dentro da caixaUm atributo (coluna)
PKChave primária
FKChave estrangeira
Dois riscos na pontaUm (e exatamente um)
Pé de galinha na pontaMuitos
Círculo na pontaZero (opcional)
Caixa no meio com duas FKsTabela de ligação (muitos-para-muitos)

Exercícios

1. No DER, o que é uma "entidade"?

2. O símbolo "pé de galinha" na ponta de uma linha quer dizer:

3. Você vê, no DER, uma caixa pequena no meio com duas FKs e pé de galinha dos dois lados. É sinal de:

4. A ponta certa

Um cliente tem muitos pedidos. Do lado da tabela pedidos, qual símbolo vai na ponta da linha? Escreva muitos ou um:

lado de pedidos:

Experimente: leia as setas do diagrama

Missão: liste todas as setas do DER do Aurora: uma linha por chave estrangeira, com a tabela de origem e a tabela para onde ela aponta. Use pragma_foreign_key_list juntado com sqlite_schema. Devem vir 7 linhas.

SELECT name FROM sqlite_schema WHERE type = 'table';
SELECT m.name AS tabela, f."table" AS aponta_para
FROM sqlite_schema AS m
JOIN pragma_foreign_key_list(m.name) AS f
WHERE m.type = 'table'
ORDER BY m.name, f."table";

Missão final: desenhe (em tabelas) um muitos-para-muitos

Missão: um aluno faz vários cursos e um curso tem vários alunos. Crie as três tabelas desse DER — alunos, cursos e a tabela de ligação matriculas (com as duas chaves estrangeiras) — e, no fim, liste as tabelas para onde matriculas aponta (devem ser duas: alunos e cursos).

-- crie alunos, cursos e matriculas (com 2 FKs)
-- depois: SELECT "table" FROM pragma_foreign_key_list('matriculas');

SELECT 'monte as três tabelas acima';
CREATE TABLE alunos (id INTEGER PRIMARY KEY, nome TEXT);
CREATE TABLE cursos (id INTEGER PRIMARY KEY, titulo TEXT);
CREATE TABLE matriculas (
  aluno_id INTEGER REFERENCES alunos(id),
  curso_id INTEGER REFERENCES cursos(id),
  PRIMARY KEY (aluno_id, curso_id)
);
SELECT "table" AS aponta_para
FROM pragma_foreign_key_list('matriculas')
ORDER BY "table";

Resumo

  • Um DER é a planta do banco: entidades (caixas = tabelas) e relacionamentos (linhas = ligações por chave estrangeira).
  • Dentro da caixa vão os atributos, com a PK e as FK marcadas.
  • A cardinalidade está nas pontas, na notação pé de galinha: dois riscos = um, pé de galinha = muitos, círculo = zero (opcional).
  • Um muitos-para-muitos aparece como uma caixa de ligação no meio, com duas FKs e pé de galinha dos dois lados — no Aurora, a itens_pedido.
  • Dá para "ler o DER" direto do banco com pragma_foreign_key_list.