Como criar um banco de dados PostgreSQL do zero
Tutorial prático para criar banco, tabelas, relacionamentos, índices, usuários, backup e consultas no PostgreSQL.
Erlan Carreira
Engenheiro de Software & Empreendedor
Um banco de dados útil não começa no comando CREATE DATABASE, mas nas regras que os dados precisam preservar. Este tutorial usa PostgreSQL e um exemplo de clientes e pedidos para mostrar criação, relacionamento, consulta, segurança e backup.
Resposta direta
Instale PostgreSQL, crie um banco e um usuário de aplicação, conecte-se com psql, modele entidades e relacionamentos, crie tabelas com restrições, insira dados de teste, consulte com JOIN, analise índices, limite privilégios e automatize backups restauráveis.
1. Crie o banco e conecte
Com PostgreSQL instalado e serviço ativo:
createdb loja
psql lojaOu dentro de uma sessão administrativa:
CREATE DATABASE loja;Se aparecer “permission denied”, o usuário atual não possui CREATEDB. Não transforme a conta da aplicação em superusuário; peça a criação a um administrador.
2. Modele antes de criar tabelas
Regras do exemplo:
- cliente possui e-mail único;
- pedido pertence a um cliente;
- valor não pode ser negativo;
- status aceita apenas estados conhecidos;
- datas são registradas com fuso horário.
Evite armazenar lista de pedidos dentro de uma coluna de cliente. Relações e restrições tornam inconsistências mais difíceis.
3. Crie as tabelas
CREATE TABLE clientes (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
nome text NOT NULL,
email text NOT NULL UNIQUE,
criado_em timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE pedidos (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
cliente_id bigint NOT NULL REFERENCES clientes(id),
valor numeric(12,2) NOT NULL CHECK (valor >= 0),
status text NOT NULL CHECK (status IN ('pendente','pago','cancelado')),
criado_em timestamptz NOT NULL DEFAULT now()
);Use numeric para dinheiro quando precisão decimal for necessária. Não use ponto flutuante para valores financeiros. A chave estrangeira impede pedido para cliente inexistente.
4. Insira e consulte
INSERT INTO clientes (nome, email)
VALUES ('Ana', 'ana@example.com')
RETURNING id;
INSERT INTO pedidos (cliente_id, valor, status)
VALUES (1, 149.90, 'pago');
SELECT c.nome, p.id, p.valor, p.status
FROM pedidos p
JOIN clientes c ON c.id = p.cliente_id
ORDER BY p.criado_em DESC;Em aplicações, use parâmetros preparados. Nunca monte SQL concatenando texto recebido do usuário.
5. Use transações
Quando duas mudanças precisam acontecer juntas:
BEGIN;
UPDATE estoque SET quantidade = quantidade - 1
WHERE produto_id = 10 AND quantidade > 0;
INSERT INTO pedidos (cliente_id, valor, status)
VALUES (1, 149.90, 'pago');
COMMIT;O exemplo ainda precisaria verificar se o update alterou uma linha. Em erro, use ROLLBACK. Transações mantêm atomicidade, mas concorrência e isolamento precisam ser projetados conforme o processo.
6. Crie índices com evidência
Chaves primárias e UNIQUE já criam índices. Para buscar pedidos recentes de um cliente:
CREATE INDEX pedidos_cliente_criado_idx
ON pedidos (cliente_id, criado_em DESC);Valide com:
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM pedidos
WHERE cliente_id = 1
ORDER BY criado_em DESC
LIMIT 20;Cada índice ocupa espaço e encarece escrita. Não crie um índice por coluna sem observar consultas reais.
7. Separe o usuário da aplicação
CREATE ROLE loja_app LOGIN PASSWORD 'troque-por-segredo-forte';
GRANT CONNECT ON DATABASE loja TO loja_app;
GRANT USAGE ON SCHEMA public TO loja_app;
GRANT SELECT, INSERT, UPDATE, DELETE ON clientes, pedidos TO loja_app;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO loja_app;Armazene a credencial em um gerenciador de segredos, não no código. Ajuste privilégios ao que a aplicação realmente faz. Ambientes e bancos de produção e teste devem ser separados.
8. Versione migrações
Não altere produção manualmente sem registro. Crie arquivos de migração ordenados, faça revisão e teste upgrade e rollback quando possível. Mudanças grandes podem exigir expansão, migração de dados e remoção posterior para não interromper versões antigas.
9. Faça backup e teste restauração
pg_dump -Fc -d loja -f loja.dump
createdb loja_restore
pg_restore -d loja_restore loja.dumpBackup que nunca foi restaurado é apenas uma esperança. Defina frequência, retenção, criptografia, acesso, local separado e objetivos de perda aceitável e tempo de recuperação.
Checklist para produção
- restrições
NOT NULL,UNIQUE,CHECKe FKs adequadas; - migrações versionadas e testadas;
- consultas parametrizadas;
- usuário sem privilégio administrativo;
- conexões protegidas por TLS;
- pool dimensionado;
- consultas lentas monitoradas;
- backups automatizados e restauração testada;
- dados pessoais com retenção e acesso definidos.
Para aplicações multiempresa, leia arquitetura multi-tenant. Para a stack completa, veja Next.js e Supabase.
Perguntas frequentes
PostgreSQL é bom para iniciantes?
Sim. Ele oferece SQL padronizado, documentação completa e recursos que continuam úteis em sistemas grandes.
Planilha substitui banco de dados?
Planilhas atendem análise e processos pequenos. Concorrência, integridade, relacionamentos e controle de acesso normalmente justificam um banco.
Fontes primárias
Erlan Carreira
Engenheiro de Software & Empreendedor
Especialista em desenvolvimento de software, automação e SaaS. Escrevo sobre tecnologia, negócios digitais, IA e boas práticas de engenharia para times que buscam excelência na execução.