【问题标题】:How to create collision-less unique key in Data Warehouse?如何在数据仓库中创建无冲突的唯一键?
【发布时间】:2021-05-18 21:33:04
【问题描述】:

我们在关系仓库中集成来自许多不同系统的表,然后在数据集市中对其进行维度化。但现在,我们真正关注的是关系仓库这一步。我们正在使用雪花云平台。

数据来自不同的表,我们决定在我们的仓库中创建一个用于本地化(翻译)的表。所有必要的翻译都将在此表中。如果我们只为每个实体使用给定的 ID,我们可能会遇到 id 冲突和非唯一 ID。

例如,我们可能在同一个本地化表中的国家和公司共享相同的 id,这些 id 在各自的表中是唯一的,但在这个联合表中不再是:

origin_table language_id name id_in_origin_table
Country 100 Germany 101
Country 200 Allemagne 101
... ... ... ...
Company 100 Mecanic Shop 101
Company 200 Garage Mécanique 101

显然我们不能使用 id_in_origin_table 作为唯一键,我们也不能使用 CONCAT(language_id, id_in_origin_table)

因此我们考虑添加一个列,该列将通过对原始表名称 + 值进行哈希处理来尝试唯一。

简化示例:hash('Country', country.id)

我们在源表和本地化表中都这样做是为了能够建立关系。但是您可能知道,大多数哈希函数生成的字母数字值的连接效率低于仅连接数字值的效率。 我们尝试将十六进制值交换为十进制对应值,然后进行算术运算以将 128 位 CHAR 值缩小为 64 位 BIGINT。但我们认为我们会发生相当高的碰撞风险。

对我们来说真的很重要:我们希望键只能是数字值。

所以问题是:

  • 有没有一种有效的方法来生成唯一的数字键?
  • 如果它意味着散列,应该优先使用哪种算法?
  • 您知道 Snowflake 中是否有一个原生函数可以在这种情况下帮助我们?
  • 是否有人有类似的问题,或者我们是否过度思考/以某种方式错过了整体情况?

非常感谢!感谢您的反馈!

【问题讨论】:

    标签: database snowflake-cloud-data-platform data-modeling data-warehouse


    【解决方案1】:

    看看使用序列。如果您在多个表中使用相同的序列,您将拥有唯一的 ID。根据详细信息,这可能无需创建表来管理您的密钥。

    https://docs.snowflake.com/en/user-guide/querying-sequences.html

    【讨论】:

      【解决方案2】:

      您所描述的并不是真正的代理键。如果您更改未发生在您的案例中的维度属性(例如名称),则代理键应保持不变。

      维护 代理键 的经典方法是包含自然键(在您的情况下为 table_name、lang Id 和 Id)和 surrogate_id 的映射表。该表用于通过查找转换自然键 -> 代理键,并且您为每个新自然键插入一条记录,并使用序列分配的代理键。

      这应该是您的基准,只有在您找到比上述解决方案更好的解决方案时才使用替代方案。

      自然键散列(顺便说一句,它不会产生 代理键,根据定义,如果自然键更改,代理键必须能够保持不变)被传播通过数据保险库。但是如果你选择DataVault,你就不应该关心哈希格式​​之类的细节。

      你在维度中的键定义和事实表中的使用之间获得独立性的论点是有效的,但你必须为此付出代价它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-06
        • 2014-02-23
        相关资源
        最近更新 更多