我和我们公司的另一位 DBA 的任务是审查供应商为我们开发的数据库设计。供应商表示他们使用 Kimball 作为其设计的基础。(注意:我不是在寻找 Kimball 与 Inmon 等的论点。)他们设计了一个具有多个事实和维度的集市。
现在平心而论,我们公司从来没有设计过一个单一的市场。我们一直让顾问这样做。我们从来没有被派去上课或做任何事情。所以我们对仓储/集市/维度建模等的知识是基于我们所拥有的一点经验,我们可以在互联网上找到的内容,以及自读(我们有 Inmon 和 Kimball 的书,并正在努力通过它们) .
既然已经为我的知识水平设置了舞台,我们就来到了设计挑战。
有一个名为“索赔损失统计”的事实表(用于保险)。他们试图同时获取索赔的付款(累计到每月的水平),然后是准备金中的资金(有点像索赔的银行账户)。他们希望看到每月的付款金额(没什么大不了的)。但他们希望看到准备金的账户当前余额。
我举一个形象的例子。
假设我们为索赔设置了 1000 美元的准备金。这被搁置了(所以在某些方面它的功能有点像银行账户)。
2014 年 10 月,我们尚未支付任何款项。因此,企业希望查看 10 月底的付款和准备金余额。
-----------------------------------------------
- MONTH_YEAR - PAYMENTS - RESERVE_BALANCE -
-----------------------------------------------
- 102014 - 0.00 - 1000.00 -
-----------------------------------------------
Run Code Online (Sandbox Code Playgroud)
然后十一月来了。我们支付 100 美元、150 美元和 75 美元。他们希望看到这些合计金额和余额中的准备金如下:
-----------------------------------------------
- MONTH_YEAR - PAYMENTS - RESERVE_BALANCE -
-----------------------------------------------
- 102014 - 0.00 - 1000.00 -
-----------------------------------------------
- 112014 - 325.00 - 675.00 -
-----------------------------------------------
Run Code Online (Sandbox Code Playgroud)
然后说我们在 12 月付款为零,然后在明年 1 月再付款 …
根据我的阅读,基于订单标题/行项目结构的事实表的推荐粒度是在行项目级别。在此过程中,任何仅适用于订单标题的附加值都会为每个行项目重复:
下面(来自第二个链接)是这种设计的一个例子:

