Suporte a Banco de Dados - Guia de MySQL & PostgreSQL
Banco de Dados · Do Zero ao SQL
Guia Prático de MySQL & PostgreSQL
Do login no console até consultas avançadas com JOIN — um roteiro prático para quem está começando.
// 01
Conectando ao MySQL via Console
Instalação
Escolha o comando conforme seu sistema operacional:
# Windows — baixe o instalador em mysql.com/downloads
# Linux (Ubuntu/Debian)
sudo apt update && sudo apt install mysql-server
# Mac
brew install mysql
Iniciando o serviço
# Windows (PowerShell como administrador)
net start MySQL80
# Linux
sudo systemctl start mysql
sudo systemctl status mysql # verifica se está rodando
# Mac
brew services start mysql
Conectando
# Forma básica
mysql -u root -p
# Já entrando em um banco específico
mysql -u root -p nome_do_banco
# Servidor remoto
mysql -h 192.168.1.100 -u root -p
# Porta diferente da padrão (3306)
mysql -u root -p -P 3307
Após digitar o comando, o terminal pedirá a senha. É normal não aparecer nada enquanto você digita — isso é intencional por segurança.
Comandos essenciais dentro do console
-- Listar todos os bancos
SHOW DATABASES;
-- Selecionar um banco
USE nome_do_banco;
-- Listar tabelas do banco atual
SHOW TABLES;
-- Ver estrutura de uma tabela
DESCRIBE Cliente;
-- Ver qual banco está em uso
SELECT DATABASE();
-- Ver usuário conectado
SELECT USER();
-- Sair
EXIT;
Criando banco e usuário
-- Criando banco com suporte a caracteres especiais (acentos)
CREATE DATABASE loja
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
-- Criando usuário
CREATE USER 'elton'@'localhost' IDENTIFIED BY 'senha123';
-- Concedendo permissões
GRANT ALL PRIVILEGES ON loja.* TO 'elton'@'localhost';
FLUSH PRIVILEGES;
Executando um arquivo .sql
# Antes de conectar
mysql -u root -p loja < /projetos/criar_tabelas.sql
# Já dentro do console
source /projetos/criar_tabelas.sql
// 02
Conectando ao PostgreSQL via Console
Instalação
# Windows — baixe em postgresql.org/download
# Linux (Ubuntu/Debian)
sudo apt update && sudo apt install postgresql postgresql-contrib
# Mac
brew install postgresql
Iniciando o serviço
# Windows (PowerShell como administrador)
net start postgresql-x64-15
# Linux
sudo systemctl start postgresql
sudo systemctl status postgresql
# Mac
brew services start postgresql
Conectando — o console se chama psql
# Forma básica
psql -U postgres
# Já entrando em um banco específico
psql -U postgres -d nome_do_banco
# Servidor remoto
psql -h 192.168.1.100 -U postgres -d nome_do_banco
# No Linux pode ser necessário usar o usuário do sistema
sudo -u postgres psql
Comandos essenciais — começam com \ (barra invertida)
-- Listar todos os bancos
\l
-- Conectar a um banco
\c nome_do_banco
-- Listar tabelas
\dt
-- Ver estrutura de uma tabela
\d Cliente
-- Listar usuários
\du
-- Limpar a tela
\! clear (Linux/Mac)
\! cls (Windows)
-- Sair
\q
Criando banco e usuário
CREATE DATABASE loja
ENCODING 'UTF8';
CREATE USER elton WITH PASSWORD 'senha123';
GRANT ALL PRIVILEGES ON DATABASE loja TO elton;
-- Conectar ao banco recém criado
\c loja
Executando um arquivo .sql
# Antes de conectar
psql -U postgres -d loja -f /projetos/criar_tabelas.sql
# Já dentro do psql
\i /projetos/criar_tabelas.sql
// 03
MySQL vs PostgreSQL — Comparativo
🐬 MySQL
- Mais simples de configurar
- Muito popular em aplicações web
- Amplamente usado com PHP/WordPress
- Console:
mysql - Porta padrão:
3306 - Listar bancos:
SHOW DATABASES - Listar tabelas:
SHOW TABLES - Ver tabela:
DESCRIBE tabela - Trocar banco:
USE banco - Rodar arquivo:
source arq.sql
🐘 PostgreSQL
- Mais robusto e completo
- Melhor para dados complexos
- Preferido em sistemas corporativos
- Console:
psql - Porta padrão:
5432 - Listar bancos:
\l - Listar tabelas:
\dt - Ver tabela:
\d tabela - Trocar banco:
\c banco - Rodar arquivo:
\i arq.sql
| Critério | MySQL | PostgreSQL |
|---|---|---|
| Facilidade inicial | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| Recursos avançados | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Velocidade em leitura | Muito boa | Muito boa |
| Suporte a JSON | Básico | Avançado (JSONB) |
| Mercado de trabalho | Muito alto | Alto |
| Gratuito | ✅ Sim | ✅ Sim |
Para quem está aprendendo: os comandos SQL são praticamente os mesmos nos dois bancos. Aprenda um e você saberá o outro. As diferenças estão nos comandos do console e em recursos avançados.
// 04
Modelagem das Entidades
Antes de criar qualquer tabela, precisamos planejar quais entidades existem no sistema e como elas se relacionam. Nosso projeto é um sistema de compras com quatro entidades:
👤 Cliente
- idPK
- nome
- telefone
- rua
- numero
- bairro
- cidade
- estado
- cep
🛒 Compras
- id_compraPK
- data
- id_clienteFK
- total
- status
- forma_pagamento
📦 Produtos
- id_produtoPK
- nome
- descricao
- preco
- estoque
- categoria
📋 Itens
- id_itemPK
- id_compraFK
- id_produtoFK
- quantidade
- preco_unitario
Relacionamentos
Cliente (1) ────────< Compras (N)
Compras (1) ────────< Itens (N)
Produtos (1) ────────< Itens (N)
Itens resolve o relacionamento N:N entre Compras e Produtos
Por que separar o endereço em vários campos? Um campo único como "Rua das Flores, 123, Centro, São Paulo" impede filtrar por cidade ou CEP. Campos separados permitem buscas, relatórios e futuras integrações com sistemas de entrega.
Por que preco_unitario em Itens? O preço de um produto pode mudar ao longo do tempo. Esse campo "congela" o valor exato no momento da venda, preservando o histórico correto.
// 05
Tipos de Dados e Conceitos Essenciais
Tipos de dados mais usados
| Tipo | Uso | Exemplo |
|---|---|---|
INT | Números inteiros | id, quantidade, estoque |
DECIMAL(10,2) | Números com casas decimais | preço, total |
VARCHAR(n) | Texto de tamanho variável | nome, email, status |
TEXT | Texto longo | descrição, observações |
CHAR(n) | Texto de tamanho fixo | estado (2), cep (9) |
DATE | Só a data | 2024-01-15 |
DATETIME | Data e hora | 2024-01-15 14:30:00 |
BOOLEAN | Verdadeiro ou falso | ativo, aprovado |
Constraints (Restrições)
| Constraint | O que faz |
|---|---|
PRIMARY KEY | Identifica unicamente cada linha. Não pode repetir nem ser nulo. |
FOREIGN KEY | Garante que o valor exista na tabela referenciada. |
NOT NULL | O campo não pode ficar vazio. |
UNIQUE | O valor não pode se repetir na tabela. |
DEFAULT | Define um valor automático se nada for informado. |
AUTO_INCREMENT | Gera um número sequencial automaticamente (MySQL). No PostgreSQL use SERIAL. |
// 06
CREATE TABLE — Criando as Tabelas
A ordem de criação importa: tabelas referenciadas por chaves estrangeiras devem existir antes.
1º Cliente →
2º Produtos →
3º Compras →
4º Itens
-- ─── 1. Cliente (sem dependências) ───────────────
CREATE TABLE Cliente (
id INT AUTO_INCREMENT PRIMARY KEY,
nome VARCHAR(100) NOT NULL,
telefone VARCHAR(20),
rua VARCHAR(150),
numero VARCHAR(10),
bairro VARCHAR(80),
cidade VARCHAR(80),
estado CHAR(2),
cep CHAR(9)
);
-- ─── 2. Produtos (sem dependências) ──────────────
CREATE TABLE Produtos (
id_produto INT AUTO_INCREMENT PRIMARY KEY,
nome VARCHAR(100) NOT NULL,
descricao TEXT,
preco DECIMAL(10,2) NOT NULL,
estoque INT DEFAULT 0,
categoria VARCHAR(60)
);
-- ─── 3. Compras (depende de Cliente) ─────────────
CREATE TABLE Compras (
id_compra INT AUTO_INCREMENT PRIMARY KEY,
data DATETIME DEFAULT CURRENT_TIMESTAMP,
id_cliente INT NOT NULL,
total DECIMAL(10,2) DEFAULT 0,
status VARCHAR(20) DEFAULT 'pendente',
forma_pagamento VARCHAR(30),
FOREIGN KEY (id_cliente) REFERENCES Cliente(id)
);
-- ─── 4. Itens (depende de Compras e Produtos) ────
CREATE TABLE Itens (
id_item INT AUTO_INCREMENT PRIMARY KEY,
id_compra INT NOT NULL,
id_produto INT NOT NULL,
quantidade INT NOT NULL,
preco_unitario DECIMAL(10,2) NOT NULL,
FOREIGN KEY (id_compra) REFERENCES Compras(id_compra),
FOREIGN KEY (id_produto) REFERENCES Produtos(id_produto)
);
PostgreSQL: substitua
INT AUTO_INCREMENT PRIMARY KEY por SERIAL PRIMARY KEY — o resto do script funciona igual.
// 07
INSERT — Inserindo Dados
Sintaxe básica
INSERT INTO nome_da_tabela (coluna1, coluna2)
VALUES (valor1, valor2);
Respeite a ordem: insira primeiro as tabelas que não dependem de ninguém (Cliente e Produtos), depois Compras e por último Itens.
Inserindo Clientes
-- Vários registros de uma vez
INSERT INTO Cliente (nome, telefone, rua, numero, bairro, cidade, estado, cep)
VALUES
('João Silva', '11 99999-0000', 'Rua das Flores', '123', 'Centro', 'São Paulo', 'SP', '01001-000'),
('Maria Souza', '11 98888-1111', 'Av. Paulista', '456', 'Bela Vista', 'São Paulo', 'SP', '01310-000'),
('Carlos Oliveira','11 97777-2222', 'Rua XV de Novembro', '78', 'Centro', 'Curitiba', 'PR', '80020-310'),
('Ana Costa', '19 96666-3333', 'Rua do Comércio', '90', 'Centro', 'Campinas', 'SP', '13010-050');
Inserindo Produtos
INSERT INTO Produtos (nome, descricao, preco, estoque, categoria)
VALUES
('Notebook Dell', 'Intel i5, 8GB RAM, 256GB SSD', 3200.00, 15, 'Informática'),
('Mouse Logitech', 'Mouse sem fio, 1000 DPI', 89.90, 50, 'Periféricos'),
('Teclado Mecânico', 'Switch Blue, ABNT2', 250.00, 30, 'Periféricos'),
('Monitor 24"', 'Full HD, 75Hz, IPS', 1100.00, 10, 'Informática');
Inserindo Compras
-- id_cliente refere os ids gerados na tabela Cliente
INSERT INTO Compras (id_cliente, status, forma_pagamento)
VALUES
(1, 'pago', 'cartão'), -- João → id_compra = 1
(2, 'pendente', 'pix'), -- Maria → id_compra = 2
(1, 'pago', 'dinheiro'); -- João → id_compra = 3 (segunda compra)
Inserindo Itens
-- Itens da compra 1 (João: notebook + 2 mouses)
INSERT INTO Itens (id_compra, id_produto, quantidade, preco_unitario)
VALUES
(1, 1, 1, 3200.00), -- 1 Notebook
(1, 2, 2, 89.90); -- 2 Mouses
-- Itens da compra 2 (Maria: teclado + monitor)
INSERT INTO Itens (id_compra, id_produto, quantidade, preco_unitario)
VALUES
(2, 3, 1, 250.00), -- 1 Teclado
(2, 4, 1, 1100.00); -- 1 Monitor
-- Itens da compra 3 (João: só um mouse)
INSERT INTO Itens (id_compra, id_produto, quantidade, preco_unitario)
VALUES
(3, 2, 1, 89.90);
Erros comuns
| Mensagem de erro | Causa | Solução |
|---|---|---|
| Cannot add or update a child row | id_cliente não existe em Cliente | Cadastre o cliente primeiro |
| Column cannot be null | Campo NOT NULL ficou vazio | Informe um valor |
| Duplicate entry | id repetido | Não informe o id, deixe AUTO_INCREMENT |
| Data too long | Texto maior que o VARCHAR | Aumente o tamanho do campo |
// 08
SELECT com JOIN — Consultando Dados
O JOIN une tabelas para que você possa cruzar informações em uma única consulta. Sem ele, cada consulta retorna apenas os dados de uma tabela — com ids sem significado.
Tipos de JOIN
| Tipo | O que retorna |
|---|---|
INNER JOIN | Somente registros com correspondência nos dois lados |
LEFT JOIN | Todos da esquerda + correspondências da direita (NULL se não houver) |
RIGHT JOIN | Todos da direita + correspondências da esquerda |
INNER JOIN — Compras com nome do cliente
SELECT
c.id_compra,
cl.nome AS cliente,
c.data,
c.status,
c.forma_pagamento
FROM Compras c
INNER JOIN Cliente cl ON cl.id = c.id_cliente;
JOIN com três tabelas — Nota fiscal completa
SELECT
cl.nome AS cliente,
c.id_compra,
c.data,
c.forma_pagamento,
p.nome AS produto,
i.quantidade,
i.preco_unitario,
(i.quantidade * i.preco_unitario) AS subtotal
FROM Itens i
INNER JOIN Compras c ON c.id_compra = i.id_compra
INNER JOIN Cliente cl ON cl.id = c.id_cliente
INNER JOIN Produtos p ON p.id_produto = i.id_produto
ORDER BY c.id_compra, p.nome;
LEFT JOIN — Clientes que nunca compraram
SELECT
cl.nome AS cliente,
c.id_compra,
c.status
FROM Cliente cl
LEFT JOIN Compras c ON c.id_cliente = cl.id;
-- Carlos e Ana aparecerão com NULL em id_compra e status
GROUP BY — Total gasto por cliente
SELECT
cl.nome AS cliente,
COUNT(c.id_compra) AS total_compras,
SUM(i.quantidade * i.preco_unitario) AS valor_total
FROM Cliente cl
LEFT JOIN Compras c ON c.id_cliente = cl.id
LEFT JOIN Itens i ON i.id_compra = c.id_compra
GROUP BY cl.id, cl.nome
ORDER BY valor_total DESC;
Produtos mais vendidos
SELECT
p.nome AS produto,
SUM(i.quantidade) AS qtd_vendida,
SUM(i.quantidade * i.preco_unitario) AS receita_total
FROM Itens i
INNER JOIN Produtos p ON p.id_produto = i.id_produto
GROUP BY p.id_produto, p.nome
ORDER BY qtd_vendida DESC;
WHERE + JOIN — Filtrando resultado
-- Apenas compras pagas
SELECT
cl.nome AS cliente,
c.id_compra,
c.forma_pagamento,
SUM(i.quantidade * i.preco_unitario) AS total
FROM Compras c
INNER JOIN Cliente cl ON cl.id = c.id_cliente
INNER JOIN Itens i ON i.id_compra = c.id_compra
WHERE c.status = 'pago'
GROUP BY c.id_compra, cl.nome, c.forma_pagamento;
// 09
UPDATE e DELETE — Alterando e Removendo
Regra de ouro: SEMPRE use
WHERE no UPDATE e no DELETE. Sem ele, você altera ou apaga todos os registros da tabela de uma vez.
UPDATE — Sintaxe básica
UPDATE nome_da_tabela
SET coluna1 = valor1, coluna2 = valor2
WHERE condição;
Exemplos de UPDATE
-- Atualizando um campo simples
UPDATE Cliente
SET telefone = '11 91111-2222'
WHERE id = 1;
-- Atualizando vários campos ao mesmo tempo
UPDATE Cliente
SET
rua = 'Rua Augusta',
numero = '200',
bairro = 'Consolação'
WHERE id = 2;
-- Mudando status de uma compra
UPDATE Compras
SET
status = 'pago',
forma_pagamento = 'cartão'
WHERE id_compra = 2;
-- Aplicando 10% de desconto no Mouse Logitech
UPDATE Produtos
SET preco = preco * 0.90
WHERE id_produto = 2;
-- Recalculando total da compra a partir dos itens reais
UPDATE Compras
SET total = (
SELECT SUM(quantidade * preco_unitario)
FROM Itens
WHERE id_compra = 1
)
WHERE id_compra = 1;
UPDATE com JOIN
-- Reduzindo estoque após a compra 1
UPDATE Produtos p
INNER JOIN Itens i ON i.id_produto = p.id_produto
SET p.estoque = p.estoque - i.quantidade
WHERE i.id_compra = 1;
DELETE — Sintaxe básica
DELETE FROM nome_da_tabela
WHERE condição;
A ordem importa no DELETE
Ao contrário do INSERT, no DELETE você deve apagar primeiro as tabelas dependentes:
1º Itens →
2º Compras →
3º Clientes / Produtos
-- ERRADO: dará erro pois Itens ainda referenciam a compra
DELETE FROM Compras WHERE id_compra = 1;
-- CERTO: apaga os itens primeiro, depois a compra
DELETE FROM Itens WHERE id_compra = 1;
DELETE FROM Compras WHERE id_compra = 1;
TRUNCATE — apagando todos os registros
-- Apaga tudo e reinicia o AUTO_INCREMENT
TRUNCATE TABLE Itens;
| DELETE sem WHERE | TRUNCATE | |
|---|---|---|
| Velocidade | Mais lento | Mais rápido |
| AUTO_INCREMENT | Mantém o último id | Reinicia do 1 |
| Pode usar WHERE | ✅ Sim | ❌ Não |
| Pode desfazer | ✅ Com transaction | ❌ Não |
Transactions — sua rede de segurança
-- Inicia o rascunho
START TRANSACTION;
DELETE FROM Itens WHERE id_compra = 3;
DELETE FROM Compras WHERE id_compra = 3;
-- Confirma — torna permanente
COMMIT;
-- Ou desfaz tudo se algo der errado
ROLLBACK;
Antes de qualquer UPDATE ou DELETE, faça primeiro um
SELECT com o mesmo WHERE para confirmar quais registros serão afetados. Só depois execute a operação.
Comentários
Postar um comentário
Ficou com alguma dúvida? Quer compartilhar sua experiência? Tem uma sugestão de
melhoria? Seu comentário é muito importante!