PostgreSQL: Criação e Gestão de Banco de Dados no PostgreSQL

Última atualização: 2026-08-26

Um banco de dados é a unidade organizacional de nível superior do PostgreSQL — como um arquivo que pode conter muitas gavetas (tabelas).

1. O Que Você Vai Aprender


2. A História Real de um Engenheiro DevOps

(1) O Problema: Três Ambientes, Três Conjuntos de Caracteres

Charlie precisa criar 3 bancos de dados para um projeto de e-commerce, correspondendo aos ambientes dev / staging / prod:

Charlie não tem certeza de como especificar o conjunto de caracteres e a collation ao criar um banco de dados e não sabe o que é um banco de dados modelo.

(2) CREATE DATABASE ao Resgate

O CREATE DATABASE do PostgreSQL permite especificar o conjunto de caracteres, a collation e o modelo no momento da criação:

SQL
-- Criar bancos de dados com locales diferentes para cada ambiente
CREATE DATABASE shop_dev
    WITH ENCODING = 'UTF8'
    LC_COLLATE = 'en_US.utf8'
    LC_CTYPE = 'en_US.utf8'
    TEMPLATE = template1;

CREATE DATABASE shop_staging
    WITH ENCODING = 'UTF8'
    LC_COLLATE = 'en_US.utf8'
    LC_CTYPE = 'en_US.utf8';

CREATE DATABASE shop_prod
    WITH ENCODING = 'UTF8'
    LC_COLLATE = 'en_US.utf8'
    LC_CTYPE = 'en_US.utf8';

(3) O Resultado


3. Fundamentos do Banco de Dados

(1) Hierarquia Organizacional do PostgreSQL

100%
graph TB
    PG[Instância PostgreSQL<br/>Um servidor em execução] --> DB1[Banco de Dados: shop_dev]
    PG --> DB2[Banco de Dados: shop_staging]
    PG --> DB3[Banco de Dados: shop_prod]
    DB1 --> SC1[Schema: public]
    SC1 --> T1[Tabela: users]
    SC1 --> T2[Tabela: orders]
    DB2 --> SC2[Schema: public]
    DB3 --> SC3[Schema: public]
Nível Descrição Cardinalidade
Instância Um processo de servidor PostgreSQL em execução 1 instância contém muitos bancos de dados
Banco de Dados O namespace independente de nível superior 1 banco de dados contém muitos schemas
Schema Um namespace dentro de um banco de dados (padrão public) 1 schema contém muitas tabelas
Tabela Uma tabela bidimensional armazenando dados Tabelas pertencem a um schema
💡 Tip: Diferente do MySQL, o "banco de dados" do PostgreSQL é mais parecido com o "Schema" do MySQL. No PG você deve especificar um banco de dados ao conectar e não pode fazer JOIN diretamente entre bancos de dados (isso precisa de FDW para consultas entre bancos de dados, abordado em uma lição posterior).


4. CREATE DATABASE

(1) Sintaxe Básica

SQL
CREATE DATABASE name
    [WITH]
    [OWNER = user_name]
    [TEMPLATE = template]
    [ENCODING = encoding_name]
    [LC_COLLATE = lc_collate]
    [LC_CTYPE = lc_ctype]
    [TABLESPACE = tablespace_name]
    [CONNECTION LIMIT = conn_limit]
    [IS_TEMPLATE = true | false];
Parâmetro Padrão Descrição
OWNER O usuário que executa Proprietário do banco de dados
TEMPLATE template1 O modelo copiado ao criar um novo banco de dados
ENCODING Codificação do modelo Codificação de caracteres (UTF8 recomendado)
LC_COLLATE Collation do modelo Ordem de classificação de strings
LC_CTYPE Classificação de caracteres do modelo Classificação de caracteres (maiúsculas/dígitos/etc.)
TABLESPACE Tablespace padrão Local de armazenamento dos arquivos de dados
CONNECTION LIMIT -1 (ilimitado) Máximo de conexões concorrentes
IS_TEMPLATE false Marcar como banco de dados modelo

▶ Exemplo: Criar um Banco de Dados Básico

SQL
-- Criar um banco de dados simples com configurações padrão
CREATE DATABASE my_app;

-- Verificar criação
\l

Output:

