Você está se perguntando o que são os esquemas do Postgresql e por que eles são importantes e como você pode usar esquemas para tornar suas implementações de banco de dados mais robustas e sustentáveis? Este artigo apresentará os fundamentos dos esquemas no Postgresql e mostrará como criá-los com alguns exemplos básicos. Artigos futuros se aprofundarão em exemplos de como proteger e usar esquemas para aplicativos reais.
Em primeiro lugar, para esclarecer uma possível confusão de terminologia, vamos entender que no mundo Postgresql, o termo “esquema” talvez esteja um tanto infelizmente sobrecarregado. No contexto mais amplo de sistemas de gerenciamento de banco de dados relacional (RDBMS), o termo "esquema" pode ser entendido como referência ao design lógico ou físico geral do banco de dados, ou seja, a definição de todas as tabelas, colunas, visualizações e outros objetos que constituem a definição do banco de dados. Nesse contexto mais amplo, um esquema pode ser expresso em um diagrama entidade-relacionamento (ER) ou um script de instruções de linguagem de definição de dados (DDL) usado para instanciar o banco de dados do aplicativo.
No mundo Postgresql, o termo “schema” pode ser melhor entendido como um “namespace”. De fato, nas tabelas do sistema Postgresql, os esquemas são registrados em colunas de tabela chamadas “espaço de nomes”, que, IMHO, é uma terminologia mais precisa. Por uma questão prática, sempre que vejo “esquema” no contexto do Postgresql eu reinterpreto silenciosamente como dizendo “espaço de nomes”.
Mas você pode perguntar:“O que é um namespace?” Geralmente, um espaço de nomes é um meio bastante flexível de organizar e identificar informações pelo nome. Por exemplo, imagine duas famílias vizinhas, os Smiths, Alice e Bob, e os Jones, Bob e Cathy (cf. Figura 1). Se usarmos apenas os primeiros nomes, pode ficar confuso sobre qual pessoa nos referimos ao falar sobre Bob. Mas, ao adicionar o sobrenome, Smith ou Jones, identificamos de maneira exclusiva a pessoa a que nos referimos.
Muitas vezes, os namespaces são organizados em uma hierarquia aninhada. Isso permite a classificação eficiente de grandes quantidades de informações em uma estrutura muito fina, como, por exemplo, o sistema de nomes de domínio da Internet. No nível superior, “.com”, “.net”, “.org”, “.edu” e etc. definem amplos espaços de nomes dentro dos quais são registrados nomes para entidades específicas, por exemplo, “severalnines.com” e “postgresql.org” são definidos exclusivamente. Mas em cada um deles há vários subdomínios comuns, como “www”, “mail” e “ftp”, por exemplo, que sozinhos são duplicados, mas dentro dos respectivos espaços de nomes são exclusivos.
Os esquemas do Postgresql servem a esse mesmo propósito de organização e identificação, porém, diferentemente do segundo exemplo acima, os esquemas do Postgresql não podem ser aninhados em uma hierarquia. Embora um banco de dados possa conter muitos esquemas, há apenas um nível e, portanto, dentro de um banco de dados, os nomes dos esquemas devem ser exclusivos. Além disso, todo banco de dados deve incluir pelo menos um esquema. Sempre que um novo banco de dados é instanciado, um esquema padrão chamado “público” é criado. O conteúdo de um esquema inclui todos os outros objetos de banco de dados, como tabelas, visualizações, procedimentos armazenados, gatilhos e etc. banco de dados Postgresql.
Além de simplesmente organizar os objetos do banco de dados em grupos lógicos para torná-los mais gerenciáveis, os esquemas servem ao propósito prático de evitar a colisão de nomes. Um paradigma operacional envolve a definição de um esquema para cada usuário do banco de dados de forma a fornecer algum grau de isolamento, um espaço onde os usuários podem definir suas próprias tabelas e visualizações sem interferir umas nas outras. Outra abordagem é instalar ferramentas de terceiros ou extensões de banco de dados em esquemas individuais para manter todos os componentes relacionados logicamente juntos. Um artigo posterior desta série detalhará uma nova abordagem para o design robusto de aplicativos, empregando esquemas como meio de indireção para limitar a exposição do design físico do banco de dados e, em vez disso, apresentar uma interface de usuário que resolve chaves sintéticas e facilita a manutenção a longo prazo e o gerenciamento de configuração conforme os requisitos do sistema evoluem.
Vamos fazer um código!
Baixe o whitepaper hoje PostgreSQL Management &Automation with ClusterControlSaiba o que você precisa saber para implantar, monitorar, gerenciar e dimensionar o PostgreSQLBaixe o whitepaper
O comando mais simples para criar um esquema dentro de um banco de dados é
CREATE SCHEMA hollywood;
Este comando requer privilégios de criação no banco de dados, e o esquema recém-criado “hollywood” será de propriedade do usuário que invocar o comando. Uma invocação mais complexa pode incluir elementos opcionais especificando um proprietário diferente e pode até incluir instruções DDL instanciando objetos de banco de dados dentro do esquema em um único comando!
O formato geral é
CREATE SCHEMA schemaname [ AUTHORIZATION username ] [ schema_element [ ... ] ]
onde “username” é quem será o proprietário do esquema e “schema_element” pode ser um de certos comandos DDL (consulte a documentação do Postgresql para detalhes). Privilégios de superusuário são necessários para usar a opção AUTHORIZATION.
Então, por exemplo, para criar um esquema chamado “hollywood” contendo uma tabela chamada “films” e uma visualização chamada “winners” em um comando, você poderia fazer
CREATE SCHEMA hollywood
CREATE TABLE films (title text, release date, awards text[])
CREATE VIEW winners AS
SELECT title, release FROM films WHERE awards IS NOT NULL;
Objetos de banco de dados adicionais podem ser criados diretamente, por exemplo, uma tabela adicional seria adicionada ao esquema com
CREATE TABLE hollywood.actors (name text, dob date, gender text);
Observe no exemplo acima o prefixo do nome da tabela com o nome do esquema. Isso é necessário porque, por padrão, ou seja, sem especificação de esquema explícita, novos objetos de banco de dados são criados dentro do esquema atual, que abordaremos a seguir.
Lembre-se de como no exemplo do primeiro espaço de nome acima, tínhamos duas pessoas chamadas Bob e descrevemos como desconflito ou distingui-las incluindo o sobrenome. Mas dentro de cada uma das famílias Smith e Jones separadamente, cada família entende que “Bob” se refere àquele que vai com aquela casa em particular. Assim, por exemplo, no contexto de cada família respectiva, Alice não precisa se referir ao marido como Bob Jones, e Cathy não precisa se referir ao marido como Bob Smith:cada um pode apenas dizer “Bob”.
O esquema atual do Postgresql é como a casa do exemplo acima. Os objetos no esquema atual podem ser referenciados sem qualificação, mas a referência a objetos com nomes semelhantes em outros esquemas requer a qualificação do nome prefixando o nome do esquema conforme acima.
O esquema atual é derivado do parâmetro de configuração “search_path”. Este parâmetro armazena uma lista de nomes de esquemas separados por vírgulas e pode ser examinado com o comando
SHOW search_path;
ou defina um novo valor com
SET search_path TO schema [, schema, ...];
O primeiro nome de esquema na lista é o “esquema atual” e é onde novos objetos são criados se especificados sem qualificação de nome de esquema.
A lista de nomes de esquemas separados por vírgulas também serve para determinar a ordem de pesquisa pela qual o sistema localiza objetos nomeados não qualificados existentes. Por exemplo, de volta ao bairro de Smith and Jones, uma entrega de pacote endereçada apenas a “Bob” exigiria visitas em cada casa até que o primeiro morador chamado “Bob” fosse encontrado. Observe que este pode não ser o destinatário pretendido. A mesma lógica se aplica ao Postgresql. O sistema procura tabelas, exibições e outros objetos nos esquemas na ordem do search_path e, em seguida, o primeiro objeto de correspondência de nome encontrado é usado. Os objetos nomeados qualificados pelo esquema são usados diretamente sem referência ao search_path.
Na configuração padrão, consultar a variável de configuração search_path revela esse valor
SHOW search_path;
Search_path
--------------
"$user", public
O sistema interpreta o primeiro valor mostrado acima como o nome de usuário conectado no momento e acomoda o caso de uso mencionado anteriormente, onde cada usuário recebe um esquema de nome de usuário para um espaço de trabalho separado de outros usuários. Se nenhum esquema nomeado pelo usuário tiver sido criado, essa entrada será ignorada e o esquema “público” se tornará o esquema atual onde novos objetos são criados.
Assim, de volta ao nosso exemplo anterior de criação da tabela “hollywood.actors”, se não tivéssemos qualificado o nome da tabela com o nome do esquema, a tabela teria sido criada no esquema público. Se anteciparmos a criação de todos os objetos dentro de um esquema específico, pode ser conveniente definir a variável search_path como
SET search_path TO hollywood,public;
facilitando a abreviação de digitar nomes não qualificados para criar ou acessar objetos de banco de dados.
Há também uma função de informações do sistema que retorna o esquema atual com uma consulta
select current_schema();
Em caso de digitação de grafia, o proprietário de um esquema pode alterar o nome, desde que o usuário também tenha privilégios de criação para o banco de dados, com o
ALTER SCHEMA old_name RENAME TO new_name;
E por último, para deletar um esquema de um banco de dados, existe um comando drop
DROP SCHEMA schema_name;
O comando DROP falhará se o esquema contiver quaisquer objetos, portanto, eles devem ser excluídos primeiro ou, opcionalmente, você pode excluir recursivamente um esquema todo o seu conteúdo com a opção CASCADE
DROP SCHEMA schema_name CASCADE;
Esses conceitos básicos irão ajudá-lo a entender os esquemas!