[英]Handling multiple fact tables in Qlikview
我有一个PostgreSQL数据库,其中包含各种教育数据,如学校级别的考试成绩和入学人数。 我需要将注册与测试分数分开,因为数据是在不同的谷物上。 即使注册与测试分数数据的粒度不同,但许多维度都是相同的。 例如,我有:
~ ---------------------------------------------------------------------------------~
| Test Scores Fact |
|-------------|-----------|----------|-----------|--------------|------------|-----|
| school_code | test_code | grade_id | gender_id | ethnicity_id | subject_id | ... |
|-------------|-----------|----------|-----------|--------------|------------|-----|
~ --------------------------------------------------------~
| Enrollment Fact |
|-------------|----------|-----------|--------------|-----|
| school_code | grade_id | gender_id | ethnicity_id | ... |
|-------------|----------|-----------|--------------|-----|
这种结构在后端很好,但在Qlikview中,这会创建一个合成密钥。 合成密钥的解决方案似乎通常是通过Qlikview脚本来替换它的链接表,这也是我的方法。 但这似乎没有扩展,因为当我添加第三个事实表(在另一个粒子上)包含更多相同的维度时,如果我创建另一个链接表,现在我的两个链接表开始关联,因为它们通常包含几个命名字段,Qlikview的回应是创建更多的合成密钥?
我对Qlikview比较陌生,而且我自己也在工作。 如何处理具有共同尺寸的不同颗粒的多个事实?
编辑:
我已经提供了解决这个问题的解决方案,这个问题已经在生产环境中工作了不到一年! 请参阅下面的答案......
看到这个问题的普及,我将把我的实际解决方案添加到混合中,这样人们就有了一个工作的例子,由于某种原因很难找到这样一个常见的问题......
我继续创建链接表。 这个解决方案至今仍然像一个黑客,因为它创建了一个巨大的表,其中包含所有事实表中每个键的笛卡尔积...但它确实有效。
问题 :您的数据库中有多个事实表; 几乎每个数据库都出现过一次。 这些事实表中的一些(或全部)共享相同的关键字段; 没问题,对吧? 错误。 不幸的是,由于Qlik的关联性质,而不是每个事实表都很好地链接到他们的查找表,你的事实表现在彼此关联并对你的数据模型造成严重破坏; 创建循环引用和无数量的合成键。
解决方案 :创建链接表。 听起来很简单吧? 嗯,确实如此,但如果没有初步解释,它也很难记录并且难以理解。 您可能想知道......什么是链接表? 它是所有事实表中所有键的笛卡尔积。 这如何解决问题? 它会删除事实表之间的所有不需要的关联,因为每个事件表现在只包含一个唯一的连接键。 这些唯一键仅与链接表关联,其中包含所有唯一的连接键以及所有单独的键。 随后链接表将与您的查找表关联,一切都会很好。
执行:
该实现将使用上述问题中包含的两个表; test_scores_fact
和enrollment_fact
。
test_scores_fact | enrollment_fact | school | gender | ...
---------------- | --------------- | ------ | ------ | ---
school_code (FK) | school_code (FK) | school_code (PK) | gender_id (PK) |
test_code (FK) | grade_id (FK) | school_name (FK) | gender_desc |
grade_id (FK) | ethnicity_id (FK) | address | ... |
gender_id (FK) | gender_id (FK) | ... |
ethnicity_id (FK) | number_enrolled (F) |
subject_id (FK) |
test_score (F) |
FK = Foreign Key
PK = Primary Key
F = Fact
如您所见,两个事实表具有重叠键, school_code
, grade_id
, gender_id
和ethnicity_id
。 在关系模型中,每个关键字段都有一个对应的表,其中包含有关密钥的其他信息。 由于Qlikview根据字段的名称关联表格,因此该模型不符合Qlikview的关联性质; 即使你不想要它。 您确实希望命名字段与其查找表关联,但是您不希望事实表中的命名字段与关联。 不幸的是你无法阻止这种行为。 您必须实现链接表...
在Qlikview脚本中,创建一个临时事实表,该表加载到数据库表的所有字段中:
[temp_test_scores]: LOAD school_code, test_code, grade_id, gender_id, ethnicity_id, subject_id, test_score; SQL SELECT * FROM <database connection>
连接您的密钥并删除所有单独的密钥:
[test_scores]: LOAD school_code & '_' test_code & '_' grade_id & '_' gender_id & '_' ethnicity_id & '_' subject_id as test_key, test_score RESIDENT [temp_test_scores];
对每个事实表重复步骤1和2:
[temp_enrollment]: LOAD school_code, grade_id, ethnicity_id, gender_id, number_enrolled; SQL SELECT * FROM <database connection> [enrollment]: LOAD school_code & '_' & grade_id & '_' & ethnicity_id & '_' & gender_id as enrollment_key, number_enrolled RESIDENT [temp_enrollment];
通过将各个键连接到一个表中来创建链接表:
[temp_link_table]: LOAD DISTINCT school_code, test_code, grade_id, gender_id, ethnicity_id, subject_id RESIDENT [temp_test_scores]; CONCATENATE ([temp_link_table]) LOAD DISTINCT school_code, grade_id, ethnicity_id, gender_id, number_enrolled RESIDENT [temp_enrollment]; /** * The final Link Table will contain all of the individual keys one time as well as your concatenated keys */ [link_table]: LOAD DISTINCT school_code, test_code, grade_id, gender_id, ethnicity_id, subject_id, school_code & '_' test_code & '_' grade_id & '_' gender_id & '_' ethnicity_id & '_' subject_id as test_key, school_code & '_' & grade_id & '_' & ethnicity_id & '_' & gender_id as enrollment_key RESIDENT [temp_link_table]
删除临时表,使它们不会出现在您的数据模型中:
DROP TABLE [temp_test_scores]; DROP TABLE [temp_enrollment]; DROP TABLE [temp_link_table];
这将删除事实表之间的所有关联,因为它们之间现在不存在公共字段名称。 每个事实表将通过创建的连接密钥链接到链接表。 然后,链接表将与每个单独的查找表相关联。 您的Qlikview数据模型不包含任何合成键或循环引用。
如果您将来创建另一个事实表,只需再次执行步骤1和2,并将任何新的单个键添加到链接表,并将新的连接键添加到链接表中。 它可以轻松扩展。
祝好运!
在QlikView中建模数据以处理多个事实表有两种主要策略:
将事实表附加到一个事实表中 - 通常称为CONCATENATED FACT,因为QlikView将数据附加到表的语法是使用CONCATENATE前缀(相当于SQL UNION操作)
构建一个链接表(到目前为止你已经完成了)对于大多数实现,选项1是适当的方法。 CONCATENATED事实的属性可以概括为:
正面:
劣势:
如何构建链接表是一个复杂的主题,但依赖于传统的数据库链接表设计技术。 很容易出错并生成链接表,这些表可能在前端产生正确的结果,但是过大,消耗内存和CPU资源。
根据我的经验,建模不良的QlikView数据模型是造成性能不佳的最常见原因。
我希望QlikView中的多事实建模的这一快速,远非详尽的介绍可以为您提供一些帮助,并为您提供正确的课程。
我能想到的最快捷的两种方式:
A)您可以将事实表连接到它们所使用的相应表中。您只需要重命名字段以避免与其他表冲突。
B)您可以重命名公共字段,这可以通过以下方式完成
QUALIFY
(在加载事实表之前)和UNQUALIFY
(在加载事实表之后) 假设事实表具有可以链接到主表的唯一id字段名称,则不必重命名主表中的任何内容
我会选择B-1,因为这似乎不那么麻烦。
QUALIFY
A,
B,
C,
ID;
FactTable1:
Load ID,
A,
B,
C,
From [FactTable1];
FactTable2:
Load ID,
A,
B,
C,
From [FactTable2];
UNQUALIFY
A,
B,
C,
ID;
编辑:如果你想从这些链接表创建一个链接表,你可以将事实表连接到一个表中,在其中将所有列放入其中(很多列都会有空值,但QlikView对空值很好)。
我通常做的是加载事实表并创建一个id字段(RowNo()或autonumberhash128([唯一id字段名列表]),然后当我将它们加载到链接表中时,我在链接中包含该id字段最后,我从事实表中删除了所有公共字段,因此它们只存在于链接表中。
但是,每个事实表都有一个“共享”字段的不同子集,因此我无法正确键入我的事实表。
您的笛卡尔维度的输入之一是针对主题和测试代码的“N / A”(因为它不在注册表中)
因此,当您使用“性别”进行衡量时,“测试分数”会与具有有效主题和测试代码的维度记录进行匹配,并且“注册”与“N / A”主题和测试代码的记录匹配
然后,当你按性别卷起时,每个人都会很好地工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.