SQL 数据库中非规范化的实际示例?

cge*_*get 4 sql denormalization google-bigquery

过去 20 分钟我一直在阅读有关非规范化的内容,但无法获得带有代码的简洁示例。

这就是非规范化吗?


1.我们有一个规范化的数据库:

表_1:
customer_id(主键)
国家/地区
城市
街道
房屋号码

表_2:
product_id(主键)
customer_id(外键)
product_storage_building

表_3:
product_id(外键)
产品名称
产品颜色
产品原产地

  1. 但是,假设连接所有三个表的运行时间太长

        SELECT a.*, b.*, c.*
        FROM 
        TABLE_1 AS a
        LEFT JOIN TABLE_2 AS b
        ON a.customer_id = b.customer_id
        LEFT JOIN TABLE_3 AS c
        ON b.product_id = c.product_id
    
    Run Code Online (Sandbox Code Playgroud)

所以我创建了一个新Table_1Table_2

    CREATE OR REPLACE TABLE Denormalized_Data AS
    (
     SELECT customer_id, 
            country, 
            city,
            street, 
            house_number,
            product_id,
            product_storage_building
     FROM Table_1
          LEFT JOIN Table_2
          ON Table_1.cusomter_id = Table_2.customer_id
    )
Run Code Online (Sandbox Code Playgroud)
  1. 然后加入Table_3如下

     SELECT customer_id, 
            country, 
            city,
            street, 
            house_number,
            product_storage_building,
            Denormalized_Data.product_id
            product_name,
            product_color,
         FROM Denormalized_Data
         LEFT JOIN Table_3
         ON Denormalized_Data.product_id = Table_3.product_id
    
    Run Code Online (Sandbox Code Playgroud)

现在这将使我的查询运行得更快——上面的整个过程可以被描述为非规范化吗?

谢谢

Bil*_*win 9

是的,您正在展示一种非规范化。

非规范化分为三种类型:

  • 连接来自不同表的行,因此您不必使用JOIN.
  • 执行像SUM()orCOUNT()MAX()或其他那样的聚合计算,因此您不必使用GROUP BY.
  • 预先计算昂贵的计算,因此您不必在选择列表中使用带有复杂表达式的查询。

您正在展示第一种类型的示例。至少您可以避免您打算执行的两个连接之一。

为什么不让非规范化表存储连接所有三个表的结果?

使用非规范化有什么缺点?您现在正在冗余地存储数据:一次存储在规范化表中,一个副本存储在非规范化表中。假设您明天开始工作,发现这些不同表中的数据并不完全匹配。发生了什么?

  • 也许有人在规范化表中插入了一行,但没有将相应的数据添加到非规范化表中。
  • 也许有人从规范化表中删除了一行,但没有从非规范化表中删除相应的行。
  • 也许有人在非规范化表中插入或删除了一行,而规范化表中没有相应的更改。

你怎么知道发生了什么?哪张表是“正确的”?这就是非规范化的风险。


rte*_*nha 6

考虑下图。顶部包含几个不同的表,封装了逻辑上独立的信息位。底部显示了这些表连接在一起的结果。这就是非规范化。

标准化到非标准化

对于 BigQuery,特别是使用 BQ 作为 BI 平台的后端,非规范化数据提供了更快的用户体验,因为它不必在用户点击“运行”时进行连接。

如果您将表保留原样,如果用户需要多个字段,您最终可能会执行最多 7 个连接,然后进行聚合(求和、计数等)。但是,如果您执行所有 7 个连接并将其存储在 1 个表中,那么用户将仅查询 1 个表并仅执行聚合。这就是 BigQuery 的力量。它是可扩展的,因此与联接相比,对大量数据进行分组和聚合相对“容易”,从而使最终用户体验更快。

朝这个方向发展的人/公司通常在 ETL 流程中这样做(通常是夜间),因此联接只需发生 1 次(当用户通常不使用数据库时),然后在白天,用户和 BI 工具就可以了无需连接即可聚合和切片数据!这确实会导致“冗余”数据并产生额外的存储成本,但对于下游用户体验来说通常是值得的