Partilhar via


Modele aplicativos SaaS multilocatários no Azure Cosmos DB para PostgreSQL

Importante

O Azure Cosmos DB para PostgreSQL não tem mais suporte para novos projetos. Não use este serviço para novos projetos. Em vez disso, use um destes dois serviços:

  • Use o Azure Cosmos DB para NoSQL para obter uma solução de banco de dados distribuído projetada para cenários de alta escala com um SLA (contrato de nível de serviço) de disponibilidade de 99.999%, dimensionamento automático instantâneo e failover automático em várias regiões.

  • Use a funcionalidade de Clusters Elásticos do Azure para PostgreSQL para PostgreSQL fragmentado, utilizando a extensão Citus de código aberto.

ID do locatário como a chave de fragmento

O ID do locatário é a coluna na raiz da carga de trabalho ou a parte superior da hierarquia em seu modelo de dados. Por exemplo, neste esquema de comércio eletrônico SaaS, seria o ID da loja:

Diagrama de tabelas, com a coluna store_id realçada.

Esse modelo de dados seria típico de uma empresa como a Shopify. Ele hospeda sites para várias lojas online, onde cada loja interage com seus próprios dados.

  • Este modelo de dados tem um monte de tabelas: lojas, produtos, pedidos, itens de linha e países.
  • A tabela de lojas está no topo da hierarquia. Produtos, pedidos e itens de linha estão todos associados às lojas, portanto, mais abaixo na hierarquia.
  • A tabela de países não está relacionada a lojas individuais, está entre todas as lojas.

Neste exemplo, store_id, que está no topo da hierarquia, é o identificador do locatário. É a chave de estilhaço certa. A escolha de store_id como chave de fragmento permite agrupar os dados de todas as tabelas para uma única loja num único trabalhador.

A colocação de mesas por loja tem vantagens:

  • Fornece cobertura SQL, como chaves estrangeiras e junções. As transações para um único locatário estão localizadas num único nó de processamento onde cada locatário existe.
  • Alcança um desempenho de milissegundos de um dígito. As consultas para um único locatário são roteadas para um único nó em vez de serem paralelizadas, o que ajuda a otimizar os saltos de rede e ainda dimensionar computação/memória.
  • É escalável. À medida que o número de inquilinos cresce, pode-se adicionar nós e reequilibrar os inquilinos para novos nós, ou até mesmo isolar grandes inquilinos para os seus próprios nós. O isolamento do locatário permite que você forneça recursos dedicados.

Diagrama de tabelas colocalizadas nos mesmos nós.

Modelo de dados ideal para aplicativos multilocatários

Neste exemplo, devemos distribuir as tabelas específicas da loja por ID da loja e criar countries uma tabela de referência.

Diagrama de tabelas com store_id mais universalmente destacado.

Observe que as tabelas específicas do locatário têm o identificador do locatário e são distribuídas. No nosso exemplo, lojas, produtos e line_items são distribuídos. O resto das tabelas são tabelas de referência. No nosso exemplo, a tabela de países é uma tabela de referência.

-- Distribute large tables by the tenant ID

SELECT create_distributed_table('stores', 'store_id');
SELECT create_distributed_table('products', 'store_id', colocate_with => 'stores');
-- etc for the rest of the tenant tables...

-- Then, make "countries" a reference table, with a synchronized copy of the
-- table maintained on every worker node

SELECT create_reference_table('countries');

Todas as tabelas grandes devem ter o ID do inquilino.

  • Se você estiver migrando um aplicativo multilocatário existente para o Azure Cosmos DB para PostgreSQL, talvez seja necessário desnormalizar um pouco e adicionar a coluna ID do locatário a tabelas grandes, se estiver faltando, e preencher os valores ausentes da coluna.
  • Para novos aplicativos no Azure Cosmos DB para PostgreSQL, verifique se a ID do locatário está presente em todas as tabelas específicas do locatário.

Certifique-se de incluir o ID do locatário nas restrições de chave primária, única e estrangeira em tabelas distribuídas na forma de uma chave composta. Por exemplo, se uma tabela tiver uma chave primária de id, transforme-a na chave (tenant_id,id)composta. Não há necessidade de alterar as teclas das tabelas de referência.

Considerações sobre consultas para melhor desempenho

As consultas distribuídas que filtram o ID do locatário são executadas de forma mais eficiente em aplicativos multilocatário. Certifique-se de que suas consultas tenham sempre o escopo de um único locatário.

SELECT *
  FROM orders
 WHERE order_id = 123
   AND store_id = 42;  -- ← tenant ID filter

É necessário adicionar o filtro de ID do locatário mesmo que as condições de filtro originais identifiquem inequivocamente as linhas desejadas. O filtro de ID do locatário, embora aparentemente redundante, indica ao Azure Cosmos DB no PostgreSQL como rotear a consulta para um único nó de trabalho.

Da mesma forma, ao unir duas tabelas distribuídas, certifique-se de que ambas as tabelas estejam limitadas a um único inquilino. O escopo pode ser definido garantindo que as condições de associação incluam o ID do locatário.

SELECT sum(l.quantity)
  FROM line_items l
 INNER JOIN products p
    ON l.product_id = p.product_id
   AND l.store_id = p.store_id   -- ← tenant ID in join
 WHERE p.name='Awesome Wool Pants'
   AND l.store_id='8c69aa0d-3f13-4440-86ca-443566c1fc75';
       -- ↑ tenant ID filter

Existem bibliotecas auxiliares para várias estruturas de aplicativos populares que facilitam a inclusão de um ID de locatário em consultas. Aqui estão as instruções:

Próximos passos

Agora terminamos de explorar a modelagem de dados para aplicativos escaláveis. O próximo passo é conectar e consultar o banco de dados com a linguagem de programação de sua escolha.