我正在设计一个 Staging+NDS+DDS 数据仓库系统,其中 ETL 将规范化数据[Staging]
并将其加载到[NDS]
,它将保存所有历史记录。
我几乎完成了将在[NDS]
数据库中创建表和约束的 T-SQL 脚本,其中包含主表和事务表,它们将分别以我打算成为星型模式的形式提供[DDS]
维度表和事实表。
我给自己制定了以下规则:
- 表格采购
[DDS]
维度以DWD_
- 表格采购
[DDS]
事实以DWF_
- 外键列以
DWK_
- 代理键列的前缀与表的前缀相同。这意味着代理键总是:
DWD_Key
一张DWD_
桌子,或DWF_Key
一张DWF_
桌子。
- 控制列的前缀与表的前缀相同。例如...
- 该
DWD_Customers
表具有控制列:DWD_IsLastImage
DWD_EffectiveFrom
DWD_EffectiveTo
DWD_DateInserted
DWD_DateUpdated
DWD_DateDeleted
- 该
DWF_InvoiceHeaders
表具有控制列:DWF_DateInserted
DWF_DateUpdated
DWF_DateDeleted
- 该
- 主键(/代理键)总是以 with 为前缀,
PK_
后跟表名(包括表前缀)——例如PK_DWD_Customers
andPK_DWF_InvoiceHeaders
。 - 我还在自然键
unique
上添加了一个约束,它们总是以 with 为前缀,后跟表名(包括表前缀)——例如and 。NK_
NK_DWD_Customers
NK_DWF_InvoiceHeaders
- 外键列总是以 with 为前缀,
DWK_
后跟引用表的名称(不带前缀)和“Key”一词 - 例如DWK_CustomerKey
。 - 外键约束总是命名的
FK_[ParentTableNameWithPrefix]_[ChildTableNameWithPrefix]
。 - 当一个表对同一个表有多个 FK 时,FK 列的名称将附加到约束的名称,例如
FK_DWD_FiscalCalendar_DWF_OrderDetails_DeliveryDate
.
所有带前缀的列都没有业务意义,不应该出现在视图中;我发现,这给我留下了一个非常干净和一致的设计,以及create table
如下所示的脚本:
create table DWD_SubCategories (
DWD_Key int not null identity(1,1)
,DWD_DateInserted datetime not null
,DWD_DateUpdated datetime null
,DWK_CategoryKey int not null
,Code nvarchar(5) not null
,Name nvarchar(50) not null
,constraint PK_DWD_SubCategories primary key clustered (DWD_Key asc)
,constraint NK_DWD_SubCategories unique (Code)
);
所以,我的问题是,在我继续并实施 ETL 以将数据加载到该数据库之前,有什么我应该知道(或忘记)的吗?以后会不会有人继承这个数据库来追杀我的脑袋?我应该改变什么来避免这种情况?我询问前缀的原因是因为我正在使用DWD
and DWF
,但这些表在技术上不是“维度”和“事实”表。这令人困惑吗?
此外,我不确定自然键的概念- 我是否正确地假设它应该是源系统可能认为其“键”列的唯一列组合,我可以在 ETL 过程中使用它来定位,比如说, 要更新的特定记录?
总是至少还有一些你应该知道的事情,几乎同样,总是有一些你应该有意识地停止的事情。特别是在数据仓库的背景下,这是一个相对新兴的行业,利用了相对较新的技术。
就我在现实世界中所见所闻而言,第一次走进一家公司并看到我对您的设计的理解真的会让人流泪:喜悦和宽慰的泪水。从一开始,您就可以很好地开始一个看似经过深思熟虑(精心设计)的 ETL/数据仓库系统。与任何软件产品的实施一样,您的里程可能会随着解决方案的增长和业务消耗而变化,但从根本上说,您是在正确的轨道上(是的,您知道什么是自然键)。
我发现这些类型的解决方案存在许多挑战,我将提及这些挑战以加强您的一些决定,并可能为您提供一些关于前方道路的见解。首先,由于开发人员(甚至是数据库管理员/数据专业人员)误解了控制列的上下文(使用,例如针对该
DateInserted
列运行一个进程,仅仅是一次插入邮票,在DateReceived
或类似命名的列,打算将一行与特定的发生日期相关联),虽然我完全同意@Aaron Bertrand 提出的警告,但我觉得你的控制列的前缀实际上可以作为一种标志来利用帮助防止他们的滥用。显而易见当然应该是显而易见的,但是就像一般编写代码一样,显式更可取。就是说,我几乎肯定会在索引等之外留下这样的前缀(甚至可能是键 -PK
类型在我看来可以而且应该保留,但除非存在真正的威胁DWD_SubCategories
并且DWF_SubCategories
存在于同一模式中,否则它们真的只是绒毛) .DWD
我认为对和前缀的担忧DWF
是有道理的,但他们将生活在[NDS]
目录并将用于指示意图,因此以这种方式使用术语完全没问题。第二个(也许是最令人恼火的)挑战之一是对你的同事进行交叉培训。如果你的追求卓越的同事参与进来并且没有做到最好(或者公平地说,甚至只是表现不佳),所有的软件工程、使用标志和设计实践规则都将完全化为乌有天 )。请记住,大型项目通常有很多人参与其中,因此这些人必须表现良好。
我在这里要谈的最后一件事是始终牢记任何 ETL 系统对企业的实际价值。在 Extract、Transform 和 Load 范式中,第一个和最后一个字母绝对没有商业价值,因此您将希望尽可能减少对 Extract 和 Load 过程的开发和维护——“真正的”工作将在转换阶段完成,因此您将希望尽可能自动化 E 和 L 步骤,以便您可以通过积极进行转换来专注于使(并保持)您的解决方案对业务部门有价值。
综上所述,我只有机会研究过少数几个不同的仓储解决方案,所以如果我需要纠正,也许更有知识的用户可以介入并把我的脚从我嘴里移开。正如我最初所说的,这是一个人总是可以学习或忘掉一些东西的领域之一,我绝对也不例外。
哦,还有一件事(可能是最重要的)——单元测试!一旦您的 E 和 L 按预期工作并且您有机会通过 T 解决方案放置一些域,请找人来审查结果。如果它们很好,请将结果集保存在某个地方,这样当您进行更改时(毫无疑问,您会这样做),您可以确保您没有在其他地方破坏某些东西。同样,尽可能多地自动化此过程(这对企业来说是另一个 0 价值的过程,直到他们至少没有它;))。我通常为此目的设置一个单独的架构或目录。
希望我说的一些内容对你有用!
作为更新,@Aaron Bertrand 的模式分离似乎也是避免不必要的前缀的好方法,所以当然要考虑这一点(我知道我会的,哈哈)。