在数据仓库中加载数据的最佳方式

Posted

技术标签:

【中文标题】在数据仓库中加载数据的最佳方式【英文标题】:Best way to Load Data in data warehouse 【发布时间】:2018-07-27 00:13:20 【问题描述】:

我们正在从头开始构建一个新的近实时(每 10 分钟刷新一次)医院数据仓库。数据位于 Oracle 数据库中,我们计划使用 SSIS 包从 Oracle 中提取数据并加载到 SQL Server 数据库中。我是 DWHousing 的新手,需要有关构建 DWH 的建议。

问题:

    从 Oracle 提取数据时,我应该导入完整的表还是应该只获取我想要的选定列? 例如:如果我有 person、address、facility_hist 表,我应该将它们加入提取包中并且只获取选定的列吗?或者我应该在暂存区分别提取所有三个表,然后将它们组合并加载到 SQL Server 中。

2)应该在目标表上或在提取数据时创建索引?

    我计划通过使用 create_dt_tm 来分批进行初始加载,并在几个月内加载数据。加载完所有内容后,我们计划使用 updt_dt_tm 并加载过去 10 分钟内完成的所有更新。

    连接到数据库每 10 分钟获取一次数据是个好主意吗?

图片显示了我计划使用的 DWH ETL SSIS 包(而不是平面文件,我将把它连接到 oracle DB)

【问题讨论】:

对于十分钟的刷新周期,您肯定会想出一种增量数据加载方法。最简单的方法是识别源中的现有字段,该字段在记录更改时进行记录。如果你有这个,那么你的增量负载将更快,更有可能适应十分钟的窗口。你设计过数据仓库模型吗?医疗数据仓库很棘手,因为数据源非常“键/值”,这不是最容易建模的东西。 感谢您的回复尼克。我们处于非常初始的阶段,但我已经设计了数据模型。我还确定了一个日期字段,每次向表中添加新行或更新任何旧行时都会更新该字段。(我是 DWH 的新手,但我曾在同一个健康数据库上工作过,我们需要为其设计 DWH ) 我现在只需要计划流程并尝试创建一个可能包含 2-3 个表的临时 DWH,以测试我们如何从 Oracle 中提取数据并使用 SSIS 包将它们加载到 SQL Server DWH 中。您对我的问题有什么建议吗? 我已经添加了一些细节,但这个问题真的太宽泛了 【参考方案1】:

这是一个非常广泛的问题,您还没有深入了解 将源医疗数据映射到业务友好的星型模式。

数据仓库要求和十分钟要求从何而来?对业务来说更重要的驱动因素是什么:只有十分钟的延迟,还是拥有一致的正确信息?我猜重点是运营(准入等),而不是财务或人力资源?

从 Oracle 提取数据时,我应该导入完整的 表还是应该只获得我想要的选定列?例如 : 如果我有 person,address,facility_hist 表,我应该加入它们吗 提取包,只得到选定的列?还是我应该 在暂存区分别提取所有三个表,然后合并 并将它们加载到 SQL Server 中。

在“ODS 层”方法中,您的 SQL 数据库中有 Oracle 表的完整副本(通常在不同的 SQL Server 架构中。请注意,Oracle 和 SQL Server 中的“架构”含义略有不同)

ODS 基本上是源系统的副本。如果您想要 10 分钟刷新,那么您需要在 ODS 中进行增量(仅限更改)加载。为此,您需要知道自上次加载 ODS 以来源代码发生了什么变化。如果源中有“上次更改”字段,这很容易。否则就很难了。

ODS 方法与“批量加载”模式一致,即数据在层中批量处理。 ODS 允许您在不同的层进行测试和故障排除。

ODS 方法不同于“流”方法,后者支持实时报告,但在整个流中包含隔离的转换规则。

应该在目标表上或在提取数据时创建索引?

通常应在数据加载之前禁用/删除表上的索引,然后再重建

我计划使用 create_dt_tm 用于记录并以月为单位加载数据。一次 一切都已加载,我们计划使用 updt_dt_tm 并加载 过去 10 分钟内完成的任何更新。

我不知道updt_dt_tm 是什么,但这听起来是个好主意

连接到数据库每 10 分钟获取一次数据是个好主意吗?

是的。否则您将如何获取数据?

总之,专注于让 10 分钟的 ODS 副本工作,基于增量负载。然后您的下一步是将数据从 ODS 转换为星型模式。

我们如何从 Oracle 中提取数据并使用 SSIS 包将它们加载到 SQL Server DWH 中。

同样,这是一个非常广泛的问题,我可以在这里为您输入一个完整的方法,但我认为我的付费客户不会喜欢它

