postgres postgresql database db
Como visto antes, uma instância do PostgreSQL é a unidade sobre a qual operamos para fins de administração de sistemas, como monitoramento, replicação, autenticação e backup. Contudo, essa não é a granularidade adequada para os fins da aplicação, que tem um interesse mais voltado à manipulação (armazenamento e consulta) dos dados.
Um banco de dados é uma segmentação tanto física quanto lógica da instância, destinada a um propósito único, como atender uma aplicação específica. Isso significa que os dados são armazenados fisicamente em outros diretórios (segmentação física) e que conexões são estabelecidas com exatamente um banco de dados e não têm acesso aos dados de outros bancos de dados (segmentação lógica).
Podem ser criados objetos locais dentro de um banco de dados, como tabelas, visões, índices e sequências. Contudo, objetos globais, como usuários, tablespaces, slots de replicação e outros bancos de dados, apesar de poderem ser criados através de uma conexão com um banco de dados, não são criados dentro daquele banco de dados, mas sim na instância.
┌───────────────────┐ ╔════════════════════╡ instância/cluster ╞═════════════════════╗ ║ └───────────────────┘ ║ ╠═╡global/╞═══════╗ ╔═════════════════════════════════╡base/╞═╣ ║ ║ ║ ║ ║ O O ║ ║ ┏┥banco de dados┝┓ ┏━┥banco de dados┝━┓ ║ ║ ─┼─ ─┼─ ║ ║ ┃└┤postgres├────┘┃ ┃ ┌─┤schema├─────┐ ┃ ║ ║ │ │ ║ ║ ┗━━━━━━━━━━━━━━━━┛ ┃ │ ☑ tabelas │ ┃ ║ ║ ╱ ╲ ╱ ╲ ║ ║ ┏┥banco de dados┝┓ ┃ │ ☑ índices │ ┃ ║ ║ ☑ usuários ║ ║ ┃└┤template1├───┘┃ ┃ │ ☑ visões │ ┃ ║ ║ ☑ grupos ║ ║ ┗━━━━━━━━━━━━━━━━┛ ┃ │ ☑ sequências │ ┃ ║ ║ ☑ slots de ║ ║ ┏┥banco de dados┝┓ ┃ │ ☑ … │ ┃ ║ ║ ☑ replicação ║ ║ ┃└┤template0├───┘┃ ┃ └──────────────┘ ┃ ║ ║ ☑ pg_control ║ ║ ┗━━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━━┛ ║ ║ ║ ║ ║ ╠═════════════════╝ ╚═════════════════════════════════════════╣ ║ ║ ╠═╡pg_wal/╞══════════════════════════╗ ╔══════╡pg_tblspc/╞═╣ ║ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ║ ║ ║ ║ │…++++│→│…++++│→│…++++│→│…++++│→… ║ ║ ║ ║ └┤/…1├┘ └┤/…2├┘ └┤/…3├┘ └┤/…4├┘ ║ ║ │ ║ ╚════════════════════════════════════╩═════╩════════╪══════════╝ │ ↓ ╔╡/…╞╗ ║ ║ ╚════╝
É necessário que exista um banco de dados e um usuário para que a
autenticação permita a nova conexão. É necessária uma conexão
ativa para criar um banco de dados e um usuário. Para quebrar esse impasse de
galinha-e-ovo, toda nova instância é criada automaticamente com um banco de
dados chamado postgres
e um usuário com permissão SUPERUSER (este com nome
igual ao usuário que executou o initdb
, normalmente também postgres
).
O propósito do usuário postgres
e do banco de dados postgres
é, portanto,
permitir que outros usuários e bancos de dados sejam criados. É recomendado que
eles não sejam usados para outros fins, mas sim que outros usuários (com permissões
reduzidas) e bancos de dados sejam usados para atender as diversas aplicações,
assim como atividades de backup, monitoramento e replicação.
Ao criar um novo banco de dados, o PostgreSQL sempre copia um modelo
pré-existente. Quando o modelo não é informado, o template1
é usado. Isso não
só traz agilidade na criação de bancos de dados, como também permite que o
usuário customize os modelos, adicionando objetos e dados que são importados em
todo novo banco de dados e economizando tempo de criá-los em todo novo banco de
dados.
O terceiro banco de dados criado com a inicialização da instância é o
template0
, que atende dois propósitos. Por um lado, ele pode ser usado para
recriar o template1
se as customizações deste precisarem ser descartadas. Por
outro, o template0
é o único banco de dados com a codificação de caracteres
indefinida e, por essa razão, quando é copiado, uma codificação pode ser
escolhida para o novo banco de dados.
IMPORTANTE: Note que a codificação recomendada para todos os propósitos no
servidor é UTF8
(outras são mantidas para compatibilidade com o passado); e a
aplicação deve configurar client_encoding
para cada conexão, assim conversões
entre codificações de cliente e servidor são feitas de forma transparente e
confiável.
Listagem dos bancos de dados existentes, com seus respectivos donos, codificações, privilégios, tamanhos e outras propriedades:
[[local]:5432] postgres@postgres=# \l+ List of databases ╔═══════════╤═══════════╤══════════╤═════════╤═════════╤═══════════════════════╤═════════╤════════════╤════════════════════════════════════════════╗ ║ Name │ Owner │ Encoding │ Collate │ Ctype │ Access privileges │ Size │ Tablespace │ Description ║ ╠═══════════╪═══════════╪══════════╪═════════╪═════════╪═══════════════════════╪═════════╪════════════╪════════════════════════════════════════════╣ ║ postgres │ postgres │ UTF8 │ C.UTF-8 │ C.UTF-8 │ │ 8097 kB │ pg_default │ default administrative connection database ║ ║ template0 │ postgres │ UTF8 │ C.UTF-8 │ C.UTF-8 │ =c/postgres ↵│ 7841 kB │ pg_default │ unmodifiable empty database ║ ║ │ │ │ │ │ postgres=CTc/postgres │ │ │ ║ ║ template1 │ postgres │ UTF8 │ C.UTF-8 │ C.UTF-8 │ postgres=CTc/postgres↵│ 7953 kB │ pg_default │ default template for new databases ║ ║ │ │ │ │ │ =c/postgres │ │ │ ║ ╚═══════════╧═══════════╧══════════╧═════════╧═════════╧═══════════════════════╧═════════╧════════════╧════════════════════════════════════════════╝
É possível impedir conexões novas a um banco de dados alterando a propriedade
ALLOW_CONNNECTIONS
, mas conexões já estabelecidas permanecem, podendo ser
fechadas com pg_terminate_backend()
:
[[local]:5432] postgres@postgres=# ALTER DATABASE app ALLOW_CONNECTIONS FALSE;
Também é possível limitar quantas conexões um banco de dados terá estabelecidas a todo momento:
[[local]:5432] postgres@postgres=# ALTER DATABASE app CONNECTION LIMIT 5;
Por padrão, apenas usuários com a permissão de SUPERUSER
podem usar todos os bancos de dados como modelos na criação de novos bancos de dados. Mas podemos marcar bancos de dados específicos com a propriedade IS_TEMPLATE
para que todo usuário com permissão CREATEDB
possa usar aquele banco de dados como modelo:
[[local]:5432] postgres@postgres=# ALTER DATABASE modelo IS_TEMPLATE TRUE;
[[local]:5432] postgres@postgres=# CREATE DATABASE app;
[[local]:5432] postgres@postgres=# CREATE DATABASE modelo_app; [[local]:5432] postgres@postgres=# \c modelo_app [[local]:5432] postgres@modelo_app=# CREATE TABLE tabela (); [[local]:5432] postgres@modelo_app=# \d List of relations ╔════════╤════════╤═══════╤══════════╗ ║ Schema │ Name │ Type │ Owner ║ ╠════════╪════════╪═══════╪══════════╣ ║ public │ tabela │ table │ postgres ║ ╚════════╧════════╧═══════╧══════════╝
[[local]:5432] postgres@postgres=# CREATE DATABASE app TEMPLATE modelo_app; [[local]:5432] postgres@postgres=# \c app [[local]:5432] postgres@app=# \d List of relations ╔════════╤════════╤═══════╤══════════╗ ║ Schema │ Name │ Type │ Owner ║ ╠════════╪════════╪═══════╪══════════╣ ║ public │ tabela │ table │ postgres ║ ╚════════╧════════╧═══════╧══════════╝
[[local]:5432] postgres@postgres=# DROP DATABASE modelo_app; [[local]:5432] postgres@postgres=# DROP DATABASE app;