Um exemplo prático de desnormalização numa base de dados SQL?

Below é a resposta específica de BigQuery!

BigQuery tem o melhor desempenho quando os seus dados são desnormalizados. Em vez de preservar um esquema relacional como um esquema em estrela ou em floco de neve, pode melhorar o desempenho desnormalizando os seus dados e tirando partido de campos aninhados e repetidos. Os campos aninhados e repetidos podem manter relações sem o impacto do desempenho de preservar um esquema relacional (normalizado).

As economias de armazenamento de dados normalizados são menos preocupantes nos sistemas modernos. Os aumentos dos custos de armazenamento valem os ganhos de desempenho da desnormalização dos dados. As uniões requerem coordenação de dados (largura de banda de comunicação). A desnormalização localiza os dados em slots individuais para que a execução possa ser feita em paralelo.

Se precisar de manter relações enquanto desnormaliza os seus dados, utilize campos aninhados e repetidos em vez de aplanar completamente os seus dados. Quando os dados relacionais são completamente achatados, a comunicação em rede (shuffling) pode ter um impacto negativo no desempenho da consulta.

Por exemplo, desnormalizar um esquema de ordens sem utilizar campos aninhados e repetidos pode exigir o agrupamento por um campo como order_id (quando existe uma relação de um para muitos). Devido ao baralhamento envolvido, agrupar os dados é menos performante do que desnormalizar os dados usando campos aninhados e repetidos.

Nota: Em algumas circunstâncias, desnormalizar os seus dados e utilizar campos aninhados e repetidos pode não resultar num aumento do desempenho.

P>Pode ver mais na secção Desnormalizar dados sempre que possível dos documentos BigQuery

Finalmente: A BigQuery não requer uma desnormalização completamente plana. Pode usar campos aninhados e repetidos para manter relações.

Below é um exemplo de produzir tabela desnormalizada a partir de três tabelas normalizadas iniciais na sua pergunta

#standardSQLSELECT ANY_VALUE(c).*, ARRAY_AGG((SELECT AS STRUCT p.*, s.product_storage_building)) productsFROM `project.dataset.customers` cLEFT JOIN `project.dataset.storage` s USING (customer_id)LEFT JOIN `project.dataset.products` p USING (product_id)GROUP BY FORMAT('%t', c)

esta produzirá tabela com o esquema abaixo

Obviamente, este é um esquema mais centrado no cliente. Depende das suas necessidades, pode de forma semelhante criar um centrado no produto. Ou, na realidade, ambos e usar apropriado com base no caso de uso

enter a descrição da imagem aqui

P>P>Pode testar, brincar com dados fictícios, como no exemplo abaixo

#standardSQLWITH `project.dataset.customers` AS ( SELECT 1 customer_id, 'country 1' country, 'city 1' city, 'street 1' street, 1 house_number UNION ALL SELECT 2, 'country 1', 'city 2', 'street 2', 2 UNION ALL SELECT 3, 'country 1', 'city 3', 'street 3', 3 UNION ALL SELECT 4, 'country 2', 'city 4', 'street 4', 4 UNION ALL SELECT 5, 'country 2', 'city 5', 'street 5', 5 ), `project.dataset.products` AS ( SELECT 1 product_id, 'product 1' product_name, 'color 1' product_color, 'origin 1' product_origin UNION ALL SELECT 2, 'product 2', 'color 2', 'origin 2' UNION ALL SELECT 3, 'product 3', 'color 3', 'origin 3' UNION ALL SELECT 4, 'product 4', 'color 4', 'origin 4' ), `project.dataset.storage` AS ( SELECT 1 product_id, 1 customer_id, 'building 1' product_storage_building UNION ALL SELECT 2, 1, 'building 1' UNION ALL SELECT 3, 1, 'building 1' UNION ALL SELECT 2, 2, 'building 2' UNION ALL SELECT 3, 2, 'building 3' UNION ALL SELECT 4, 2, 'building 3' UNION ALL SELECT 1, 3, 'building 1' UNION ALL SELECT 3, 3, 'building 1' )SELECT ANY_VALUE(c).*, ARRAY_AGG((SELECT AS STRUCT p.*, s.product_storage_building)) productsFROM `project.dataset.customers` cLEFT JOIN `project.dataset.storage` s USING (customer_id)LEFT JOIN `project.dataset.products` p USING (product_id)GROUP BY FORMAT('%t', c) 

com saída

enter descrição da imagem aqui

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *