【问题标题】:Reporting denormalized vs normalized database [closed]报告非规范化与规范化数据库[关闭]
【发布时间】:2018-02-07 20:40:50
【问题描述】:

我们正在构建报告应用程序,我们将在其中每天转储大量数据。目前,我们有两种数据模型,一种用于运营,另一种用于报告。

报表数据模型中的几列出现在操作表中。如果运营数据模型得到更新,我们如何确保报告数据模型进行类似的更改,更新成本是多少?

例子:

Report Table - 
     user_name
     organisation_name
     event_name
     etc 10 more col.

User Table -
    id
    name
    ..

Organisation Table -
    id
    name 

让我们考虑报表表包含 100 万条记录,并且组织名称发生更改,该更改需要反映在报表表中。更改细节的频率可能是平均的。

所以我们有两个选择 规范化数据库 -
这将节省报告表的更新,但查询处理将花费更长的时间。 非规范化数据库 - 这将帮助我们指导更快的查询处理,但维护它会涉及复杂性。

请指教,我们应该走哪条路?我们的数据量非常大,报告数据的粒度很高。

【问题讨论】:

  • 有些查询可能更快,有些可能更慢。 “过早的优化是万恶之源。”

标签: database-design database-normalization denormalization


【解决方案1】:

唯一的选择确实是规范化数据库。为什么?

优点:

  • 更易于维护。
  • 由于您将拥有大量数据,规范化数据库将需要更少的磁盘空间! 为什么?因为不是说每次都用他的用户名代表用户,假设平均需要 10 个字符,你会使用他的 id 并且只需要 2 或 3 个字符。从远距离来看,这是一个巨大的差异。

“较慢”的查询实际上并不慢。唯一的缺点是小菜一碟,您将不得不编写更多代码。但是您编写一次代码,数据库将永远存在。

【讨论】:

  • 您的规范化示例是引入代理键。除了在极少数情况下,代理键与规范化无关。规范化是将复杂谓词分解为基本事实类型,同时保留数据中的依赖关系,其目标是通过消除冗余和数据异常来确保一致性。存储空间和性能不是逻辑模型的关注点。
  • 我认为这个问题并没有问什么是规范化或规范化用于什么,而是为什么要使用它。您所说的更容易维护(数据一致性等)
【解决方案2】:

“非规范化”这个词的问题在于它没有具体说明您将使用什么设计原则。更好的计划是采用特定的设计计划,该计划不会导致完全规范化的数据库,但有一定的意义。

一个相当广泛使用的设计计划是星型模式,或近似变体的雪花模式。这两种模式已用于报告数据库以及数据集市和数据仓库。

在我处理星型模式的每一种情况下,数据都是从一个或多个其他数据库复制的,并且这些源数据库已被规范化。源数据库用于 OLTP(在线事务处理),而星型模式用于 OLAP(在线分析处理)目的,包括报告。

定期(例如每天一次)将数据从 OLTP 存储传输到 OLAP 存储的过程称为 ETL(提取、传输和加载)。它本身就是一门艺术,您可以购买一些工具来促进 ETL。如果您想构建自己的 ETL 流程,还可以学习一些技术。

拥有两个数据库的模式,一个用于 OLTP,另一个用于 OLAP,让您在两种不同的上下文中获得两种不同设计模式的好处。维护两个不同的数据库的成本几乎是维护一个的两倍,而且您还必须管理传输过程。

所有这些都不能为您的问题提供明确的答案,但它确实为您提供了一些流行语,可用于在网络上搜索相关项目。

【讨论】:

    【解决方案3】:

    第一个问题:

    让我们考虑报表表包含 100 万条记录, 和组织名称被改变,改变 需要反映在报告表中...

    ...更新费用是多少?

    它应该很低,因为我们不需要更新“报告表”。您只需要更新维度表,原因如下:

    考虑不要制作一个可以直接被报告工具读取的“报告表”。考虑改为使用星型模式(“非规范化”选项之一)。该报告将通过在运行时将事实连接到维度来生成。

    请参考销售星模式的实体关系图 (ERD): https://upload.wikimedia.org/wikipedia/en/f/fe/Star-schema-example.png

    假设 Wiki 文章中的示例 ERD 是一家拥有不同商店品牌的公司的数据仓库,因此它们的名称将彼此不同。

    所以让我们在 DIM_STORE 表中添加一个“store_name”列,并且只添加到 DIM_STORE 表中。 FACT_SALES 表保持原样。

    当商店更改其名称时,我们会更新 DIM_STORE.store_name 列。

    DIM_STORE 和 FACT_SALES 加入 store_id,允许我们从 DIM 中获取当前商店名称。

    商店很少更改名称,但一旦发生,报告用户通常希望记录此更改。这种类型的维度更新称为渐变维度 (SCD)。

    这篇 Wiki 文章解释了 SCD: https://en.wikipedia.org/wiki/Slowly_changing_dimension

    仅供参考,SCD 类型 1 和 2 是常用的。我更喜欢类型 2,因为它会保留历史记录,但请选择最符合您报告要求的类型。

    ERD 来自这篇关于星型模式的 Wiki 文章: https://en.wikipedia.org/wiki/Star_schema

    第二个问题:

    如果运营数据模型得到更新,我们将如何 可以确保报告数据模型进行类似的更改

    如果源系统中的表结构发生更改,那么您将不得不手动更新加载过程和相应的数据仓库表。在某些情况下,这可能涉及重新加载所有数据。

    代理键:与您的问题密切相关,代理键是维护 SCD 所必需的: http://www.bidw.org/datawarehousing/what-is-surrogate-key/

    在关于 SCD 的 Wiki 文章中,supplier_key 是它们的代理键,由数据仓库或 ETL 过程生成,supplier_code 类似于您的 organization_id(或关于星型模式的 Wiki 文章中的 store_id)源数据库。

    我认为这些概念需要一些研究和重新阅读才能消化,所以我希望你不要着急。如果做得好,他们需要大量时间进行规划和设计,但以后会节省大量开发时间。

    【讨论】:

      【解决方案4】:

      我认为您需要了解的第一件事是组织名称的更改频率。如果答案不是很频繁,那么我会保持报告表不变(非规范化)。

      【讨论】:

        猜你喜欢
        • 2012-12-31
        • 2016-11-18
        • 2016-07-23
        • 2016-05-13
        • 2018-06-06
        • 2013-12-11
        • 2013-01-18
        • 1970-01-01
        • 2014-12-23
        相关资源
        最近更新 更多