繁体   English   中英

在Qlikview中处理多个事实表

[英]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_factenrollment_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_codegrade_idgender_idethnicity_id 在关系模型中,每个关键字段都有一个对应的表,其中包含有关密钥的其他信息。 由于Qlikview根据字段的名称关联表格,因此该模型不符合Qlikview的关联性质; 即使你不想要它。 您确实希望命名字段与其查找表关联,但是您不希望事实表中的命名字段与关联。 不幸的是你无法阻止这种行为。 您必须实现链接表...

  1. 在Qlikview脚本中,创建一个临时事实表,该表加载到数据库表的所有字段中:

     [temp_test_scores]: LOAD school_code, test_code, grade_id, gender_id, ethnicity_id, subject_id, test_score; SQL SELECT * FROM <database connection> 
  2. 连接您的密钥并删除所有单独的密钥:

     [test_scores]: LOAD school_code & '_' test_code & '_' grade_id & '_' gender_id & '_' ethnicity_id & '_' subject_id as test_key, test_score RESIDENT [temp_test_scores]; 
  3. 对每个事实表重复步骤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]; 
  4. 通过将各个键连接到一个表中来创建链接表:

     [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] 
  5. 删除临时表,使它们不会出现在您的数据模型中:

     DROP TABLE [temp_test_scores]; DROP TABLE [temp_enrollment]; DROP TABLE [temp_link_table]; 

这将删除事实表之间的所有关联,因为它们之间现在不存在公共字段名称。 每个事实表将通过创建的连接密钥链接到链接表。 然后,链接表将与每个单独的查找表相关联。 您的Qlikview数据模型不包含任何合成键或循环引用。

如果您将来创建另一个事实表,只需再次执行步骤1和2,并将任何新的单个键添加到链接表,并将新的连接键添加到链接表中。 它可以轻松扩展。

祝好运!

在QlikView中建模数据以处理多个事实表有两种主要策略:

  1. 将事实表附加到一个事实表中 - 通常称为CON​​CATENATED FACT,因为QlikView将数据附加到表的语法是使用CONCATENATE前缀(相当于SQL UNION操作)

  2. 构建一个链接表(到目前为止你已经完成了)对于大多数实现,选项1是适当的方法。 CONCATENATED事实的属性可以概括为:

正面:

  1. 由于数据模型中大型表的数量减少,因此执行良好
  2. 易于实现,只需将所有数据附加到一个通用事实表,同时确保公共维度由公共字段名称引用

劣势:

  1. 不同的事实并不直接相互关联。 理解这一含义很重要。 这意味着事实的交叉分析通常只能通过共同维度来实现。 任何特定事实的维度都不以任何方式连接到不参考这些维度的事实的记录。 复杂的“集合分析”语法可以在某种程度上缓解这一缺点,但如果您的核心要求是通过事实B的事实特定维度对事实A进行间接分析,那么您可能需要转而使用链接表模型。

如何构建链接表是一个复杂的主题,但依赖于传统的数据库链接表设计技术。 很容易出错并生成链接表,这些表可能在前端产生正确的结果,但是过大,消耗内存和CPU资源。

根据我的经验,建模不良的QlikView数据模型是造成性能不佳的最常见原因。

我希望QlikView中的多事实建模的这一快速,远非详尽的介绍可以为您提供一些帮助,并为您提供正确的课程。

我能想到的最快捷的两种方式:

A)您可以将事实表连接到它们所使用的相应表中。您只需要重命名字段以避免与其他表冲突。

B)您可以重命名公共字段,这可以通过以下方式完成

  1. 使用QUALIFY (在加载事实表之前)和UNQUALIFY (在加载事实表之后)
  2. 使用“[旧字段名称]作为[新字段名称]”重命名字段

假设事实表具有可以链接到主表的唯一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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM