20-Popular um banco de dados completo
Materiais desta aula
20 — Popular um banco de dados completo
1. Por que popular um banco?
Popular um banco é preencher as tabelas com dados. Nos Encontros 17 a 19 você aprendeu os comandos (INSERT, UPDATE, DELETE) e treinou com poucas linhas. Hoje o objetivo é diferente: transformar um banco vazio em um banco completo, com dados suficientes para fazermos perguntas a ele.
Pense numa biblioteca: as estantes (tabelas) já existem, mas se não houver livros nelas, não há o que procurar. A partir do Encontro 21 vamos consultar o banco (SELECT, filtros, ordenação, junções, totais). Se hoje a carga ficar errada, as consultas vão dar respostas erradas — por isso hoje o foco é carregar certo e conferir.
2. O banco loja
É a Loja de Roupas do Encontro 19, que cresceu: agora são 5 tabelas.
| Tabela | O que guarda | Chaves |
|---|---|---|
categoria | tipos de produto (camisetas, calças...) | PK id_categoria (AUTO_INCREMENT) |
produto | o que a loja vende | PK id_produto (AUTO_INCREMENT); FK categoria_id → categoria |
cliente | quem compra | PK id_cliente (AUTO_INCREMENT); cpf único |
pedido | uma compra de um cliente | PK id_pedido (AUTO_INCREMENT); FK cliente_id → cliente |
item_pedido | cada produto dentro de um pedido | PK composta (pedido_id, produto_id); FKs para pedido e produto |
Novidade em relação aos Encontros 17 a 19: as chaves primárias id_... agora são AUTO_INCREMENT (explicado na seção 3). A única PK sem AUTO_INCREMENT é a de item_pedido, formada por duas FKs.
Mudanças em relação ao Encontro 19: produto ganhou estoque e categoria_id (e perdeu tamanho); cliente ganhou cidade e data_nascimento; pedido ganhou forma_pagamento.
3. AUTO_INCREMENT: o MySQL numera para você
Nos Encontros 17 a 19 você digitava o id de cada linha (VALUES (1, 'Camisetas')). Isso tem um risco: duas pessoas (ou o mesmo comando executado duas vezes) podem usar o mesmo número, e o MySQL responde com o erro 1062 (registro duplicado).
Pense na senha numerada do atendimento de um banco ou de um mercado: você não escolhe o número, a máquina entrega o próximo. O AUTO_INCREMENT ("incrementar automaticamente") faz isso com o id: a cada linha nova, o MySQL coloca o próximo número (1, 2, 3...). É o jeito usado na grande maioria dos sistemas: ninguém digita id à mão.
Na criação da tabela, aparece assim (já está nos scripts de hoje):
CREATE TABLE categoria (
id_categoria INT PRIMARY KEY AUTO_INCREMENT,
nome VARCHAR(40) NOT NULL
);
Como muda o INSERT: o id fica de fora da lista de colunas e dos valores.
-- antes (Encontros 17 a 19): você digitava o id
INSERT INTO categoria (id_categoria, nome) VALUES (1, 'Camisetas');
-- agora: o MySQL gera o id
INSERT INTO categoria (nome) VALUES ('Camisetas');
Descobrindo o id que foi gerado
Se o id é gerado pelo MySQL, como saber qual número ele recebeu? Consulte a tabela. Isso importa porque a FK de outra tabela precisa desse número:
INSERT INTO categoria (nome) VALUES ('Camisetas'), ('Calcas'), ('Acessorios'), ('Agasalhos');
SELECT * FROM categoria;
| id_categoria | nome |
|---|---|
| 1 | Camisetas |
| 2 | Calcas |
| 3 | Acessorios |
| 4 | Agasalhos |
Os números saem na ordem em que as linhas foram inseridas. Para inserir um produto de calças, o valor de categoria_id será 2, porque é o id que o MySQL deu a Calcas. Por isso, hoje as planilhas seguem uma ordem fixa: se você inserir na mesma ordem, os números serão os mesmos do professor.
Três regras do AUTO_INCREMENT
- Não digite o id no INSERT: liste só as outras colunas.
- O contador só avança. Se uma linha for apagada, ou se um INSERT der erro, aquele número não é reaproveitado: ficam "buracos" na numeração (1, 2, 4, 5...). Isso é normal e inofensivo.
- Nunca presuma o id: antes de usá-lo como FK, confira com
SELECT.
Pergunta para pensar: se o id agora não repete, o INSERT de uma categoria pode dar o erro 1062 por repetir o id? E se eu rodar o mesmo INSERT duas vezes, o que acontece? (Resposta na seção 6.)
4. Por onde começar? O mapa de dependências
Uma tabela com FK depende de outra: ela só aceita valores que já existem na tabela "pai" (erro 1452, visto no Encontro 17). Então a ordem da carga não é um palpite — dá para descobri-la olhando as FKs, em níveis:
- Nível 1 — não dependem de ninguém:
categoriaecliente. - Nível 2 — dependem de uma tabela do nível 1:
produto(de categoria) epedido(de cliente). - Nível 3 — dependem de tabelas do nível 2:
item_pedido(de pedido e de produto).
Como construir um prédio: primeiro a fundação, depois os andares, por último o acabamento. Dentro de um mesmo nível, a ordem entre as tabelas tanto faz.
5. Da planilha ao INSERT: traduzindo os formatos
Os dados quase nunca chegam prontos para o MySQL. Chegam numa planilha, numa lista, num cadastro em papel — escritos do jeito brasileiro. Antes de digitar, traduza:
| Na planilha | No INSERT | Regra |
|---|---|---|
| Camiseta Basica | 'Camiseta Basica' | texto entre aspas simples |
| 39,90 | 39.90 | decimal com ponto, sem aspas |
| 14/03/1998 | '1998-03-14' | data no formato 'AAAA-MM-DD', entre aspas |
| 123.456.789-01 | '12345678901' | CPF só com dígitos, entre aspas (CHAR, não número) |
| (vazio) ou — | NULL | sem aspas |
Exemplo completo — duas linhas da planilha de produtos (sem a coluna id, que o MySQL gera):
| nome | preço | estoque | categoria (nº) |
|---|---|---|---|
| Camiseta Basica | 39,90 | 50 | 1 |
| Camiseta Estampada | 59,90 | 30 | 1 |
vira um único INSERT com os grupos separados por vírgula (visto no Encontro 17):
INSERT INTO produto (nome, preco, estoque, categoria_id)
VALUES ('Camiseta Basica', 39.90, 50, 1),
('Camiseta Estampada', 59.90, 30, 1);
Confira a ordem das colunas: cada valor tem que cair na coluna certa. O id_produto ficou de fora: o MySQL gera o 1 e o 2.
6. Erros que aparecem ao popular
Quando se carregam muitos dados, alguns erros são campeões. Já sabemos ler mensagens de erro (Encontro 19): comando → resposta → por quê → correção.
6.1 Erro 1062 — valor repetido numa coluna UNIQUE
Com o AUTO_INCREMENT, o id não repete mais. Mas o erro 1062 continua possível em qualquer coluna UNIQUE, como o cpf de cliente (duas pessoas não têm o mesmo CPF):
INSERT INTO cliente (nome, cpf, cidade, data_nascimento)
VALUES ('Marina Alves', '12345678901', 'Vilhena', '1998-03-14');
-- (rodado uma segunda vez)
-- Error Code: 1062. Duplicate entry '12345678901' for key 'cliente.cpf'
Aconteceu porque o comando foi executado duas vezes (ou o CPF já existia). O MySQL recusa o comando inteiro e nada é alterado. Correção: não rodar de novo; olhar o que já está lá com SELECT * FROM cliente;.
6.2 Sem erro, mas duplicado: o INSERT repetido numa tabela sem UNIQUE
E se o INSERT repetido for numa tabela sem coluna UNIQUE, como categoria?
INSERT INTO categoria (nome) VALUES ('Camisetas');
INSERT INTO categoria (nome) VALUES ('Camisetas'); -- rodou de novo
SELECT * FROM categoria;
| id_categoria | nome |
|---|---|
| 1 | Camisetas |
| 2 | Camisetas |
Não dá erro. Como o id é novo, o MySQL aceita: agora existem duas "Camisetas" com ids diferentes. É por isso que o AUTO_INCREMENT não substitui a conferência: conte as linhas depois de cada tabela. Para remover a linha repetida, use o DELETE com a chave no WHERE (Encontro 18): DELETE FROM categoria WHERE id_categoria = 2;. Para recomeçar do zero, rode o script de estrutura.
6.3 O contador não volta atrás
Depois do DELETE acima, o próximo INSERT em categoria recebe o id 3, e não 2. O mesmo vale quando um INSERT dá erro (como o 1062 do CPF): o número que ele ia usar também é "queimado". É normal: o id é só uma identificação, não uma contagem de linhas. Para saber quantas linhas existem, use SELECT COUNT(*).
6.4 Erro 1292 — data em formato brasileiro
INSERT INTO cliente (nome, cpf, cidade, data_nascimento)
VALUES ('Marina Alves', '12345678901', 'Vilhena', '14/03/1998');
-- Error Code: 1292. Incorrect date value: '14/03/1998' for column 'data_nascimento' at row 1
O MySQL só entende datas como AAAA-MM-DD. Correção: 1998-03-14.
6.5 Erro 1406 — valor grande demais para a coluna
... VALUES ('Marina Alves', '123.456.789-01', ...);
-- Error Code: 1406. Data too long for column 'cpf' at row 1
cpf é CHAR(11): cabem 11 caracteres, e 123.456.789-01 tem 14 (com pontos e traço). Correção: só os dígitos, '12345678901'.
6.6 Erro 1136 — a vírgula decimal vira dois valores
INSERT INTO produto (nome, preco, estoque, categoria_id)
VALUES ('Camiseta Basica', 39,90, 50, 1);
-- Error Code: 1136. Column count doesn't match value count at row 1
No MySQL a vírgula separa valores. 39,90 virou dois valores (39 e 90), e o comando ficou com 5 valores para 4 colunas. Correção: 39.90.
7. Conferir cada tabela antes de seguir
Hábito de quem carrega dados: depois de cada tabela, confira.
SELECT * FROM produto;
Olhe a faixa de resultado: ela diz quantas linhas vieram (ex.: 12 row(s) returned). Compare com o esperado. Se não bate, descubra o motivo antes de seguir para a próxima tabela: um erro na tabela-pai vai estourar na tabela-filha (erro 1452), e linhas a mais indicam que algum INSERT rodou duas vezes (seção 6.2). Confira também se os ids gerados são os esperados (SELECT * FROM categoria;), pois as FKs dependem deles.
Total esperado ao final da carga: categoria 4 · produto 12 · cliente 10 · pedido 20 · item_pedido 38.
8. Carregando por script
Para grandes volumes, ninguém digita: usa-se um script (arquivo .sql). Hoje você vai digitar categoria, produto e cliente (para treinar a tradução de formatos) e rodar o script encontro_20_loja_02_pedidos.sql, que carrega pedido e item_pedido. Esse script só funciona se as três primeiras tabelas estiverem certas (e com os ids esperados, por isso você inseriu na ordem da planilha) — ele é, ao mesmo tempo, um teste do seu trabalho: se der erro 1452, falta algo nas tabelas-pai. Rode-o uma única vez: como o id dos pedidos é gerado pelo AUTO_INCREMENT, rodá-lo duas vezes duplicaria os 20 pedidos; se isso acontecer, recrie o banco com o script de estrutura e refaça a carga.
9. Teste de conferência e gancho para o próximo bloco
Rode, no loja, estas consultas (ainda não vamos estudá-las — só rode):
SELECT nome, preco FROM produto WHERE preco > 100;
Resultado esperado: 5 linhas — Calca Jeans (119.90), Calca Social (139.90), Jaqueta Jeans (159.90), Moletom com Capuz (129.90) e Casaco de La (189.90).
SELECT COUNT(*) FROM pedido WHERE data_pedido >= '2026-10-01';
Resultado esperado: 9.
Se os resultados forem iguais, seu banco está igual ao do professor. E uma pergunta para os próximos encontros: qual cliente comprou mais itens no total? Para responder, será preciso juntar três tabelas e somar. Você vai conseguir fazer isso até o fim do bloco de consultas.
10. Banco-padrão para as próximas aulas
Nos próximos encontros usaremos os mesmos dados, para que os resultados batam com os slides. Por isso, ao final deste encontro, rode o script encontro_20_loja_completo.sql: ele recria o banco loja completo. Assim, qualquer diferença que ficou na sua carga (ou os dados extras do desafio) some, e os contadores do AUTO_INCREMENT voltam ao início.
11. Prévia do próximo encontro
No Encontro 21 começa o bloco de consultas (DQL): SELECT básico e a cláusula WHERE no banco loja que você acabou de popular.
Vídeos sobre o assunto
- Curso MySQL — INSERT, UPDATE e DELETE — CursoemVideo, mesma série dos encontros anteriores.
Para se aprofundar
- ERROR 1062: Duplicate entry — Bytebase — explica o erro de registro duplicado (em inglês).