许多设计模式。我更喜欢 T-SQL 繁重的 ELT(提取负载转换)ODS 方法,但根据我的经验是最好的方法。在这种方法中,您加载和暂存最近几天更新的记录,然后使用 SQL 将它们合并到 ODS 表中

只有一件事:我在您的问题历史中看到您在询问条件拆分。我只需要警告你,如果你开始在 SSIS 中使用条件拆分和查找来加载数据,那么你的包可能不会执行得很好,你最终会得到一些非常复杂的东西,而且它会吹爆你的十分钟。

这真的归结为 ETL 与 ETL 方法。如果您对 SQL 不满意,那么您可能不得不使用 ELT(SSIS 包中的所有登录)方法。但根据我的经验,它变得缓慢且难以维护

【讨论】:

10 分钟的要求来自医院和从事数据收集和分析工作的人员。这就是这个项目开始的原因。 “通常应该在数据加载之前禁用/删除表上的索引,然后再重建” 您是说我们应该每 10 分钟在提取数据时删除暂存数据库中的索引,然后在提取数据后重新构建它们吗?对不起,如果这是一个基本问题.. updt_dt_tm 是记录的更新日期时间.. 我认为我以错误的方式提出了这个问题。我只需要询问从数据库中提取数据作为 PROD 数据库的有效方法,我们不会通过每 10 分钟查询一次来影响数据库的性能 也许,也许不是。你必须试试看。这取决于表的大小、索引的数量等。最大程度地减少对源数据库的影响的最佳方法是确保updt_dt_tm 上有一个索引,以便尽可能高效地提取数据。然后将该数据本地导入 SQL Server 并在 SQL Server 端运行昂贵的转换,而不会影响源。这就是 ODS 方法:从源头获取数据。你也可以只创建某种 Oracle 数据库的镜像并解决它【参考方案2】:

我最近构建了一个具有类似要求的解决方案,但我的解决方案将 100 多个表从 Oracle EBS 数据库复制到“实时 BI”系统,延迟只有几秒钟。但是,我选择 Vertica 作为 DB 和 StreamSets 进行数据集成。

StreamsSets 专为流式传输而设计,使用单一数据管道,它可以处理我的所有表。它计算出所有列,甚至计算出用于更新目标数据库的键。

我使用 Vertica 是因为列式 MPP 数据库可以提供 100 倍于行式数据库的性能,并且不使用需要重建的索引。 Vertica 比最近的纯云列式数据库(如 RedShift、Snowflake 和 BigQuery)更成熟,并且设计了内存中的写入优化存储和磁盘上的读取优化存储,因此写入速度非常快。在幕后,元组移动器进程每五分钟压缩一次写入的数据,但查询始终通过合并这两个区域来返回最新数据。

我们将表设计视为 ODS/数据湖,但我确实选择排除 100% 空的列(StreamSets 只是跳过不在目标中的列)。我确实有一些定期刷新的表,例如我的日历表和度量单位转换,因为视图可能会影响性能并且它们不会经常更改。否则,我不理会这些表,而是使用视图和 Oracle BI 语义层数据建模来为业务构建用户友好的视图。由于数据库是列式的,即使表经常有超过 100 列,我的查询也非常快。

【讨论】:

谢谢丹。我们必须使用 SQL Server 作为目标数据库,因为团队知道如何使用它,而我的经理不想改变它。但如果有比 SSIS 更快、更灵活的工具从 Oracle 中提取并加载到 SQL Server 中,我们可以更改数据加载工具。 我明白了。 StreamSets Data Collector 可以像 Vertica 一样轻松地定位 SQL Server。我还应该提到它是 100% 开源的。它只需要数据库的 JDBC 驱动程序。它还具有针对 Oracle、SQL Server、mysql 和其他一些数据库的更改数据捕获步骤。我们已经在 MS SQL Server 上为我们的 MES 系统中的一系列表打开了更改跟踪,以便我们可以复制它们。对于所有 CDC 步骤,它利用数据库特定技术(Oracle 的 LogMiner)来检测您指向的表上的插入、更新或删除,并在您定位的任何数据库上执行相同的操作。

以上是关于在数据仓库中加载数据的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章

在数据块中加载增量表特定分区的最佳实践是啥?

如何使用 talend 中的 tmysql 行将唯一行从数据库加载到数据仓库中

为数据仓库创建 SQL Server 数据库的最佳实践

在数据仓库中保存大列数据的最佳方法

牛人大讲堂:京东数据仓库运营最佳实践

从 PostgreSQL 到数据仓库:近实时 ETL / 数据提取的最佳方法