在阅读业务对象的书籍时,我遇到了术语 - 事实表和维度表.
我想了解Dimension表和Fact表之间有什么不同?
我在互联网上阅读了几篇文章,但我无法理解.
任何简单的例子都会帮助我更好地理解?
我是数据仓库的新手.首先,我想比我的数据仓库工具包的副本在我的邮箱(蜗牛邮件:P)的路上精确.但我已经用网上找到的东西研究了所有这些东西.
然而,我在网上找不到的是当你在DW中看到多个事实时该怎么办.在我的情况下(保险),我退款是非定期发生的.一个客户可以在3个月内没有,然后在同一个月内没有.另一方面,我有"订阅费"(不确定什么是正确的英语术语,但你明白了),每个月或每三个月发生一次.这对我来说显然是两个截然不同的事实.
这两者是某种程度的松散耦合,如客户或"保险产品".现在是这两个不同的仓库,我必须在其上生成两个不同的报告,然后将报告连接到DW之外?或者有没有办法设计它以适应单个下降DW.或者我应该将这两个事实结合在一起?那么我可能会在退款时失去粒度.
我读过的一些博客说DW总是有一个事实表.其他人提到了使用S设计什么是事实表的步骤,但是没有明确的说明它们之间是否存在链接,或者它们只是同一DW项目的不同组件.
有没有人知道关于DW设计精确部分的一些参考文献?
我的数据仓库中有一些实体:
人 - 具有属性personId,dateFrom,dateTo和其他可以更改的人,例如姓氏,出生日期等 - 慢慢变化的维度
文档 - documentId,数字,类型
地址 - addressId,city,street,house,flat
(人与文件)之间的关系是一对多,(人与地址)是多对多的.
我的目标是创建历史事实表,可以回答以下问题:
2,居民的定义地址在规定的时间间隔内有什么历史?
这不仅适用于DW的设计,但我认为这是DW设计中最难的事情.
例如,布朗小姐的personId = 1,自01/01/2005至02/02/2010以来,documentId = 1且documentId = 2的文档已经存在于addressId = 1的地址,然后移至addressId = 2从2010年2月2日开始生活到当前日期(NULL?).但她自2006年5月4日起将姓氏改为格林夫人,自2007年7月6日起,她的第一份文件记录为documentId = 1至documentId = 3.带有personId = 2的Black先生,自2010年2月2日至今日,documentId = 4一直存在于addressId = 1.
对于问题2的查询的预期结果,其中addressId = 1,时间间隔是从01/01/2000到现在,必须如下:
行:
last_name="Brown", documentId=1, dateFrom=01/01/2005, dateTo=04/04/2006
last_name="Brown", documentId=2, dateFrom=01/01/2005, dateTo=04/04/2006
last_name="Green", documentId=1, dateFrom=04/05/2006, dateTo=06/06/2007
last_name="Green", documentId=2, dateFrom=04/05/2006, dateTo=06/06/2007
last_name="Green", documentId=2, dateFrom=06/07/2007, dateTo=02/01/2010
last_name="Green", documentId=3, dateFrom=06/07/2007, dateTo=02/01/2010
last_name="Black", documentId=4, dateFrom=02/03/2010, dateTo=NULL
Run Code Online (Sandbox Code Playgroud)
我有一个想法,用复合键(personId,documentId,addressId,dateFrom)创建事实表,但我不知道如何加载此表,然后使用此结构获得预期的结果.
我会很高兴得到任何帮助!
我听说过一些参考资料,事实表上不需要pk.我相信每张桌子都应该有一个PK.
如果没有pk和10+外键,一个人怎么能理解事实表中的一行呢?
想象一下PostgreSQL 9.0上具有以下结构的表:
create table raw_fact_table (text varchar(1000));
Run Code Online (Sandbox Code Playgroud)
为了简化起见,我只提到一个文本列,实际上它有十几个.该表有100亿行,每列有很多重复.该表是使用COPY FROM从平面文件(csv)创建的.
为了提高性能,我想转换为以下星型模式结构:
create table dimension_table (id int, text varchar(1000));
Run Code Online (Sandbox Code Playgroud)
然后将事实表替换为如下事实表:
create table fact_table (dimension_table_id int);
Run Code Online (Sandbox Code Playgroud)
我当前的方法是基本上运行以下查询来创建维度表:
Create table dimension_table (id int, text varchar(1000), primary key(id));
Run Code Online (Sandbox Code Playgroud)
然后创建填充我使用的维度表:
insert into dimension_table (select null, text from raw_fact_table group by text);
Run Code Online (Sandbox Code Playgroud)
之后我需要运行以下查询:
select id into fact_table from dimension inner join raw_fact_table on (dimension.text = raw_fact_table.text);
Run Code Online (Sandbox Code Playgroud)
想象一下,通过多次将所有字符串与所有其他字符串进行比较,我获得了可怕的性能.
在MySQL上,我可以在COPY FROM期间运行存储过程.这可以创建字符串的哈希值,并且所有后续字符串比较都是在哈希而不是长原始字符串上完成的.这似乎不可能在PostgreSQL上,我该怎么办?
样本数据将是包含类似内容的CSV文件(我也使用整数和双精度的引号):
"lots and lots of text";"3";"1";"2.4";"lots of text";"blabla"
"sometext";"30";"10";"1.0";"lots of text";"blabla"
"somemoretext";"30";"10";"1.0";"lots of text";"fooooooo"
Run Code Online (Sandbox Code Playgroud) 我有一个维度(SiteItem)有两个重要的事实:
perUserClicks
perBrowserClicks
Run Code Online (Sandbox Code Playgroud)
但是,在这个维度中,我有一组基于属性列的值(让我们调用组AboveFoldItems,LeftNavItems,OnTheFlyItems等)每个都有更多特定于该组的事实:
AboveFoldItems: eyeTime, loadTime
LeftNavItems: mouseOverTime
OnTheFlyItems: doesn't have any extra, but may in the future
Run Code Online (Sandbox Code Playgroud)
以下事实表架构是否正常?
DateKey
SessionKey
SiteItemKey
perUserClicks
perBrowserClicks
eyeTime
loadTime
mouseOverTime
Run Code Online (Sandbox Code Playgroud)
这看起来有点浪费,因为只有一些列属于某些维度键(不相关的事实都是NULL).但是......这似乎是一个常见的问题,所以应该有一个共同的解决方案,对吧?
我正在尝试建立一个数据集市.
我有很多维度和一些措施 - 事实.每项措施都与业务方面的所有维度相关联.有一种标准方法,将有一个包含所有措施的重要事实表.
但我有一个想法:如果每个度量都有单独的事实表,该怎么办?它将如何处理数据库性能,解决方案扩展性等?
编辑:::在非常复杂的企业环境中,基于olap立方体的巨大解决方案.因此,首先需要的是易于扩展和维护,然后是性能
extensibility database-design data-warehouse fact-table business-intelligence
我实际上是在建模数据仓库
在我的一个事实表中,我有3个数据(我想要分析的数字).问题是,我将首先填写其中一个号码,稍后(几天)填写另外两个号码.
在DW中这样做是不是坏事(因为"没有修改表"法)?
我想到的另一个解决方案是将第一个数字放在第一个事实表中,将另外两个放在第二个事实表中.当然,2 FT将链接到相同的维度表.这个解决方案对我来说似乎很好,但稍后比较数据可能会更重一些.
-
我谈到的数据是关于工作时间的.首先,员工将他的工作时间(未经验证)放在DB中,这是我的第一个属性(Qe).然后老板验证或修改(或不修改)这个数据,它给我另一个属性(Qa)有时两个属性将同时加载到DW中(如果快速验证),有时不会
那么您如何看待它,哪种解决方案更好/更清洁?
求助于你
我每天在DimPerson维度表中跟踪员工更改,并在每个月末填写我的事实表并计算员工,退出和员工人数.对于这个例子,假设我将填写4月30日月底的事实表.现在这就是我面临的问题:我在4月17日有一个员工记录,这是一个"雇佣"行动,所以在那个时候,我的DimPerson表读起来像这样:
+-------+-----------+----------+--------+--------------------+-------+
| EmpNo | Firstname | LastName | Action | EffectiveStartDate | isCur |
+-------+-----------+----------+--------+--------------------+-------+
| 4590 | John | Smith | Hire | 4/17/2017 | Y |
+-------+-----------+----------+--------+--------------------+-------+
Run Code Online (Sandbox Code Playgroud)
现在2天后,我看到同一个员工,但是有一个动作"经理改变",所以现在我的DimPerson表变为:
+-------+-----------+----------+-----------------+--------------------+-------+
| EmpNo | Firstname | LastName | Action | EffectiveStartDate | isCur |
+-------+-----------+----------+-----------------+--------------------+-------+
| 4590 | John | Smith | Hire | 4/17/2017 | N |
| 4590 | John | Smith | Manager Change | 4/19/2017 | Y |
+-------+-----------+----------+-----------------+--------------------+-------+
Run Code Online (Sandbox Code Playgroud)
因此,在月末,当我选择所有"当前"员工时,我会错过这个人的雇佣捕获,因为他最近的记录只是经理变更而实际招聘发生在"月内".在进行定期快照时,您是否可以错过某些更改?在这种情况下,你建议我做什么来捕捉雇佣行动?
fact-table ×9
database ×1
datahistory ×1
dimension ×1
etl ×1
mysql ×1
postgresql ×1
primary-key ×1
sql ×1
sql-server ×1
star-schema ×1