DROP, TRUNCATE e Boas Praticas
Comandos destrutivos do SQL
Existem tres formas de remover dados ou estrutura no SQL: DELETE, TRUNCATE e DROP. Cada um tem um nivel diferente de destruicao, e confundir eles pode causar problemas serios.
DELETE: Remove linhas especificas
Voce ja conhece o DELETE das aulas anteriores. Ele remove linhas e aceita WHERE para filtrar:
-- Remove apenas alunos de Curitiba
DELETE FROM alunos WHERE cidade = 'Curitiba';
-- Remove TODAS as linhas (cuidado!)
DELETE FROM alunos;
Caracteristicas do DELETE:
- Aceita WHERE para filtrar
- Pode ser revertido com ROLLBACK (dentro de uma transacao)
- Dispara triggers
- Mais lento para grandes volumes de dados
TRUNCATE TABLE: Limpa todos os dados
TRUNCATE remove todas as linhas da tabela de uma vez. Nao aceita WHERE.
-- Remove todos os dados, mas mantem a tabela
TRUNCATE TABLE alunos;
-- Reseta o contador do SERIAL/auto-increment
TRUNCATE TABLE alunos RESTART IDENTITY;
Caracteristicas do TRUNCATE:
- Remove TODAS as linhas (sem WHERE)
- Muito mais rapido que DELETE para tabelas grandes
- Reseta o auto-increment (com RESTART IDENTITY)
- Nao dispara triggers de linha
- A tabela continua existindo, so fica vazia
DROP TABLE: Remove a tabela inteira
DROP remove a tabela por completo: estrutura, dados, indices, constraints; tudo.
-- Remove a tabela completamente
DROP TABLE matriculas;
-- Remove so se existir (evita erro)
DROP TABLE IF EXISTS matriculas;
A tabela deixa de existir. Para usar novamente, voce precisa recria-la com CREATE TABLE.
DROP DATABASE: Remove o banco inteiro
O mais destrutivo de todos:
-- Remove o banco de dados inteiro (MUITO cuidado!)
DROP DATABASE IF EXISTS escola;
Comparacao: DELETE vs TRUNCATE vs DROP
| Caracteristica | DELETE | TRUNCATE | DROP |
|---|---|---|---|
| O que remove | Linhas especificas | Todas as linhas | A tabela inteira |
| Aceita WHERE | Sim | Nao | N/A |
| Tabela continua existindo | Sim | Sim | Nao |
| Velocidade | Lento (linha a linha) | Rapido | Rapido |
| Reseta auto-increment | Nao | Sim (RESTART IDENTITY) | N/A |
| Dispara triggers | Sim | Nao (por linha) | Nao |
Boas Praticas no dia-a-dia
Essas sao as praticas que vao evitar dor de cabeca quando voce trabalhar com bancos de dados em projetos reais.
1. Sempre use WHERE no DELETE e UPDATE
-- ERRADO: apaga TODOS os alunos
DELETE FROM alunos;
-- CERTO: apaga apenas o aluno especifico
DELETE FROM alunos WHERE id = 5;
-- ERRADO: muda a cidade de TODOS
UPDATE alunos SET cidade = 'Curitiba';
-- CERTO: muda apenas o aluno 5
UPDATE alunos SET cidade = 'Curitiba' WHERE id = 5;
2. Teste DELETE/UPDATE com SELECT antes
Antes de rodar um DELETE ou UPDATE, troque o comando por SELECT com o mesmo WHERE. Isso mostra quais linhas serao afetadas sem mudar nada:
-- Primeiro, veja quem vai ser afetado
SELECT * FROM alunos WHERE cidade = 'Curitiba';
-- So depois, se estiver correto, rode o DELETE
DELETE FROM alunos WHERE cidade = 'Curitiba';
3. Use snake_case para nomes
-- CERTO: snake_case, minusculo
CREATE TABLE historico_notas (
aluno_id INTEGER,
nota_final DECIMAL(4,2),
data_avaliacao DATE
);
-- EVITE: camelCase, PascalCase, espacos
CREATE TABLE "HistoricoNotas" (
"alunoId" INTEGER,
"notaFinal" DECIMAL(4,2)
);
4. Use NOT NULL para campos obrigatorios
Se um campo deve sempre ter valor, marque como NOT NULL. Isso evita dados incompletos:
CREATE TABLE alunos (
id SERIAL PRIMARY KEY,
nome VARCHAR(100) NOT NULL, -- obrigatorio
email VARCHAR(150) NOT NULL, -- obrigatorio
telefone VARCHAR(20), -- opcional (pode ser NULL)
cidade VARCHAR(100) NOT NULL DEFAULT 'Nao informada'
);
5. Evite SELECT * em producao
-- EVITE: traz tudo, inclusive colunas que voce nao precisa
SELECT * FROM alunos;
-- PREFIRA: apenas as colunas necessarias
SELECT nome, email, cidade FROM alunos;
Motivos para evitar SELECT *:
- Gasta mais memoria e banda de rede
- Pode expor dados sensiveis (senhas, tokens)
- Dificulta entender o que a consulta realmente precisa
- Quebra se alguem adicionar/remover colunas
6. Crie indices em colunas usadas no WHERE e JOIN
-- Se voce filtra por cidade frequentemente:
CREATE INDEX idx_alunos_cidade ON alunos(cidade);
-- Se voce faz JOIN por aluno_id frequentemente:
CREATE INDEX idx_matriculas_aluno_id ON matriculas(aluno_id);
7. Faca backup antes de comandos destrutivos
Antes de rodar DROP, TRUNCATE, ou DELETE sem WHERE em producao, faca backup:
# Backup de um banco PostgreSQL
pg_dump nome_do_banco > backup_2025_03_30.sql
# Restaurar o backup
psql nome_do_banco < backup_2025_03_30.sql
8. Use transacoes para operacoes criticas
-- Comeca a transacao
BEGIN;
-- Faz as alteracoes
DELETE FROM matriculas WHERE curso_id = 5;
DELETE FROM cursos WHERE id = 5;
-- Se tudo esta certo:
COMMIT;
-- Se algo deu errado:
ROLLBACK;
Resumo de seguranca
| Comando | Nivel de perigo | Reversivel? |
|---|---|---|
| SELECT | Nenhum | N/A (so leitura) |
| INSERT/UPDATE/DELETE | Medio | Sim, com ROLLBACK em transacao |
| TRUNCATE | Alto | Depende do banco |
| DROP TABLE | Muito alto | Nao (precisa backup) |
| DROP DATABASE | Critico | Nao (precisa backup) |
Exercicios
- Explique com suas palavras a diferenca entre DELETE, TRUNCATE e DROP.
- Escreva o SELECT que voce rodaria antes de executar:
DELETE FROM alunos WHERE nota < 5. - Crie uma tabela
produtoscom boas praticas: snake_case, NOT NULL nos campos obrigatorios, valor padrao onde faz sentido. - Crie um indice na coluna
cidadeda tabelaalunos. - Escreva uma transacao que apaga um curso e todas as matriculas relacionadas a ele.
Referencias
- DROP TABLE - PostgreSQL Docs -- documentacao oficial
- TRUNCATE - PostgreSQL Docs -- documentacao oficial
- SQL Performance Best Practices -- guia completo sobre indices e performance
- Curso SQL #12 - Boas Praticas -- Curso em Video
Testa o que você leu
5 perguntas sobre esta aula. Errar aqui não custa nada - a explicação vem junto da correção.