Sql server 如何为事实表建模

Sql server 如何为事实表建模,sql-server,database-design,data-warehouse,Sql Server,Database Design,Data Warehouse,我将在星型模式中创建一个包含事实和维度的数据仓库 我想回答的业务问题通常是: 第一季度我们卖了多少钱 我们在第一季度向女性销售了多少钱 在第一季度,我们向30-35岁的女性销售了多少钱 在第一季度,我们向居住在纽约的30-35岁女性出售了多少钱 在第一季度,我们向居住在纽约的30-35岁女性出售了多少钱 去年我们的同类服装卖了多少钱 去年我们卖了多少钱的蓝色牛仔裤产品 去年,我们向居住在澳大利亚的40-42岁的男性出售蓝色牛仔裤的价格是多少 我正在考虑一个粒度为小时的日期维度(指定年、月、日

我将在星型模式中创建一个包含事实和维度的数据仓库

我想回答的业务问题通常是:

  • 第一季度我们卖了多少钱
  • 我们在第一季度向女性销售了多少钱
  • 在第一季度,我们向30-35岁的女性销售了多少钱
  • 在第一季度,我们向居住在纽约的30-35岁女性出售了多少钱
  • 在第一季度,我们向居住在纽约的30-35岁女性出售了多少钱

  • 去年我们的同类服装卖了多少钱

  • 去年我们卖了多少钱的蓝色牛仔裤产品
  • 去年,我们向居住在澳大利亚的40-42岁的男性出售蓝色牛仔裤的价格是多少
我正在考虑一个粒度为小时的日期维度(指定年、月、日、小时、季度、日名称、月名称等) 我还考虑了产品维度和用户维度

我想知道这些问题是否可以用一个事实表来回答,或者创建多个事实表是否合适?我正在考虑一张桌子,例如:

FactSales

DimDate-fk到包含日期信息的表(例如季度、星期几、年、月、日)

DimProduct-fk到包含产品信息的表,例如(产品名称)

DimUser-fk到包含用户信息的表,例如(年龄、性别)

TotalSales—特定日期、产品和用户的所有销售额的总和

另外,如果我想测量展位的总销售额(钱)和总销售额?创建具有相同维度但使用TotalNumberOfSales作为事实的新事实表是否合适


感谢所有我能得到的关于这方面的意见。

我认为你的思路是正确的。以上所有问题都可以用一个事实表来回答

我认为一开始应该不加合计,如果需要的话,以后再加合计。考虑到一次销售可以包含多个产品和多个项目,我将按如下方式组织它。。。销售中每个产品的一个事实行(通常是发票上的行,所以我称之为“订单行”或“销售行”),可能还有三个计数器属性:

  • NumItems
    -项目数量,即如果客户购买了三个相同的产品,则为3
  • NumLines
    “订单行”的数量应始终为1。在以后聚合数据时(big win在SQL中已经有了
    sum(NumLines)
    而不是
    count(*)
    ),或者在添加更正项时(
    NumLines=-1
    )可能很有用
  • NumSales
    -一个小数,可以将其相加得出销售数量(即,如果销售涉及三种不同的产品,因此包含三个订单行,则为0.333)
现在,要获得正确的计数,即“涉及黑衣服的销售数量”,将遇到一个问题。我们在我以前的工作场所遇到了这个问题——我相信一定存在一些“最佳实践”,我们或多或少地在事实表(或
TransactionID
)中引入了
SaleID
)并进行了
计数(不同的SaleID)
。这缺乏优雅,但有效

在我们的设置中,我们有几个金钱属性——最重要的是,一个是收入(在支付了销售物品的直接成本后剩下的收入),另一个是营业额(客户为物品支付的价格)。销售税或增值税可能会增加更多的复杂性。可以只使用一个money属性,然后在事实表中将销售拆分为多行,但我认为我更倾向于推荐sales line事实表中的多个money列。事实表中的所有内容都以“基础货币”(在我们的例子中是欧元)计算,然后我们有一个汇率维度来跟踪准确的金额


我认为用日期维度包含一天中的小时是没有意义的。在我以前的工作中,我把我的仓库放在博士后,实际上我在没有日期维度的情况下管理得相当好——尽管日期维度被认为是“最佳商业实践”我发现从性能角度来看,通过使用标准的postgres日期函数,而不是在日期维度中拖动,我们获得了更好的性能。我一直在玩它,我想最后我发现最理想的方法是把日期和时间分成两个不同的属性。(时区和夏令时给了我很多额外的麻烦…

我同意托比森的观点-你走的是对的

我建议您阅读拉尔夫·金博尔(Ralph Kimball)的书《数据仓库工具包》(The Data Warehouse Toolkit),特别是关于零售销售的一章——它深入介绍了一个销售事实

日期维度类似于拥有一个日历表——您可以根据季度、会计月和其他特定于日期的业务进行拆分。我通常会保留日期键和时间戳数据类型,这样我们就可以使用财政日历进行操作。如果你需要一个单独的时间维度,比如一天中的几个小时,或者几分钟,等等。我怀疑你是否需要每小时一次

下面是我要做的:

声明事实表的粒度:

每订单行1行

请注意,颗粒如何不包含任何不唯一标识行的内容

订单行的维度属性:

Date
Time (if needed, and bucketed by hour/minute etc)
Product
Customer
订单行的退化维度(这些是与交易相关的代码):

一些抽样措施:

Item Price at time of Sale (optional, may be useful in some situations)
Discount Amount
Sale Dollars
这应该回答所有这些问题

对于总计,在对维度的属性进行过滤后进行简单的计数/求和应该可以正常工作

你应该考虑这一点。
Item Price at time of Sale (optional, may be useful in some situations)
Discount Amount
Sale Dollars