TEXT 📖 Somente leitura
CREATE TABLE

▶ Exemplo: Criar um Banco de Dados com Parâmetros Completos

SQL
-- Criar banco de dados com todas as opções comuns especificadas
CREATE DATABASE shop_prod
    WITH OWNER = devuser
    ENCODING = 'UTF8'
    LC_COLLATE = 'en_US.utf8'
    LC_CTYPE = 'en_US.utf8'
    CONNECTION LIMIT = 100;

Output:

TEXT 📖 Somente leitura
CREATE TABLE
⚠️ Note: CREATE DATABASE não pode ser executado dentro de uma transação (executar dentro de BEGIN...COMMIT gera erro). Isso é por design do PG — criar um banco de dados é uma operação DDL e não pode ser revertida.


5. Bancos de Dados Modelo

(1) template0 vs template1

O PostgreSQL vem com dois bancos de dados modelo integrados:

Propriedade template0 template1
Finalidade Modelo puro, não modificável Modelo personalizável, modificável
Modificável? ❌ Não ✅ Sim
Conteúdo padrão Objetos de sistema mínimos Igual ao template0 + objetos definidos pelo usuário
Quando usar Quando você precisa restaurar codificação/collation original Criação diária de banco de dados (padrão)
Criação TEMPLATE = template0 TEMPLATE = template1 (padrão)
📌 Key point: Uma vez que você cria tabelas, funções ou extensões no template1, todos os novos bancos de dados herdam esses objetos. Esta é uma maneira conveniente de pré-configurar novos bancos de dados.

▶ Exemplo: Pré-Configurar um Banco de Dados com Modelos

SQL
-- Etapa 1: Conectar ao template1 e adicionar extensões comuns
\c template1

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pg_trgm";

-- Etapa 2: Agora todos os novos bancos de dados terão essas extensões
\c postgres

CREATE DATABASE new_project;
-- new_project tem automaticamente uuid-ossp e pg_trgm

-- Etapa 3: Verificar
\c new_project
\dx

Output:

TEXT 📖 Somente leitura
CREATE TABLE

▶ Exemplo: Reconstruir Codificação com template0

SQL
-- Se template1 tem uma codificação diferente da que você precisa,
-- use template0 para criar um banco de dados com codificação específica
CREATE DATABASE db_with_latin
    TEMPLATE = template0
    ENCODING = 'LATIN1'
    LC_COLLATE = 'C'
    LC_CTYPE = 'C';

Output:

TEXT 📖 Somente leitura
CREATE TABLE

6. ALTER DATABASE

(1) Modificações Comuns

Operação Sintaxe Descrição
Renomear ALTER DATABASE old_name RENAME TO new_name Alterar o nome do banco de dados
Definir parâmetro ALTER DATABASE name SET parameter = value Definir um parâmetro de execução para o banco de dados
Redefinir parâmetro ALTER DATABASE name RESET parameter Restaurar o padrão do parâmetro
Alterar proprietário ALTER DATABASE name OWNER TO new_owner Alterar o proprietário do banco de dados
Definir limite de conexão ALTER DATABASE name CONNECTION LIMIT = n Alterar o máximo de conexões
Marcar como modelo ALTER DATABASE name IS_TEMPLATE = true Marcar / desmarcar como modelo

▶ Exemplo: Modificar Propriedades do Banco de Dados

SQL
-- Renomear um banco de dados (deve desconectar todos os usuários primeiro)
ALTER DATABASE shop_dev RENAME TO shop_development;

-- Definir search_path padrão para um banco de dados
ALTER DATABASE shop_prod SET search_path TO public, admin;

-- Definir work_mem para um banco de dados específico
ALTER DATABASE shop_prod SET work_mem = '64MB';

-- Alterar limite de conexão
ALTER DATABASE shop_prod CONNECTION LIMIT = 200;

-- Marcar como modelo
ALTER DATABASE shop_base IS_TEMPLATE = true;

Output:

TEXT 📖 Somente leitura
-- instrução SQL executada com sucesso
⚠️ Note: Antes de renomear um banco de dados, você deve desconectar todos os usuários conectados a ele. Use a seguinte consulta para ver conexões ativas:

SQL
-- Encontrar conexões ativas para um banco de dados
SELECT pid, usename, application_name, client_addr, state
FROM pg_stat_activity
WHERE datname = 'shop_dev';

