日期维度的代理键?

时间:2012-08-31 04:17:17

标签: oracle database-design oracle11g data-modeling

有两种思想流派:

  1. 使用代理键,最好采用以下格式:YYYYMMDD,因为这将始终如此 顺序。

  2. 取消日期维度代理键并改为使用实际日期。

  3. 我对维度建模专家的问题是:

    1> Which design would you prefer and why?
    
    2> How should we handle unknown values in each of the cases, Can we simply place 
       NULL in Fact table for unknown dates as Foreign Key can be NULL (if not why)?
    
    3> If we need to partition fact table on date column, how would we achieve that 
       in case 1.
    

    我倾向于使用实际日期并使用NULL来表示事实表中的UNKNOWN日期,因为日期相关的事实验证可以在不需要查看维度表的情况下完成。

3 个答案:

答案 0 :(得分:4)

Oracle的不寻常之处在于它的Date data type包含时间,需要7个字节。其他平台通常具有裸日期的独立数据类型。 SQL Server的日期需要3个字节,PostgreSQL需要4个字节,DB2需要4个(我认为)。

当您使用格式为YYYYMMDD的整数时,您必须在其他地方编写的其他代码以确保这些值是有效日期。 20121332是一个有效的整数,但它不代表有效日期。您不必为日期数据类型编写类似的验证代码。

在单个列中记录缺失信息时,两个选项之间没有太多差异。您要么使用不代表其他日期含义的日期,要么使用不代表其他整数含义的整数。编码原因数量很少 - 例如“1”可能意味着“尚未提供”,例如 - 意味着您必须在同一列中存储不是有效日期整数的值,其值为有效日期整数。

但是我认为将事实分离出一些数据从原因缺失的数据更有意义。这意味着存储更多数据,有些人不愿意存储更多数据。


我发现这两本IBM红皮书在设计数据仓库方面很有用。

Anchor modeling是最新的发展。以这种方式设计的架构中的大多数表都位于6NF

答案 1 :(得分:4)

你要问:

  1. Kimball对约会的替代关键词进行了抨击,但我还没有看到一个引人注目的技术论据,赞成这样做。转换为YYYYMMDD格式意味着您必须转换日期或连接日期维度以进行日期算术。这两种方法都有各种各样的方法可以解决查询计划。
    日期时间是SQL Server上的8个字节和Oracle上的(IIRC)7个字节,因此它比整数代理更广泛,但我不喜欢除非你有非常大的数据量,否则不再看到这个论点的优点。优化器只是将日期视为幕后的数值。

  2. 我对某种类型的“特殊”值有要求。根据您希望它们的排序方式,您可以使用各种值。在过去,我曾多次使用过这个方案:

    • 1800-01-01 for'previous'。除非您需要比此更早的日期,否则这将在开头排序。
    • 9000-01-01为'持续'。这将在最后排序。
    • 9100-01-01为'未知'。这将在最后排序。
    • 9200-01-01为'错误'。这将在结束时排序。
  3. 任何支持它的DBMS平台上的范围分区(包括几乎所有主流的RDBMS平台)都可以在日期或整数分区键上正常工作。

  4. 我不建议对数据仓库中的未知值使用NULL,因为它需要外部联接才能使用数据。这将影响查询计划的效率,并为没有经验的玩家提供数据陷阱。数据仓库中的NULL键在很多方面都是糟糕的。

    NULL键值的另一个问题是,大多数临时报告工具不能很好地与连接中的空键一起使用。通常,它们将使用内部联接,因此键列中具有NULL的行将会中断。

    对于大多数其他尺寸,您将使用代理。这会将维度与源数据分离,并允许您将新数据源引入系统,而不会中断现有数据。

    在某些情况下,将自然键作为维度键可能很有用。一个例子可能是ISO货币代码或帐号。在前一种情况下,3字母代码足够小,使得将其用作密钥的开销最小,并且编码方案(通常)在所有数据源中是通用的。在后一种情况下,代码通常是数字的,并且足够短,无论如何都要适合整数,并且通常在整个组织中是通用的。

    这样做的主要好处是您可以使用自己的查询来处理数据。它使得表格对于直接处理数据的人来说更容易辨认。

答案 2 :(得分:1)

1.优先使用代理键,格式为YYYYMMDD,因为这将始终是顺序的。

2.取消日期维度代理键并改为使用实际日期。

使用第一个选项。您使用实际日期,它将耗尽更多磁盘,索引效率更低,加入效率更低。此外,如果您使用日期类型,您将如何表示“未知日期”,“日期尚未提供”,“日期早于日历日期范围”,“日期晚于日历日期范围”?

对于日历维度的所有这些不同的“未知”类型成员,您不能使用“01 -01-1900”。理想情况下,所有代理键都应该没有意义,否则报表用户忽略维度太诱人了。维度增加了维度的丰富程度,例如日历维度,当天所属的星期,月份,年份,日期名称等等。记者应该通过匿名代理键强制使用维度。

您应该永远不会在数据仓库的表示层中有空值,因为它们会强制您在事实和维度之间执行左外连接。星型模式的重点是提高查询性能 - 执行外连接直接违反此原则。总是用未知的成员键替换空值,如-1,-2等等(假设你的'真实'成员键从1开始并从那里顺序上升)。

编辑Catcall

我建议使用代理键,其中日历中的最早日期获得密钥1,下一个日期获得2,依此类推。在星型模式中,事实由代理键组成 - 所有小整数或度量。您必须加入维度才能查看1代表的日期。这些代理人都没有任何意义。这就是你构建数据集市的方式。用户应该如何表示“01 -01-1900”表示“日期不可用”,“01 -01-1901”表示“未知”和“01 -01-1902”早期等等?将这些字幕存储在维度中并且事实上具有-3,-2,-1的代理不是更好。然后,用户将在报告中看到标题“未知”或“早期日期”。将日期类型作为代理键只是一个错误,并将限制解决方案的有用性,效率和灵活性。我通过经验知道这一点。