Listando e Alternando Bancos de Dados no PostgreSQL: O Guia Técnico Completo
O PostgreSQL gere múltiplas bases de dados isoladas numa única instância de servidor, cada uma com o seu próprio esquema, funções e privilégios. Para listar todas as bases de dados, execute l dentro do psql ou consulte SELECT datname FROM pg_catalog.pg_database; a partir de qualquer sessão. Para mudar de base de dados, deve abrir uma nova ligação — o PostgreSQL impõe uma vinculação estrita de sessão a base de dados, sem equivalente ao comando USE dentro da sessão.
Este guia abrange todos os métodos disponíveis para enumerar e ligar a bases de dados PostgreSQL, desde comandos psql brutos e consultas ao catálogo do sistema até strings de ligação, considerações sobre pg_hba.conf e padrões de fluxo de trabalho com múltiplas bases de dados utilizados em ambientes de produção.
Por Que a Mudança de Base de Dados no PostgreSQL Funciona de Forma Diferente
A maioria dos programadores que vêm do MySQL espera um comando USE database_name;. O PostgreSQL omite deliberadamente este comando. Cada sessão PostgreSQL está vinculada a exatamente uma base de dados no momento da ligação, e essa vinculação é imutável durante o tempo de vida da sessão. Esta é uma decisão arquitetural enraizada no modelo de processos do PostgreSQL: o processo backend (postgres) carrega o catálogo do sistema da base de dados para a memória partilhada no arranque, e mudar de catálogos a meio da sessão exigiria de qualquer forma um reinício completo do processo.
Compreender esta limitação antecipadamente evita horas de depuração e molda a forma como arquiteta ferramentas de múltiplas bases de dados, pools de ligações e configurações de aplicações.
Listar Todas as Bases de Dados no PostgreSQL
Método 1: O Meta-Comando l no psql
A forma mais rápida de enumerar bases de dados é o meta-comando l (alias: list) dentro de uma sessão interativa do psql.
psql -U postgresUma vez ligado:
lIsto produz uma tabela formatada semelhante a:
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
myapp_db | appuser | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
analytics | analyst | UTF8 | en_US.UTF-8 | en_US.UTF-8 | analyst=CTc/analyst
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |As colunas revelam mais do que apenas nomes: Encoding é importante ao migrar dados entre servidores, Collate afeta a ordem de ordenação e o comportamento dos índices, e Access privileges utiliza a notação ACL do PostgreSQL (C = CONNECT, T = TEMPORARY, c = CREATE).
Para obter detalhes alargados incluindo tablespace e limites de ligação, utilize:
l+Método 2: Consultar o Catálogo do Sistema pg_database
Para scripting, monitorização ou introspecção ao nível da aplicação, consulte diretamente a vista pg_catalog.pg_database. Isto funciona a partir de qualquer base de dados no cluster porque os catálogos do sistema são globalmente visíveis.
SELECT
datname AS database_name,
pg_catalog.pg_get_userbyid(datdba) AS owner,
pg_encoding_to_char(encoding) AS encoding,
datcollate AS collation,
datctype AS ctype,
datconnlimit AS connection_limit,
pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(datname)) AS size
FROM pg_catalog.pg_database
WHERE datistemplate = false
ORDER BY datname;Filtrar datistemplate = false exclui template0 e template1 dos resultados — esses são modelos de sistema, não bases de dados operacionais. A coluna datconnlimit é crítica em ambientes partilhados: um valor de -1 significa ilimitado, enquanto qualquer número inteiro positivo limita as ligações simultâneas a essa base de dados.
Dica de produção: Adicione pg_database_size() às suas consultas de monitorização. Uma base de dados que cresce silenciosamente além da capacidade do tablespace é uma causa comum de falhas de escrita que são difíceis de diagnosticar após o facto.
Método 3: Listar Bases de Dados Sem Entrar no psql
Para scripts de shell e pipelines de automação, pode obter a lista de bases de dados sem entrar numa sessão interativa:
psql -U postgres -c "l"Ou para uma saída limpa e analisável por scripts:
psql -U postgres -t -c "SELECT datname FROM pg_database WHERE datistemplate = false;"O sinalizador -t suprime cabeçalhos de colunas e contagens de linhas, devolvendo apenas valores brutos — ideal para encaminhar para grep, awk ou arrays Bash.
Para exportar a lista para um ficheiro:
psql -U postgres -t -A -c "SELECT datname FROM pg_database WHERE datistemplate = false;" > db_list.txt-A desativa o alinhamento de colunas, produzindo um nome de base de dados por linha.
Mudar Entre Bases de Dados no PostgreSQL
Uma vez que não pode mudar de base de dados dentro de uma sessão ativa, a abordagem correta é terminar a ligação atual e estabelecer uma nova direcionada para a base de dados desejada. Existem várias formas de o fazer eficientemente.
Método 1: Sair e Reconectar a partir do Shell
Dentro do psql, saia da sessão atual:
q
Em seguida, ligue-se à base de dados de destino:
psql -U postgres -d target_database
Método 2: Utilizar c (Connect) Dentro do psql
Este é o método mais prático para trabalho interativo. O meta-comando c fecha a ligação atual e abre uma nova para a base de dados especificada — tudo dentro da mesma sessão de terminal.
c target_database
Também pode mudar de utilizador e host simultaneamente:
c target_database admin_user localhost 5432
Sintaxe: c [database [username [host [port]]]]Quando executa c, o psql apresentará uma confirmação:
You are now connected to database "target_database" as user "postgres".Caso limite importante: Se a base de dados de destino não existir ou o utilizador atual não tiver privilégio CONNECT, o c falhará e voltará à ligação anterior. Isto é mais seguro do que parece — não ficará sem ligação, mas deve tratar isto em scripts verificando o estado de saída.
Método 3: Ligar como um Utilizador Diferente
Para ligar a uma base de dados sob uma função específica:
psql -d myapp_db -U appuser -h localhost -p 5432Ou utilizando o atalho c dentro de uma sessão existente:
c myapp_db appuserIsto é particularmente útil ao testar políticas de segurança ao nível de linha (RLS) ou verificar que os utilizadores da aplicação não podem aceder a tabelas fora do seu esquema.
Método 4: Utilizar Strings de Ligação (Formato URI)
O PostgreSQL suporta o formato URI de ligação libpq, que encapsula todos os parâmetros de ligação numa única string. Este é o método preferido para configuração de aplicações, pipelines CI/CD e ferramentas de infraestrutura-como-código.
psql "postgresql://appuser:password@localhost:5432/myapp_db"Ou utilizando o esquema postgres:// (ambos são válidos):
psql "postgres://appuser:password@db.example.com:5432/analytics?sslmode=require"O parâmetro ?sslmode=require impõe encriptação TLS na ligação — um requisito inegociável para qualquer base de dados exposta além do localhost. Se estiver a hospedar o PostgreSQL num VPS ou servidor dedicado, combine sempre as strings de ligação com sslmode=require ou sslmode=verify-full e um certificado SSL válido.
Parâmetros de URI de ligação a ter em conta:
| Parâmetro | Finalidade | Valor de Exemplo |
|---|---|---|
sslmode | Nível de imposição TLS | require, verify-full |
connect_timeout | Segundos antes de a ligação falhar | 10 |
application_name | Identifica o cliente em pg_stat_activity | myapp_worker |
options | Passa parâmetros GUC do lado do servidor | -c search_path=myschema |
Método 5: Utilizar psql com Variáveis de Ambiente
Para ligações repetidas ao mesmo cluster, defina variáveis de ambiente para evitar digitar credenciais repetidamente:
export PGHOST=localhost
export PGPORT=5432
export PGUSER=postgres
export PGPASSWORD=secret # Use .pgpass file in production instead
export PGDATABASE=myapp_db
psqlEm produção, utilize um ficheiro .pgpass em vez de PGPASSWORD para evitar expor credenciais no histórico do shell ou nas listas de processos:
# ~/.pgpass format: hostname:port:database:username:password
localhost:5432:myapp_db:appuser:strongpasswordDefina as permissões corretamente ou o PostgreSQL ignorará o ficheiro:
chmod 600 ~/.pgpassComparação: Métodos de Mudança de Base de Dados
| Método | Contexto | Requer Novo Processo | Suporta Mudança de Utilizador | Scriptável |
|---|---|---|---|---|
q + psql -d | Shell | Sim | Sim | Sim |
c dbname | psql interativo | Não (psql trata disso) | Sim | Limitado |
| URI de ligação | Shell / App | Sim | Sim | Sim |
| Variáveis de ambiente | Shell | Sim | Sim | Sim |
| pgAdmin GUI | Cliente GUI | Não | Sim | Não |
| Pool de ligações (PgBouncer) | Aplicação | Não | Depende do modo | Sim |
Gerir Múltiplas Ligações a Bases de Dados Eficientemente
Utilizar o pgAdmin para Navegação Baseada em GUI
O pgAdmin lista todas as bases de dados sob cada servidor registado na árvore de objetos do lado esquerdo. Clicar numa base de dados e abrir a Ferramenta de Consulta delimita automaticamente todas as consultas a essa base de dados. Isto é útil para trabalho exploratório, mas não é adequado para automação.
Armadilha: O pgAdmin mantém slots de ligação separados por base de dados. Se o seu servidor PostgreSQL tiver uma definição max_connections baixa (o padrão é 100), abrir muitas bases de dados no pgAdmin pode esgotar o pool de ligações antes mesmo de a sua aplicação iniciar.
Utilizar o PgBouncer para Pool de Ligações
Em ambientes de produção com mudanças frequentes de base de dados, um pool de ligações como o PgBouncer reduz drasticamente a sobrecarga. O PgBouncer opera em três modos:
- Modo de sessão: Uma ligação de servidor por sessão de cliente. Funcionalmente equivalente a ligações diretas.
- Modo de transação: A ligação ao servidor é mantida apenas durante uma transação. Mais eficiente para cargas de trabalho OLTP.
- Modo de instrução: Ligação devolvida após cada instrução. Incompatível com transações de múltiplas instruções.
Ao executar múltiplas bases de dados de aplicações numa única instância PostgreSQL — um padrão comum em alojamento VPS ou VPS com cPanel — o PgBouncer em modo de transação pode reduzir os processos backend ativos por uma ordem de magnitude.
Consultas Entre Bases de Dados com dblink e postgres_fdw
Uma vez que as sessões têm âmbito de base de dados, consultar dados entre bases de dados requer uma extensão. O PostgreSQL fornece duas opções:
dblink — abordagem mais antiga e procedural:
SELECT * FROM dblink(
'dbname=analytics user=analyst host=localhost',
'SELECT user_id, event_count FROM events WHERE date = current_date'
) AS remote(user_id INT, event_count BIGINT);postgres_fdw — Foreign Data Wrapper moderno e compatível com padrões:
CREATE EXTENSION postgres_fdw;
CREATE SERVER analytics_server
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host 'localhost', dbname 'analytics', port '5432');
CREATE USER MAPPING FOR appuser
SERVER analytics_server
OPTIONS (user 'analyst', password 'secret');
CREATE FOREIGN TABLE remote_events (
user_id INT,
event_count BIGINT
)
SERVER analytics_server
OPTIONS (schema_name 'public', table_name 'events');Após a configuração, remote_events comporta-se como uma tabela local. O postgres_fdw suporta pushdown de predicados, o que significa que as cláusulas WHERE são executadas no servidor remoto, não localmente — uma distinção de desempenho crítica para grandes conjuntos de dados.
Bases de Dados do Sistema: O Que Não Deve Tocar
O PostgreSQL é fornecido com quatro bases de dados em cada cluster novo:
| Base de Dados | Finalidade | Seguro para Ligar? | Seguro para Modificar? |
|---|---|---|---|
postgres | Base de dados de administração padrão | Sim | Com precaução |
template1 | Modelo para CREATE DATABASE | Sim | Sim, as alterações propagam-se |
template0 | Modelo de linha de base limpo | Raramente | Não |
pg_catalog | Não é uma base de dados, é um esquema | N/A | Nunca |
template1 é clonado sempre que executa CREATE DATABASE sem especificar um modelo. Se instalar extensões ou criar esquemas em template1, cada nova base de dados herda-os. Isto é útil para padronizar ambientes, mas perigoso se feito acidentalmente.
template0 existe como um fallback imaculado. É o único modelo que pode ser utilizado ao restaurar um arquivo pg_dump com uma codificação ou localidade diferente, porque não tem objetos criados pelo utilizador que possam entrar em conflito.
Privilégios, pg_hba.conf e Falhas de Ligação
Uma fonte comum de confusão ao mudar de bases de dados é a distinção entre privilégios ao nível de função do PostgreSQL e regras de autenticação pg_hba.conf. Ambos devem permitir a ligação de forma independente.
Verificação ao nível de função: A função deve ter privilégio CONNECT na base de dados de destino:
GRANT CONNECT ON DATABASE target_database TO appuser;Verificação pg_hba.conf: O ficheiro de autenticação baseada em host (/etc/postgresql/15/main/pg_hba.conf no Debian/Ubuntu) deve ter uma regra correspondente para o utilizador, base de dados e endereço de origem. Uma entrada típica:
# TYPE DATABASE USER ADDRESS METHOD
host myapp_db appuser 10.0.0.0/8 scram-sha-256Após editar pg_hba.conf, recarregue a configuração sem reiniciar o servidor:
sudo systemctl reload postgresqlOu a partir do psql:
SELECT pg_reload_conf();Padrão de falha comum: Um utilizador tem privilégio CONNECT ao nível SQL, mas o pg_hba.conf não tem regra correspondente. A mensagem de erro (FATAL: no pg_hba.conf entry for host) é explícita, mas os programadores frequentemente ignoram o ficheiro completamente porque esperam que as permissões da base de dados sejam geridas exclusivamente através de SQL.
Matriz de Decisão Prática
Utilize esta lista de verificação para selecionar a abordagem de ligação correta para o seu cenário:
- Exploração interativa numa máquina de desenvolvimento local: Utilize
c dbnamedentro dopsql. Rápido, sem novo processo. - Script de shell a iterar sobre múltiplas bases de dados: Utilize
psql -U postgres -d $dbname -c "..."num ciclo com-t -Apara saída limpa. - Aplicação a ligar a uma base de dados: Utilize um URI de ligação com
sslmode=requiree um pool de ligações (PgBouncer ou pooling integrado no driver). - Aplicação que necessita de dados de duas bases de dados: Implemente
postgres_fdwna base de dados primária em vez de gerir dois pools de ligações separados no código da aplicação. - Verificar isolamento de RLS ou privilégios: Utilize
c dbname role_namepara personificar a função de destino sem sair dopsql. - Provisionamento automatizado / infraestrutura-como-código: Utilize variáveis de ambiente ou
.pgpasscom uma conta de serviço; nunca codifique credenciais em scripts. - Carga de trabalho de produção de alta concorrência: Implante o PgBouncer em modo de transação entre a aplicação e o PostgreSQL. Num servidor dedicado, ajuste
max_connectionsempostgresql.confpara corresponder à capacidade de memória do seu hardware (cada backend utiliza aproximadamente 5–10 MB de RAM). - SaaS multi-inquilino com bases de dados por inquilino: Considere a multi-tenancy baseada em esquemas dentro de uma única base de dados em vez de bases de dados por inquilino, para evitar a fragmentação do pool de ligações e simplificar as estratégias de backup.
Para equipas que executam o PostgreSQL juntamente com aplicações web, combinar o servidor de base de dados com um ambiente de alojamento partilhado ou VPS devidamente configurado e um domínio registado para a camada de aplicação completa a stack de produção padrão.
FAQ
Posso mudar de base de dados sem fechar a minha sessão psql?
Sim. Utilize o meta-comando c target_database dentro do psql. Fecha a ligação backend atual e abre uma nova para a base de dados especificada, tudo dentro da mesma sessão de terminal. Pode opcionalmente especificar um utilizador, host e porta diferentes no mesmo comando.
Por que o PostgreSQL não tem um comando USE como o MySQL?
A arquitetura do PostgreSQL vincula um processo backend a uma única base de dados no arranque. O catálogo do sistema da base de dados é carregado para a memória partilhada para esse processo, e mudar de catálogos a meio da sessão é arquiteturalmente equivalente a iniciar um novo processo. O comando c no psql é o equivalente prático — apenas torna o reinício do processo transparente para o utilizador.
Como consulto dados de duas bases de dados PostgreSQL diferentes simultaneamente?
Utilize a extensão postgres_fdw para criar um servidor estrangeiro e tabelas estrangeiras que mapeiam para a base de dados remota. Após a configuração, pode fazer JOIN de tabelas locais e remotas numa única consulta. Para consultas pontuais, o dblink é mais simples, mas menos eficiente e mais difícil de manter.
O que acontece se me ligar ao template1 e o modificar?
Quaisquer objetos que criar no template1 — tabelas, extensões, esquemas — serão clonados para cada nova base de dados criada com CREATE DATABASE (a menos que TEMPLATE template0 seja explicitamente especificado). Isto é por vezes intencional (por exemplo, pré-instalar uuid-ossp ou pgcrypto), mas modificações acidentais podem corromper todas as bases de dados criadas subsequentemente.
Como descubro a que base de dados uma sessão psql atual está ligada?
Execute o seguinte dentro do psql:
SELECT current_database();Ou verifique o próprio prompt psql — por padrão apresenta dbname=# (superutilizador) ou dbname=> (utilizador regular), onde dbname é a base de dados ativa.
