2013-04-17 53 views
1

我正在创建一个DW,用于吱吱声的OLTP。数据仓库设计 - 处理OLTP中的空值和空值

我面临的问题是OLTP数据库中没有太多的数据完整性。一个例子是郊区字段。

这个郊区字段是OLTP用户界面上的一个自由文本字段,这意味着我们在字段中有值,并且我们有空字符串,并且有NULL值。

我们通常会如何处理?我想出的方案是:

  1. 导入数据是(不理想)
  2. 在我的ETL过程,治疗任何空字符串同一个NULL并替换以单词“未知”在DW
  3. 进口都空在DW

字符串和NULL的为空字符串仅供参考,我使用的是微软的BI堆栈(SQL服务器,SSIS,SSAS,SSRS)

+1

为什么NULL在DW中是不可以的?我不明白从70年代开始遵循DW概念的愿望 - 如果出生日期不详,那不是1900-01-01。 –

+0

我可能会同意你的意见。这个问题更多的是关于在OLTP中处理空字符串V NULL的问题 – Paul

+1

这个问题非常类似于您担心在将数据移动到DW之后如何处理这些数据。如果你想纠正源OLTP系统,你应该在问题(和标题)中更加清楚。 –

回答

4

简短的回答是,它取决于NULL和空字符串在源系统中的含义。

这个一般问题(处理NULL)已经被讨论了很多,例如, here,here,here等。我认为最重要的一点是数据仓库只是一个数据库;它可能有一个非常特定类型的模式,并且是为一个目的而设计的,但它仍然只是一个数据库,并且仍然适用于任何关于NULL的一般建议。 (作为一个方面说明,我有时候更喜欢谈论“报告数据库”而不是“数据仓库”,因为它让事情保持透彻,一些DBA和开发人员开始为巨大的服务器群和多服务器群制定计划,但是最终它只是一个报告数据库。)

无论如何,它并不是完全清楚你想使用哪一个NULL,但它看起来像它可能是维度上的属性。

我(可能)不会使用你的三种方法中的任何一种,但它取决于你的数据的含义。按原样导入数据并不实用,因为数据仓库的部分价值在于数据已被清理并且一致,这使得查询和比较其他维度中的数据变得更加容易。

用'Unknown'替换空字符串可能正确也可能不正确:空字符串在源系统中的含义是什么? “这意味着没有郊区”和“这意味着我们不知道是否有郊区”有很大的区别。假设空字符串表示“没有郊区”,并且NULL表示“未知”,那么我会将空字符串原样导入,但将NULL替换为“未知”。这样做的主要原因是,如果Suburb字段将用作报表中的过滤条件,则用户(可能还有报表工具)会更容易使用“UNKNOWN”之类的非NULL值。如果源系统中没有一致性,并且您不知道空字符串和NULL是什么意思,那么您需要先澄清并理想地修复源系统(DWH的另一个好处是它有助于识别不一致性和源系统中的数据处理错误)。

您最后的想法将NULL s转换为空字符串是相同的问题:NULL实际上在源系统中意味着什么?如果它的意思是“没有郊区”,那么用空字符串替换它可能是一个好主意,但如果它意味着别的东西,那么你应该把它当作别的东西来处理。因此,总而言之,我的首选是按原样导入空字符串,并将NULL转换为“UNKNOWN”,但我无法确定这对您的情况是否有意义。这个问题没有单一的答案,因为这一切都取决于你的具体数据及其含义。但只要您始终如一地执行并清楚了解源系统如何处理数据,在数据仓库(或任何其他数据库)中使用NULL就没有问题。

+1

如果空字符串有多个可能的含义,它会变得更糟 - 如果这意味着“这个记录没有郊区,但它适用于该行;我们不知道是否有郊区;郊区存在但尚未加载;郊区不适用于此行“ –

+0

@NWest是的,我完全同意,这就是为什么您需要非常好地了解源系统的原因。根据我的经验,最糟糕的罪魁祸首是用户可定义的自定义字段或不可修改的第三方应用程序,因此用户(ab)使用现有的但未使用的字段来存储那些从来不存在的奇怪数据。当两个用户使用相同的字段表示不同的东西时,情况会更糟糕,这在像CRM这样的系统中并不少见:每个用户都只能看到他们自己的数据,因此他们倾向于考虑数据,甚至将GUI视为“他们的”。 – Pondlife

1

语义,NULL通常会是mea ñ未定义/未知。而空字符串将意味着该值已知为空。在你的郊区例子中,NULL可能意味着不知道给定记录是否有郊区,而“”可能意味着对于给定记录肯定没有郊区。

如果NULL和“的意思是”在你的情况相同,最好是归两个值,以同样的事情(说“导入到DW之前”),以方便以后做你的报告(以免具有NULL = 50和“”= 34并且必须将它们加在一起)。