7. DROP DATABASE

(1) Sintaxe de Remoção

SQL
DROP DATABASE [IF EXISTS] name [WITH (FORCE)];
Opção Descrição
IF EXISTS Sem erro se o banco de dados não existir (apenas um aviso)
WITH (FORCE) Forçar desconexão de todas as conexões e depois remover (PG 13+)

▶ Exemplo: Remover um Banco de Dados

SQL
-- Exclusão segura (sem erro se o banco de dados não existir)
DROP DATABASE IF EXISTS old_project;

-- Exclusão forçada (desconectar todos os usuários primeiro, PG 13+)
DROP DATABASE IF EXISTS shop_dev WITH (FORCE);

Output:

TEXT 📖 Somente leitura
-- instrução SQL executada com sucesso

��� Gotcha: Remover um banco de dados é irreversível! Todas as tabelas, dados e visões no banco de dados são permanentemente perdidos. Em produção, sempre faça backup antes de remover.


8. Conjunto de Caracteres e Collation

(1) Codificações de Caracteres Comuns

Codificação Descrição Cenário recomendado
UTF8 Unicode, suporta todos os idiomas Todos os projetos (recomendado)
LATIN1 Idiomas da Europa Ocidental Compatibilidade com sistemas legados
EUC_JP Japonês Sistemas legados japoneses
SQL_ASCII Sem conversão de codificação Dados puramente ASCII

(2) Comparação de Collation

Collation Comportamento Exemplo
en_US.utf8 Ordenação em inglês, sensível a maiúsculas A, a, B, b
C Ordenação por ordem de bytes, mais rápido A, B, a, b
en_US.utf8 (com ICU) Ordenação mais flexível Pode ignorar maiúsculas/acentos

▶ Exemplo: Visualizar Codificações e Collations Suportadas pelo Sistema

SQL
-- Listar codificações disponíveis
SELECT name, description FROM pg_encodings LIMIT 10;

-- Listar collations disponíveis
SELECT name, locale FROM pg_collation LIMIT 10;

Output:

TEXT 📖 Somente leitura
 id | name     | value 
----+----------+-------
  1 | example  | 42
(1 row)

▶ Exemplo: Como a Collation Afeta os Resultados da Consulta

SQL
-- Criar uma tabela de teste com dados de texto
CREATE TABLE sort_test (name TEXT);
INSERT INTO sort_test VALUES ('apple'), ('Banana'), ('cherry'), ('Apple');

-- Ordenar com locale C (ordem de bytes: maiúsculas primeiro)
SELECT name FROM sort_test ORDER BY name COLLATE "C";

-- Ordenar com en_US.utf8 (ordem de dicionário: insensível a maiúsculas dentro da mesma letra)
SELECT name FROM sort_test ORDER BY name COLLATE "en_US.utf8";

-- Limpar
DROP TABLE sort_test;

Output:

TEXT 📖 Somente leitura
-- locale C:
  Apple
  Banana
  apple
  cherry

-- en_US.utf8:
  apple
  Apple
  Banana
  cherry

9. Meta-Comandos de Gestão de Banco de Dados do psql

Comando SQL equivalente Descrição
\l SELECT * FROM pg_database Listar todos os bancos de dados
\l+ Igual, com tablespace/tamanho Listar bancos de dados em detalhes
\c dbname - Alternar para o banco de dados especificado
\conninfo - Mostrar informações da conexão atual

▶ Exemplo: Gerenciar Bancos de Dados no psql

BASH
# Listar todos os bancos de dados
\l

# Alternar para o banco de dados shop_dev
\c shop_dev

# Verificar conexão atual
\conninfo

# Voltar para o banco de dados postgres
\c postgres

Output:

TEXT 📖 Somente leitura
# comando executado com sucesso

10. Exemplo Completo: Configuração de Banco de Dados para Três Ambientes

SQL
-- ============================================
-- Exemplo completo: configurar bancos de dados dev/staging/prod
-- Para um projeto de e-commerce
-- ============================================

-- Etapa 1: Conectar ao postgres (banco de dados de manutenção)
\c postgres

