在数据仓库(关系)中有外键是一种好习惯吗?
Posted
技术标签:
【中文标题】在数据仓库(关系)中有外键是一种好习惯吗?【英文标题】:Is it good practice to have foreign keys in a datawarehouse (relationships)? 【发布时间】:2010-04-22 12:44:57 【问题描述】:我认为这个问题已经很清楚了。我的数据仓库表中的某些列可能与主键有关系。但这是好的做法吗?它是非规范化的,因此永远不应再次删除它(数据仓库中的数据)。希望问题有点清楚。
【问题讨论】:
【参考方案1】:我假设您在事实表中指的是 FK。在 DW 加载期间,索引和任何外键都会被删除以加快加载速度——ETL 过程会处理键。
外键约束在插入和更新期间“激活”(这是当它需要检查父表中是否存在键值时)以及在删除父表中的主键期间。它在读取期间不起作用。删除 DW 中的记录是(应该)是一个受控过程,它会在从维度表中删除之前扫描任何现有关系。
因此,大多数 DW 没有将外键实现为约束。
【讨论】:
【参考方案2】:FK 约束在 SQL Server 上的 Kimball 维度模型中运行良好。
通常,您的 ETL 将需要查找维度表(通常在处理缓慢变化的维度的业务键上)以确定维度代理 ID,而维度代理 ID 通常是一个身份,维度上的 PK 是通常是维度代理id,它已经是一个索引(可能是聚集的)。
此时拥有 RI 并不会产生巨大的写入开销,因为它还可以帮助在开发过程中发现 ETL 缺陷。此外,将事实表的 PK 作为所有 FK 的组合还有助于捕获潜在的数据建模问题和双重加载。
如果您希望创建通用扁平视图或星型模型的表值函数,它实际上可以减少选择的开销。因为额外的维度内连接保证只产生一行,所以优化器可以非常有效地使用这些约束来消除查找表的需要。如果没有 FK 约束,可能必须执行这些查找以消除维度不存在的事实。
【讨论】:
【参考方案3】:在 DW 中使用 FK 约束就像戴上自行车头盔。如果 ETL 设计正确,您技术上不需要它们。也就是说,如果我每次看到无错误的 ETL 都能获得一百万美元,那么我将获得零美元。
直到你处于 FK 约束导致性能问题的地步,我说离开他们。清理参照完整性问题可能比从一开始就添加它们要困难得多;-)
【讨论】:
我在数据和数据仓库方面 20 多年的经验与您的观点一致……项目发生变化/发展,客户(和开发人员!)可以轻松引入打破假设的变化。拥有 FK 确实是一个很好的安全网——“自行车头盔”就像一个比喻!如果做不到这一点,我会鼓励加载过程的最终“验证”阶段,该阶段至少检查数据中的约束/唯一性。很好的答案,比尔。【参考方案4】:问题很明确,但“良好做法”似乎是错误的问题。
“可以有 FK 的” 吗?
外键是一种在数据库修改期间保持完整性约束的机制。
如果您的 DW 是只读的(累积数据源而不回写),则不需要 FK。
如果您的 DW 支持写入,则完整性约束通常需要由 ETL 跨参与的数据源进行协调(相反,它与 Store 等效)。这个过程可能会也可能不会依赖于数据库中的 FK。
所以正确的问题是:你需要它们吗?
(我能想到的唯一其他原因是记录关系 - 但是,这也可以在纸上/在单独的文档中完成。)
【讨论】:
+1。 “外键是一种在数据库修改期间保持完整性约束的机制。如果您的 DW 是只读的,则不需要 FK 的......” - 牛眼! 一些数据库在星型或雪花型结构数据仓库的地方有特定的优化。在这些情况下,即使在只读情况下,外键也可以用来提醒仓库星型的结构——告诉它哪些是事实和维度。即使在规范化数据库中,外键也会影响优化器。我现在正在努力确定这件事何时以及有多重要,但它确实会产生一些影响。 是的,只读意味着 enforcing 约束是不必要的——如果您的仓库是约束强制数据库的快照。但是约束允许 DBMS 优化查询。所以“不需要”是错误的。像往常一样,这是一个权衡。【参考方案5】:我不知道。但是没有人回答,所以我用谷歌搜索并找到了a best practises paper,他似乎说“这取决于”非常有帮助:-)
虽然外键约束有助于数据完整性,但它们对所有插入、更新和删除语句都有相关的成本。当您希望确保数据完整性和验证时,请特别注意仓库或 ODS 中约束的使用
【讨论】:
【参考方案6】:在数据仓库中使用外键约束的原因与任何其他数据库相同:确保数据完整性。
查询性能也可能会受益,因为外键允许某些类型的查询重写,而这些重写通常在没有它们的情况下是不可能的。然而,数据完整性仍然是使用外键的主要原因。
【讨论】:
【参考方案7】:是的,作为最佳实践,在事实表上实施 FK 约束。在 SQL Server 中,使用 NOCHECK。在 ORACLE 中始终使用 RELY DISABLE NOVALIDATE。这允许仓库或集市了解关系,但不能在 INSERT、UPDATE 或 DELETE 操作中检查它。星型转换、优化等可能不再像过去那样依赖 FK 约束来改进查询,但人们永远不知道前端或您的仓库或市场将使用哪些 BI 或 OLAP 工具。其中一些工具可以利用知道定义的关系。另外,你见过多少丑陋的仓库,几乎没有或没有外部文档,不得不尝试对它们进行逆向工程?定义 FK 总是有帮助的。
作为设计师,我们似乎从来没有像我们应该的那样让我们的数据仓库或集市自记录。定义 FK 肯定会对此有所帮助。现在,话虽如此,如果星型模式在没有定义 FK 的情况下设计得当,那么无论如何都很容易阅读和理解它们。
对于 ORACLE 事实表,总是在每个 FK 上为一个维度定义一个 LOCAL BITMAP 索引。去做就对了。索引实际上比定义的 FK 更重要。
【讨论】:
与NOCHECK有关系吗?对于 DW 来说,这听起来是个好主意。您在设计系统时记录关系,但在源系统出现问题时不会破坏 ETL。【参考方案8】:在只读 DW/DM 中创建 FK 约束是有充分理由的。 是的,从只读 DW 本身的角度来看,它们并不是真正需要的,如果您的 ETL 是防弹的,等等等等。但是猜猜看 - 生活不会停止在 DW 中加载数据。大多数 BI 分析/报告工具都使用有关 DW 关系的信息来自动构建其模型(例如 SSAS 表格模型)。 在我看来,仅此一项就超过了在 ETL 过程中删除和重新创建 FK 约束的少量开销。
【讨论】:
以上是关于在数据仓库(关系)中有外键是一种好习惯吗?的主要内容,如果未能解决你的问题,请参考以下文章
在 Room 数据库实体上实现 Parcelable 是一种好习惯吗?