在此示例中,适用于整个订单的运费对每个订单项重复。
但是,如果您将所有运输金额归结到特定客户下,您的实际价值就会翻倍。您如何避免这种价值翻倍?
我正在使用数据仓库的星型模式,但遇到来自不同数据源的标题和行项目的问题。
CREATE TABLE DataSourceAHeader
(
OrderId INT NOT NULL
,TotalCost MONEY NOT NULL
-- Date, etc...
);
CREATE TABLE DataSourceALine
(
OrderId INT NOT NULL
,LineNumber INT NOT NULL
-- Dates, etc...
);
CREATE TABLE DataSourceBLine
(
OrderId INT NOT NULL
,Cost MONEY NOT NULL
,LineNumber INT NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
我有数据源 A 和 B,它们以不同的方式表示相同的数据。数据源 A 包含标题和行项目,但标题中仅包含净结果(总成本)。数据源 B 仅包含行项目,每个项目都有一个结果(成本)。
我可以保留两个事实表(一个用于标题,一个用于行项目),但我已经研究过,这似乎是不可取的。是否有处理这种不匹配格式的策略,还是应该将它们存储在单独的数据仓库中(每个数据源一个仓库)?
我目前的策略:
CREATE TABLE Fact.Order
(
Id BIGINT IDENTITY PRIMARY KEY
,OrderId INT NOT NULL
,Cost MONEY NOT NULL
-- …Run Code Online (Sandbox Code Playgroud) 据我所知:- 当维度表不能与事实表直接关联时,使用桥接表。
例如,在银行的数据仓库中,由于多个客户可以与同一个银行帐户相关联,因此不能使用客户 ID 作为事实表和客户维度之间的链接来存储客户余额的事实表。(即联名账户)
所以使用事实表存储账户ID和账户维度和客户维度之间的桥接表来区分。
但是它们与解决事实表和另一个维度之间多对多关系的辅助表有什么不同呢?
这是我一直在努力解决的一个思想问题。我对事实表中维度值的重复组合的概念有一种发自内心的反感。我已经阅读了很多关于当事实表中的维度组合没有形成唯一键时存在问题的信息。但是,我想了解可能出现的分析失败的确切类型。
请注意,我将事先规定,假设的丑陋事实表具有相同粒度的数据。 假设所有销售都是唯一报告的,但销售时间的最细粒度是一天。显然会有事务共享相同的维度值组合。因此,这种方法不会按照良好实践通常规定的方式汇总每天的交易。
我认为使用标准聚合的简单 DW 查询仍然是正确的。“简单”是指查询中只引用了一个事实表。在聚合/分析度量的通常形式中,我认为查询会产生正确的结果。
尝试通过组合所有维度来选择唯一的事实行会产生一种失败情况。我相信这些类型的查询实际上是未知的;我认为它们没什么用,除非用户想要真正深入到所有维度的最精细级别。我的想法正确吗?
我能看到的唯一可预测和常见的失败案例来自跨事实查询。在这里,额外的基数可能会乘以任何事实表中使用的任何度量。
对于我的学生(以及我的公司工作),我经常被问到“如果我不遵守这条规则会发生什么坏事?” 现在我担心我没有所有的答案。
预先感谢您的想法和答案。
data-warehouse database-design facttable dimensional-modeling
我有一个事实表 CardTransactionFact
表结构
TABLE [dbo].[CardTransactionFact]
[CardTransactionID] [int] IDENTITY(1,1) NOT NULL,
[TransactionTerminalID] [int] NOT NULL,
[SourceAccountTypeID] [int] NULL,
[DestinationAccountTypeID] [int] NULL,
[RimNo] [varchar](15) NULL,
[CaptureCodeID] [int] NOT NULL,
[RoutingCodeID] [int] NOT NULL,
[ProcessingCodeID] [int] NOT NULL,
[ActionCodeID] [int] NOT NULL,
[NetworkCodeID] [int] NOT NULL,
[ProductCodeID] [int] NOT NULL,
[AcquiringCountryCodeID] [int] NOT NULL,
[IssuingCountryCodeID] [int] NOT NULL,
[TransactionCurrencyCodeID] [int] NOT NULL,
[AmountBD] [decimal](18, 3) NOT NULL,
[LocalCurrencyCodeID] [int] NOT NULL,
[CardIssuerBank] [int] NOT NULL,
[CardTypeID] [int] NOT NULL,
[SuspectTransactionFlag] [char](1) NOT NULL, …Run Code Online (Sandbox Code Playgroud) performance index sql-server-2008 facttable query-performance
我开始为一家公司设计一个数据仓库。我们试图解决的第一个问题是关于他们的支持票务系统。我的初始架构如下

现在我们要问的问题之一是历史上任何时候都有多少票是有效的。
问题是票证将在某一天创建,但可能会在几天/几周/几个月内打开而不会更新或再次创建,这意味着即使票证每天都被打开,我们在创建票证时只有一个事实记录。
我不确定处理这个问题的最佳方法是什么,我想到的就是这个。
在一天开始时,任何尚未标记为已解决的票证都会在每天开始时将另一个票证输入到事实表中,无论是否有任何更新?这看起来是一个明智的解决方案吗?还是我错过了更简单的东西?
对架构的任何反馈也将不胜感激,因为我们仍然有时间更改它并从一开始就做好。
我有一个 Datawarehouse 星型架构。一张 Dim 表是“DimTweet”。这包含推文详细信息。
对于选定的日期,我希望能够显示推文的数量。
但是,我目前的设计有问题。对于 DimTweet tbl 中的多行,如何在 Fact tbl 中使用一个 TweetID 作为 FK?
代码:
INSERT INTO [CarDW].[dbo].[FactCarDetail]
([CarID]
,[RegionID]
,[DateID]
,[TweetID]
,[SharePrice]
,[ShareQty]
,[SalesQty]
,[TweetCountPositive]
,[TweetCountNegative])
SELECT
c.CarID,
r.RegionID,
d.DateKey,
-- ????? AS TweetID
scsp.Price,
scsp.Quantity,
scs.Quantity,
-- COUNT NO. OF TWEETS Postive
-- COUNT NO. OF TWEETS Negative
FROM
dbo.DimCar c
INNER JOIN
dbo.StagingCarSale scs
ON scs.CarModel = c.Model
INNER JOIN
dbo.DimRegion r
ON r.Region = scs.Region
INNER JOIN
dbo.DimDate d
ON d.Date = scs.SaleDate
--INNER …Run Code Online (Sandbox Code Playgroud)