¿Un ejemplo práctico de desnormalización en una base de datos SQL?

¡Abajo está la respuesta específica de BigQuery!

BigQuery funciona mejor cuando sus datos están desnormalizados. En lugar de preservar un esquema relacional como un esquema de estrella o de copo de nieve, puede mejorar el rendimiento desnormalizando sus datos y aprovechando los campos anidados y repetidos. Los campos anidados y repetidos pueden mantener las relaciones sin el impacto en el rendimiento de preservar un esquema relacional (normalizado).

El ahorro de almacenamiento de los datos normalizados es menos preocupante en los sistemas modernos. Los aumentos en los costes de almacenamiento valen la pena las ganancias de rendimiento de la desnormalización de los datos. Las uniones requieren coordinación de datos (ancho de banda de comunicación). La desnormalización localiza los datos en ranuras individuales para que la ejecución pueda hacerse en paralelo.

Si necesita mantener las relaciones mientras desnormaliza sus datos, utilice campos anidados y repetidos en lugar de aplanar completamente sus datos. Cuando los datos relacionales se aplanan por completo, la comunicación de red (barajada) puede afectar negativamente al rendimiento de las consultas.

Por ejemplo, desnormalizar un esquema de pedidos sin usar campos anidados y repetidos puede requerir que se agrupe por un campo como order_id (cuando hay una relación de uno a muchos). Debido al barajado involucrado, agrupar los datos es menos performante que desnormalizar los datos usando campos anidados y repetidos.

Nota: en algunas circunstancias, la desnormalización de los datos y el uso de campos anidados y repetidos puede no resultar en un mayor rendimiento.

Puede ver más en la sección Denormalizar datos siempre que sea posible de los docs de BigQuery

Finalmente: BigQuery no requiere una desnormalización completamente plana. Puede utilizar campos anidados y repetidos para mantener las relaciones.

A continuación se muestra un ejemplo de producción de una tabla desnormalizada a partir de las tres tablas iniciales normalizadas en su pregunta

#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)

esto producirá una tabla con el siguiente esquema

Obviamente, este es un esquema más centrado en el cliente. Depende de tus necesidades puedes crear de forma similar uno centrado en el producto. O en realidad ambos y utilizar el apropiado basado en el caso de uso

introducir la descripción de la imagen aquí

Puede probar, jugar con lo anterior utilizando datos ficticios como en el siguiente ejemplo

#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) 

con salida

introducir descripción de la imagen aquí

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *