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
- CREATE DATABASE para criar um banco de dados
- DROP DATABASE para remover um banco de dados
- ALTER DATABASE para modificar propriedades do banco de dados
- Bancos de dados modelo (template0 / template1)
- Conjunto de caracteres e collation
- Meta-comandos do psql: \l / \c
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:
- dev: collation em inglês (conveniente para desenvolvimento)
- staging: UTF8 + collation em inglês (consistente com produção)
- prod: UTF8 + uma collation específica (mercado do Oriente Médio, precisa de suporte a árabe)
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:
-- 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
- Cada ambiente tem seu próprio banco de dados independente; os dados não interferem
- Conjunto de caracteres unificado para UTF8, suportando dados multilíngues
- Collation corresponde à necessidade do negócio, então a ordem dos resultados da consulta está correta
3. Fundamentos do Banco de Dados
(1) Hierarquia Organizacional do PostgreSQL
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 |
4. CREATE DATABASE
(1) Sintaxe Básica
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
-- Criar um banco de dados simples com configurações padrão
CREATE DATABASE my_app;
-- Verificar criação
\l
Output:
CREATE TABLE
▶ Exemplo: Criar um Banco de Dados com Parâmetros Completos
-- 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:
CREATE TABLE
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) |
▶ Exemplo: Pré-Configurar um Banco de Dados com Modelos
-- 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:
CREATE TABLE
▶ Exemplo: Reconstruir Codificação com template0
-- 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:
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
-- 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:
-- instrução SQL executada com sucesso
-- 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
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
-- 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:
-- 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
-- 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:
id | name | value
----+----------+-------
1 | example | 42
(1 row)
▶ Exemplo: Como a Collation Afeta os Resultados da Consulta
-- 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:
-- 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
# 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:
# comando executado com sucesso
10. Exemplo Completo: Configuração de Banco de Dados para Três Ambientes
-- ============================================
-- 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:
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 = template0em 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
- CREATE DATABASE cria um banco de dados, suportando codificação/collation/modelo/proprietário/limite de conexão
- template0 é um modelo puro (não modificável); template1 é um modelo personalizável (o padrão)
- Instale extensões no template1 e novos bancos de dados as herdam automaticamente
- ALTER DATABASE pode renomear, definir parâmetros e alterar o proprietário
- DROP DATABASE é irreversível; IF EXISTS previne erros, WITH (FORCE) força desconexão
- Sempre use codificação UTF8; escolha a collation com base nas necessidades do negócio
- Meta-comandos do psql:
\llista bancos de dados,\calterna banco de dados,\conninfomostra informações da conexão
📝 Exercícios
-
Básico (★): Crie um banco de dados chamado
my_bookstoreusando codificação UTF8, depois verifique com\lque foi criado e, finalmente, remova-o. -
Intermediário (★★): Primeiro instale a extensão
uuid-osspno template1, depois crie um novo banco de dadostest_templatee verifique se o novo banco de dados herdou automaticamente a extensão uuid-ossp. -
Desafio (★★★): Crie dois bancos de dados usando as collations
Ceen_US.utf8respectivamente. 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.