Conteúdo principal
Programação
Curso: Programação > Unidade 3
Lição 3: Consultas relacionais em SQL- Separando dados em tabelas relacionadas
- Associando tabelas relacionadas com JOIN
- Desafios: Os hobbies de Bobby
- Associando tabelas relacionadas com left outer joins
- Desafio: Pedidos dos clientes
- Associando tabelas a elas mesmas com self-joins
- Desafio: Sequências em SQL
- Combinando várias associações
- Projeto: Pessoas famosas
- SQL mais eficiente com otimização e planejamento de consulta
© 2023 Khan AcademyTermos de usoPolítica de privacidadeAviso de cookies
Separando dados em tabelas relacionadas
Até agora, trabalhamos com apenas uma tabela por vez e vimos que dados interessantes podemos selecionar a partir da tabela. Mas na verdade, na maioria das vezes, temos nossos dados distribuídos em várias tabelas e essas tabelas estão "relacionadas" umas às outras de alguma forma.
Por exemplo, vamos supor que temos uma tabela para registrar o quão bem os alunos se saem em suas provas e vamos incluir e-mails caso precisemos entrar em contato com seus pais devido a notas ruins:
nome_aluno | email_aluno | prova | nota |
---|---|---|---|
Peter Rabbit | peter@rabbit.com | Nutrição | 95 |
Alice Wonderland | alice@wonderland.com | Nutrição | 92 |
Peter Rabbit | peter@rabbit.com | Química | 85 |
Alice Wonderland | alice@wonderland.com | Química | 95 |
Também podemos ter uma tabela para registrar quais livros cada aluno lê:
nome_aluno | título_livro | autor_livro |
---|---|---|
Peter Rabbit | The Tale of Mrs. Tiggy-Winkle | Beatrix Potter |
Peter Rabbit | Jabberwocky | Lewis Carroll |
Alice Wonderland | The Hunting of the Snark | Lewis Carroll |
Alice Wonderland | Jabberwocky | Lewis Carroll |
Também podemos ter uma tabela apenas para informações detalhadas do aluno:
id | primeiro_nome | sobrenome | email_aluno | telefone | nascimento |
---|---|---|---|---|---|
1 | Pedro | Coelho | peter@rabbit.com | 555-6666 | 2001-05-10 |
2 | Alice | Wonderland | alice@wonderland.com | 555-4444 | 2001-04-02 |
O que você acha dessas tabelas? Você as alteraria de alguma forma?
Há uma coisa importante sobre essas tabelas: elas estão descrevendo dados relacionais - elas estão descrevendo dados relacionados entre si. Cada uma dessas tabelas descreve dados relacionados a um aluno específico e muitas delas replicam os mesmos dados. Quando o mesmo dado está replicado em várias tabelas, pode haver consequências interessantes.
Por exemplo, e se um aluno trocasse de e-mail? Que tabelas precisaríamos alterar?
Precisaríamos alterar a tabela de informações sobre o aluno, mas como também incluímos esse dado na tabela de notas, também precisaríamos encontrar todas as linhas sobre esse aluno e alterar o e-mail em todas elas.
Geralmente é preferível garantir que uma coluna específica de dados está armazenada apenas em um único local, assim há menos locais para atualizar e menos riscos de ter dados diferentes em locais diferentes. Se fizermos isso, precisamos garantir que tenhamos uma forma de relacionar os dados entre as tabelas, e veremos isso mais tarde.
Vamos supor que decidimos remover o e-mail das tabelas de nota, porque percebemos que esse dado é redundante com o e-mail na tabela de detalhes sobre o aluno. É isso que teríamos:
nome_aluno | prova | nota |
---|---|---|
Peter Rabbit | Nutrição | 95 |
Alice Wonderland | Nutrição | 92 |
Peter Rabbit | química | 85 |
Alice Wonderland | química | 95 |
Como poderíamos descobrir o e-mail de cada aluno? Poderíamos encontrar a linha na tabela de informações sobre o aluno com o nome correspondente. E se dois alunos tivessem o mesmo nome? (Você sabia que em Bali só existem 4 nomes e cada pessoa só pode ter um deles?) Não podemos confiar no nome para encontrar um aluno e, na verdade, nunca devemos confiar em algo como um nome para identificar algo único em uma tabela.
Assim, o melhor a fazer é substituir
nome_aluno
por id_aluno
, já que este é um identificador único:id_aluno | prova | nota |
---|---|---|
1 | Nutrição | 95 |
2 | Nutrição | 92 |
1 | Química | 85 |
2 | Química | 95 |
Nós poderíamos fazer a mesma mudança na nossa tabela de livros, usando
student_id
ao invés de student_name
:id_aluno | título_livro | autor_livro |
---|---|---|
1 | The Tale of Mrs. Tiggy-Winkle | Beatrix Potter |
1 | Jabberwocky | Lewis Carroll |
2 | The Hunting of the Snark | Lewis Carroll |
2 | Jabberwocky | Lewis Carroll |
Percebe que temos o título e o autor repetidos duas vezes para Jabberwocky? Esse é outro sinal de alerta de que podemos dividir nossa tabela em várias tabelas relacionadas, assim não precisamos atualizar vários locais se algo sobre um livro for alterado.
Poderíamos ter uma tabela apenas sobre livros:
id | título_livro | autor_livro |
---|---|---|
1 | The Tale of Mrs. Tiggy-Winkle | Beatrix Potter |
2 | Jabberwocky | Lewis Carroll |
3 | The Hunting of the Snark | Lewis Carroll |
E então nossa tabela
livros_aluno
fica assim:id_aluno | id_livro |
---|---|
1 | 1 |
1 | 2 |
2 | 3 |
2 | 2 |
Eu sei, essa tabela não é tão legível quanto a antiga, que tinha toda a informação armazenada em cada linha. Mas, geralmente, as tabelas não são concebidas para serem lidas por humanos - elas são concebidas para armazenar dados da melhor forma possível, com a maior facilidade de manutenção e da forma menos propensa a erros. Em muitos casos, pode ser melhor dividir as informações em várias tabelas relacionadas, assim há menos dados redundantes e menos locais para atualizar.
É importante compreender como usar SQL para lidar com dados reais que foram divididos em várias tabelas relacionadas e juntar os dados das tabelas quando for necessário. Isso é feito usando um conceito chamado "join"s e é isso que vamos lhe mostrar a seguir.
Quer participar da conversa?
- Teria algum material de boas práticas para criação de tabelas?(14 votos)
- Existe sim, se chama normalização de dados, é um processo que se faz depois que se criou as tabelas, ai vc vai normalizando elas, removendo o que é desnecessário ou que atrapalha.
https://pt.wikipedia.org/wiki/Normaliza%C3%A7%C3%A3o_de_dados(23 votos)
- O id na tabela de livros, não deveria de ser id_livro?(7 votos)
- Não necessariamente, pois livros é uma tabela independente das outras.(7 votos)
- qual seria a biografia adequada para a continuidade desse material?(5 votos)
- Existe algum caso em que seria melhor para a otimização do código eu deixar de seguir as normas?(4 votos)
- Existe sim, principalmente quando trabalhamos com B.I, aí temos que deixar de normatizar as tabelas. Quando estamos trabalhamos com tabelas multidimensionais (cubos), a normalização das tabelas ficam em segundo plano no grau de importância.(2 votos)
- Não consigo passar no parte 2 do desafio Os hobbies de Bobby, mas o resultado está correto. O que está faltando?
select persons.name, hobbies.name from persons
join hobbies
on persons.id = hobbies.person_id;(1 voto) - Em todas a tabelas posso somente utilizar o conceito id para busca?(1 voto)
- Pode, mas acho que de vez em quando é preciso utilizar outros meios também, mas o id é sempre aconselhável(0 votos)
- Porque em vez de criar varias tabelas e relaciona-las ente si ,não se cria somente uma tabela com todos os dados deixando apenas os dados necessários?(0 votos)
- então eu sempre tenho que utilizar id em minhas tabelas e focar as pequisas no id e quando precisar unir busco sempre pelo id?(0 votos)
- Não necessariamente, mas é que deste modo fica mais fácil para trabalhar com os dados(0 votos)