Azure SQL 数据仓库代理键
Azure SQL Data Warehouse Surrogate Keys
所以 Azure SQL 数据仓库不支持标识列,因此处理代理键很棘手。有人对此有任何大胆的解决方案吗?
This 是我发现的最好的,而且非常可怕。
这是最佳选择 - 但您可以在 OVER 子句中使用常量值以避免必须对特定值进行排序,并且您不需要使用变量。
INSERT INTO testTgtTable (SrgKey, colA, colB)
SELECT
ROW_NUMBER() OVER(ORDER BY (SELECT 1)) + (SELECT ISNULL(MAX(SrgKey),0) SK FROM dbo.testTgtTable) SK
, [colA]
, [colB]
FROM testSrcTable;
Hash-based 代理键可以用 the moving from SMP to MPP Data Warehouses 替换 sequence-based 代理键并引入Hadoop、NoSQL 和其他大数据对您的 BI 生态系统的扩展。
以下是为什么要考虑基于哈希的代理键而不是基于序列的代理键的几个原因:
跨 BI 生态系统中的各种平台的一致代理键生成方法。可以在任何 ETL 工具(SSIS、DataStage 等)、任何 NoSQL 或 MPP 数据库或 Hadoop 实现的各种环境中独立生成一致的基于哈希的密钥。
与 ETL 相比,在 ELT 实现中,基于哈希逻辑的代理键比基于序列的代理键更有意义。 "Load the data into and then process it" (ELT) 是 MPP 和 BigData 解决方案中的首选方式。通过用散列值计算代替查找,简化了数据加载和转换过程。因此,这从 I/O 密集型操作(查找)转变为 CPU 密集型操作(哈希生成)。
通常所有数据loading/transforming进程都可以完全并行执行,因为可以避免表之间的依赖关系,因为基于散列的代理键是一致的并且可以独立生成。
经常在 real-time/near 实时数据更新场景中,基于散列的代理键可以即时生成,无需进行额外的查找,从而可以跳过暂存areas and do 直接插入到事实表中。
在开发、UAT 和生产环境中使用一致的代理键。
固定长度散列键上的联接在大多数 MPP 数据仓库平台上是相当理想的。
这里有几点建议:
使用自然业务键作为维度表中主键哈希函数的输入。
使用构成主键的串联自然业务键作为事实表哈希函数的输入。不要忘记按特定字符将连接的业务键分开,例如|, 避免意外碰撞。
使用自然业务键作为哈希函数的输入以链接到事实表中的维度。
但是,像往常一样,警告一下!基于散列的代理键可能会产生冲突,即给定两个不同的输入值可能会生成相同的散列值。更多相关信息,您可以阅读 here and here.
有时文件中存在行号或可以轻松添加。如果存在,则可以利用它来生成代理键值。这是一个多步骤过程
- 将数据加载到分段 table
- 对目标执行 MAX() 查找 table 代理键以获取当前最大值
- CTAS 或将分段 table 中的数据插入到目标中。将 max_count 常量添加到 row_number 值
代码看起来像这样:
DECLARE @max_count bigint
SET @max_count = (SELECT MAX(ID) FROM Fact)
...
CREATE TABLE Input_Load
WITH (DISTRIBUTION = ROUND_ROBIN
,CLUSTERED COLUMNSTORE INDEX
)
AS
SELECT @max_count + RowNumber
, ...
FROM dbo.stage_table
;
我认为基于业务密钥的哈希值的代理键不是一个好的解决方案,因为您提出的冲突问题非常突出。它违背了代理键的目的,即为 DW 提供唯一 ID 而不管 BK。 "Intelligent" 或 "Smart" 密钥的所有经典问题,或者与使用 BK 作为 PK 相关的那些问题仍然存在。
我们现在在 Azure SQL 数据仓库中具有标识列功能。
Link
Identity 列功能与 CTAS 语句不兼容,这大大减少了它作为 "solution"。它仅适用于在 ASDW
中表现不佳的 INSERTS、UPDATES、DELETES
所以 Azure SQL 数据仓库不支持标识列,因此处理代理键很棘手。有人对此有任何大胆的解决方案吗?
This 是我发现的最好的,而且非常可怕。
这是最佳选择 - 但您可以在 OVER 子句中使用常量值以避免必须对特定值进行排序,并且您不需要使用变量。
INSERT INTO testTgtTable (SrgKey, colA, colB)
SELECT
ROW_NUMBER() OVER(ORDER BY (SELECT 1)) + (SELECT ISNULL(MAX(SrgKey),0) SK FROM dbo.testTgtTable) SK
, [colA]
, [colB]
FROM testSrcTable;
Hash-based 代理键可以用 the moving from SMP to MPP Data Warehouses 替换 sequence-based 代理键并引入Hadoop、NoSQL 和其他大数据对您的 BI 生态系统的扩展。
以下是为什么要考虑基于哈希的代理键而不是基于序列的代理键的几个原因:
跨 BI 生态系统中的各种平台的一致代理键生成方法。可以在任何 ETL 工具(SSIS、DataStage 等)、任何 NoSQL 或 MPP 数据库或 Hadoop 实现的各种环境中独立生成一致的基于哈希的密钥。
与 ETL 相比,在 ELT 实现中,基于哈希逻辑的代理键比基于序列的代理键更有意义。 "Load the data into and then process it" (ELT) 是 MPP 和 BigData 解决方案中的首选方式。通过用散列值计算代替查找,简化了数据加载和转换过程。因此,这从 I/O 密集型操作(查找)转变为 CPU 密集型操作(哈希生成)。
通常所有数据loading/transforming进程都可以完全并行执行,因为可以避免表之间的依赖关系,因为基于散列的代理键是一致的并且可以独立生成。
经常在 real-time/near 实时数据更新场景中,基于散列的代理键可以即时生成,无需进行额外的查找,从而可以跳过暂存areas and do 直接插入到事实表中。
在开发、UAT 和生产环境中使用一致的代理键。
固定长度散列键上的联接在大多数 MPP 数据仓库平台上是相当理想的。
这里有几点建议:
使用自然业务键作为维度表中主键哈希函数的输入。
使用构成主键的串联自然业务键作为事实表哈希函数的输入。不要忘记按特定字符将连接的业务键分开,例如|, 避免意外碰撞。
使用自然业务键作为哈希函数的输入以链接到事实表中的维度。
但是,像往常一样,警告一下!基于散列的代理键可能会产生冲突,即给定两个不同的输入值可能会生成相同的散列值。更多相关信息,您可以阅读 here and here.
有时文件中存在行号或可以轻松添加。如果存在,则可以利用它来生成代理键值。这是一个多步骤过程
- 将数据加载到分段 table
- 对目标执行 MAX() 查找 table 代理键以获取当前最大值
- CTAS 或将分段 table 中的数据插入到目标中。将 max_count 常量添加到 row_number 值
代码看起来像这样:
DECLARE @max_count bigint
SET @max_count = (SELECT MAX(ID) FROM Fact)
...
CREATE TABLE Input_Load
WITH (DISTRIBUTION = ROUND_ROBIN
,CLUSTERED COLUMNSTORE INDEX
)
AS
SELECT @max_count + RowNumber
, ...
FROM dbo.stage_table
;
我认为基于业务密钥的哈希值的代理键不是一个好的解决方案,因为您提出的冲突问题非常突出。它违背了代理键的目的,即为 DW 提供唯一 ID 而不管 BK。 "Intelligent" 或 "Smart" 密钥的所有经典问题,或者与使用 BK 作为 PK 相关的那些问题仍然存在。
我们现在在 Azure SQL 数据仓库中具有标识列功能。 Link
Identity 列功能与 CTAS 语句不兼容,这大大减少了它作为 "solution"。它仅适用于在 ASDW
中表现不佳的 INSERTS、UPDATES、DELETES