15%

Poupe 15% em todos os serviços

Teste as suas habilidades e obtenha Desconto em qualquer plano

Utilizar o código:

Skills
Começar a trabalhar
24.10.2024

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 postgres

Uma vez ligado:

l

Isto 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 5432

Ou utilizando o atalho c dentro de uma sessão existente:

c myapp_db appuser

Isto é 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âmetroFinalidadeValor de Exemplo
sslmodeNível de imposição TLSrequire, verify-full
connect_timeoutSegundos antes de a ligação falhar10
application_nameIdentifica o cliente em pg_stat_activitymyapp_worker
optionsPassa 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

psql

Em 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:strongpassword

Defina as permissões corretamente ou o PostgreSQL ignorará o ficheiro:

chmod 600 ~/.pgpass

Comparação: Métodos de Mudança de Base de Dados

MétodoContextoRequer Novo ProcessoSuporta Mudança de UtilizadorScriptável
q + psql -dShellSimSimSim
c dbnamepsql interativoNão (psql trata disso)SimLimitado
URI de ligaçãoShell / AppSimSimSim
Variáveis de ambienteShellSimSimSim
pgAdmin GUICliente GUINãoSimNão
Pool de ligações (PgBouncer)AplicaçãoNãoDepende do modoSim

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.

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 DadosFinalidadeSeguro para Ligar?Seguro para Modificar?
postgresBase de dados de administração padrãoSimCom precaução
template1Modelo para CREATE DATABASESimSim, as alterações propagam-se
template0Modelo de linha de base limpoRaramenteNão
pg_catalogNão é uma base de dados, é um esquemaN/ANunca

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-256

Após editar pg_hba.conf, recarregue a configuração sem reiniciar o servidor:

sudo systemctl reload postgresql

Ou 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 dbname dentro do psql. 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 -A para saída limpa.
  • Aplicação a ligar a uma base de dados: Utilize um URI de ligação com sslmode=require e um pool de ligações (PgBouncer ou pooling integrado no driver).
  • Aplicação que necessita de dados de duas bases de dados: Implemente postgres_fdw na 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_name para personificar a função de destino sem sair do psql.
  • Provisionamento automatizado / infraestrutura-como-código: Utilize variáveis de ambiente ou .pgpass com 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_connections em postgresql.conf para 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.

15%

Poupe 15% em todos os serviços

Teste as suas habilidades e obtenha Desconto em qualquer plano

Utilizar o código:

Skills
Começar a trabalhar