Douglas Legramante

Douglas Legramante

Informática

Técnico em Informática · Banco de Dados

20-Popular um banco de dados completo

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.

TabelaO que guardaChaves
categoriatipos de produto (camisetas, calças...)PK id_categoria (AUTO_INCREMENT)
produtoo que a loja vendePK id_produto (AUTO_INCREMENT); FK categoria_id → categoria
clientequem compraPK id_cliente (AUTO_INCREMENT); cpf único
pedidouma compra de um clientePK id_pedido (AUTO_INCREMENT); FK cliente_id → cliente
item_pedidocada produto dentro de um pedidoPK 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_categorianome
1Camisetas
2Calcas
3Acessorios
4Agasalhos

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

  1. Não digite o id no INSERT: liste só as outras colunas.
  2. 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.
  3. 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: categoria e cliente.
  • Nível 2 — dependem de uma tabela do nível 1: produto (de categoria) e pedido (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 planilhaNo INSERTRegra
Camiseta Basica'Camiseta Basica'texto entre aspas simples
39,9039.90decimal 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 —NULLsem aspas

Exemplo completo — duas linhas da planilha de produtos (sem a coluna id, que o MySQL gera):

nomepreçoestoquecategoria (nº)
Camiseta Basica39,90501
Camiseta Estampada59,90301

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_categorianome
1Camisetas
2Camisetas

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

Para se aprofundar