-- Etapa 2: Criar banco de dados dev com locale em inglês
CREATE DATABASE shop_dev
    WITH ENCODING = 'UTF8'
    LC_COLLATE = 'en_US.utf8'
    LC_CTYPE = 'en_US.utf8'
    OWNER = devuser
    CONNECTION LIMIT = 50;

-- Etapa 3: Criar banco de dados staging (mesma configuração do prod)
CREATE DATABASE shop_staging
    WITH ENCODING = 'UTF8'
    LC_COLLATE = 'en_US.utf8'
    LC_CTYPE = 'en_US.utf8'
    OWNER = devuser
    CONNECTION LIMIT = 50;

-- Etapa 4: Criar banco de dados prod com limite de conexão
CREATE DATABASE shop_prod
    WITH ENCODING = 'UTF8'
    LC_COLLATE = 'en_US.utf8'
    LC_CTYPE = 'en_US.utf8'
    OWNER = devuser
    CONNECTION LIMIT = 200;

-- Etapa 5: Definir search_path padrão para prod
ALTER DATABASE shop_prod SET search_path TO public, admin;

-- Etapa 6: Verificar todos os bancos de dados criados
SELECT datname, pg_encoding_to_char(encoding) AS encoding,
       datcollate, datctype, datconnlimit
FROM pg_database
WHERE datname LIKE 'shop_%'
ORDER BY datname;

Output:

TEXT 📖 Somente leitura
   datname    | encoding |  datcollate  |   datctype   | datconnlimit
--------------+----------+--------------+--------------+-------------
 shop_dev     | UTF8     | en_US.utf8   | en_US.utf8   |           50
 shop_prod    | UTF8     | en_US.utf8   | en_US.utf8   |          200
 shop_staging | UTF8     | en_US.utf8   | en_US.utf8   |           50

❓ Perguntas Frequentes

P: Qual é o número máximo de bancos de dados que uma instância PostgreSQL pode criar? R: Não há limite rígido em teoria, mas cada banco de dados consome algum espaço de catálogo do sistema. Na prática, mantenha uma única instância abaixo de 100 bancos de dados. Se você precisa de mais isolamento, considere usar schemas em vez disso.

P: E se CREATE DATABASE der erro "source banco de dados is being accessed by other users"? R: Isso significa que template1 está sendo usado por outra conexão. Corrija: 1) terminando todas as sessões conectadas ao template1; ou 2) usando TEMPLATE = template0 em vez disso.

P: Qual é a diferença entre LC_COLLATE e LC_CTYPE? R: LC_COLLATE controla a ordem de classificação de strings (o resultado de ORDER BY); LC_CTYPE controla a classificação de caracteres (conversão de maiúsculas, o que conta como letra, etc.). Na maioria dos casos, defini-los iguais é suficiente.

P: A codificação de caracteres pode ser alterada após o banco de dados ser criado? R: Não diretamente. Você deve fazer pg_dump dos dados, criar um novo banco de dados com a nova codificação e depois pg_restore. É por isso que UTF8 é recomendado desde o início — ele suporta todos os idiomas.

P: Como verifico o tamanho do banco de dados atual? R: Use SELECT pg_size_pretty(pg_database_size('shop_dev')) para um único banco de dados, ou \l+ para ver os tamanhos de todos os bancos de dados.

P: Dev e prod podem compartilhar um banco de dados? R: Fortemente não recomendado. Operações durante o desenvolvimento (DROP TABLE, DELETE em lote) poderiam destruir acidentalmente dados de produção. Requisito mínimo: dev e prod usam bancos de dados diferentes, preferencialmente instâncias PG diferentes.


📖 Resumo


📝 Exercícios

  1. Básico (★): Crie um banco de dados chamado my_bookstore usando codificação UTF8, depois verifique com \l que foi criado e, finalmente, remova-o.

  2. Intermediário (★★): Primeiro instale a extensão uuid-ossp no template1, depois crie um novo banco de dados test_template e verifique se o novo banco de dados herdou automaticamente a extensão uuid-ossp.

  3. Desafio (★★★): Crie dois bancos de dados usando as collations C e en_US.utf8 respectivamente. Em cada um, crie a mesma tabela e insira os dados 'apple', 'Banana', 'cherry', 'Apple', depois use ORDER BY para comparar os resultados da ordenação e explique por que eles diferem.

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%