将非规范化的数据移至Reporting DB

时间:2018-11-19 08:48:06

标签: sql sql-server database reporting-services

当前情况:

我们有一个包含所有业务数据的SQL数据库。有许多对象,例如客户,门票和产品。每个对象保存在多个表中,每个对象通常在8到12个表之间。因此我们的数据库现在有200多个表。

为了使报告更容易,我们想创建一个报告数据库,在其中我们对那些对象进行非规范化处理,以使其更易于访问,并改善实时数据库的性能,因为所有报告现在都从实时数据库中获取数据。

问题:

这是棘手的过去:我们还需要在目标/报告数据库中创建包含数据的新列,我们可以在其中存储计算出的数据以进行报告。例如,票证从头到尾花费了多长时间,或者谁订购了产品(以文本逗号分隔的形式被规范化)

问题是,什么是将数据传输到新数据库的最佳解决方案?我们想到的是不同的方法:

  • 使用存储过程:

创建一个sql脚本,使用例如merge将所有已定义的列传输到新数据库。缺点是,由于所有计算都必须由数据库本身来完成,因此可能会增加性能。

  • 创建客户端应用程序:

创建一个从实时数据库中选择数据的客户端应用程序,在运行时计算所有必要的列,并将其插入报告数据库中。

  • 使用SSIS作业:

这是上述两者之间的一种混合:ssis作业,用于获取数据,计算所有扩展列并将其放入报告数据库中。

我知道这可能是一个“基于意见”的问题,但是必须有一个最佳实践解决方案,因为我们不能是唯一有此需要的人。不幸的是,我真的可以在网上找到任何好的答案。

任何建议都非常感谢!

2 个答案:

答案 0 :(得分:2)

这个问题确实太广泛了,但我会尝试概述您可以使用的一些选项。

提取

选项1:创建直接从源表读取的,存储在源数据库本身或报表数据库中的存储过程(使用跨数据库调用(显然,这样做有缺点,即数据库被绑在一起))。这些过程应能够在完整(所有数据)和增量(仅最新)模式下运行。您可能还想为增量负载做一些重叠。

选项2:您设置了更改数据捕获(在此处发出以确保您不填写日志,但这可为您提供更详细的信息)或更改跟踪(仅获取记录的最新版本,而不是更改),然后从生成的更改表中读取以从源数据库获取更改的记录。

选项3:创建源数据库的只读副本并从此副本中读取。

转换

选项1:我个人的选择是在提取过程中使用SSIS。它是为执行此类操作而构建的。尤其是当您在服务器之间移动时,还可以从组织的其余部分引入数据,例如HR记录等。您应该在其中拥有一个项目的地方建立一个框架,每个项目都包含一个以完整或增量模式执行的SSIS包列表。您可以直接加载到源数据库中,也可以创建一个中间人数据库以准备任何复杂的数据以进行进一步处理。拾起它们后,您可能需要放下东西进行一些更复杂的事情。

选项2:您编写了存储过程,这些存储过程从源读取并直接推送到目标位置。可以将其与“提取”部分中的选项1结合使用。您将需要确保它们可以合并,因此可以使用单独的INSERT和UPDATE语句,也可以使用MERGE。

加载

选项1:将您的数据从ETL流程中放入星型或雪花模式(星型将需要较少的连接,并且SSAS中针对星型模式进行了内置优化)。然后,您可以使用它将数据移动到多维或表格模型的SSAS中。

选择2:按报表将数据放入报表所需的格式。显然,这可能会导致疯狂的数据集,但是如果只需要少量的报告而不会更改,那么它就会成功。这取决于...。

在尝试构建整个BI解决方案时,您的确确实有太多选择,我们都会对最适合您的事物有不同的想法。

答案 1 :(得分:0)

我最终做出了一种混合动力:

我创建了一个Web应用程序,该应用程序显示在对象模型中显示的所有对象和表。它允许您选择应该传输,非规范化哪个对象的哪些列。这样的输出将保存到一个表中,该表列出了ReportingDB中应该可用的所有列。

保存选定的列将创建:

  • LiveDB中的一个视图,选择所有这些列。每个对象基于对象模型的一个视图。

  • 一个存储过程,该过程将所有数据从“新”列移至报表DB。 新列是尚未传输的列。该存储过程在夜间每24小时触发一次,以避免对LiveDB造成任何影响。

  • “更新”存储过程,用于传输更新报告数据库中所有日期时间戳与报告数据库不相等的所有数据行。此SP每15分钟触发一次。

  • 一个名为“ objectname” _aggregates的存储过程,只会创建一次。 它允许您添加自定义函数以用数据填充聚合列。更新SP之后,每15分钟就会触发一次此SP。您可以根据已传输的列来计算聚合列的内容,也可以从旧值到新值来计算“增量”(如果需要进行复杂的时间计算等...)

所有存储过程总是从以前创建的视图中选择数据。