【问题标题】:Preventing invalid JOINs using dimension/fact tables that contain NULL Foreign Keys使用包含 NULL 外键的维度/事实表防止无效 JOIN
【发布时间】:2022-01-18 05:24:41
【问题描述】:

目标

我们正在尝试制作便于任何人使用的事实和维度表。许多现代 BI 系统促进探索和实验,我们希望所有技能水平的人都能取得成功。

问题

我们的数据有大量 NULLable 外键 ID。这会导致几乎每个数据库中出现意外行为。在Snowflake(我们的数据仓库)中,JOINing on NULL 会导致CROSS JOIN,这非常非常糟糕。

可能的方法

每个JOIN都需要格外小心
这可以通过两种方式完成,但它们都很容易搞砸或错过......

  1. JOINs 中使用COALESCE(nullable, '--SOMETHING_INVALID--')
  2. JOINs 的ON 子句中检查NULL

NULL id 替换为默认值
如果我们默认使用有效的东西,这将以未知的方式扭曲报告。如果我们默认某些无效的东西,我们将以第二种且难以追踪的方式破坏参照完整性。

SELECT
  customer_id,
  -- Some default "id" that wont cause a collision
  COALESCE(location_id, '9999999999') AS location_id,
  ...
FROM
  crm.customers

将所有 NULL 值添加到每个表中
这有点笨拙,但是...JOINs 将始终有效。

问题

所有这些都有缺点。

  • 有没有更好/更清洁的东西?
  • dbt 是否有工具或实用程序可以提供帮助?

【问题讨论】:

标签: sql snowflake-cloud-data-platform data-modeling dbt data-integration


【解决方案1】:

我认为一个好的方法是在每个表格的顶部创建视图。 在这些视图中,您可以清理数据,例如处理 NULL 值,然后仅将视图用于 JOINing 以及您需要执行的任何其他下游报告/处理。

编辑以下对我的评论的回复, 您可以将记录添加到“未指定”和/或“未知”的每个维度(例如位置)中,例如Location_ID 为 -1 或 999999999 然后,您需要将包含 NULL 值的表(在此示例中参考 Location)更新为您想要的值(-1 或 999999999)。 然后,您可以将这些值设置为默认值,以使用这些键处理表上的任何新插入/更新。 然后您可以强制执行参照完整性。

【讨论】:

  • 问题不在于在哪里进行清理,而是关于如何以易于人们使用数据的方式进行清理的更温和的最佳实践。
  • 上述答案中的编辑评论是正确的。您的事实表不应在其键中包含空值,您需要在加载事实表的过程中强制执行这一点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-06
  • 1970-01-01
  • 2012-07-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多