使用Pentaho Kettle,如何在保持参照完整性的同时从单个表中加载多个表?

blu*_*ers 21 mysql etl pentaho kettle

需要将具有100,000多条记录的单个文件中的数据加载到MySQL上的多个表中,以维护文件/表中定义的关系; 意味着关系已经匹配.该解决方案应该适用于最新版本的MySQL,并且需要使用InnoDB引擎; MyISAM不支持外键.

我是一个全新的使用Pentaho数据集成(aka Kettle),任何指针将不胜感激.

我可能会补充说,要求不禁用外键约束.由于我的理解是,如果数据库的引用完整性存在问题,MySQL将不会在重新打开外键约束时检查引用完整性.消息来源: 5.1.4.服务器系统变量 - foreign_key_checks

如果插入失败,或者无法保持参照完整性,则所有方法都应包括验证和回滚策略中的一些.

再次,对此全新,并尽力提供尽可能多的信息,如果您有任何问题或要求澄清 - 请告诉我.

如果您能够从超级的kjb和ktr文件(作业/转换)发布XML.甚至可能追捕你在任何地方所做的每一条评论/答案,然后投票给他们...... :-) ......真的,找到答案对我来说真的很重要.

谢谢!


示例数据:为了更好地举例说明,我们假设我正在尝试加载一个包含员工姓名的文件,他们过去占用的办公室以及用标签分隔的职位名称历史记录.

文件:

EmployeeName<tab>OfficeHistory<tab>JobLevelHistory
John Smith<tab>501<tab>Engineer
John Smith<tab>601<tab>Senior Engineer
John Smith<tab>701<tab>Manager
Alex Button<tab>601<tab>Senior Assistant
Alex Button<tab>454<tab>Manager
Run Code Online (Sandbox Code Playgroud)

注意:单表数据库是完全标准化的(可能只有一个表) - 例如,在"John Smith"的情况下,只有一个John Smith; 意味着没有重复会导致参照完整性的冲突.

MyOffice数据库架构有如下表:

Employee (nId, name)
Office (nId, number)
JobTitle (nId, titleName)
Employee2Office (nEmpID, nOfficeId)
Employee2JobTitle (nEmpId, nJobTitleID)
Run Code Online (Sandbox Code Playgroud)

所以在这种情况下.表格应如下所示:

Employee
1 John Smith
2 Alex Button

Office
1 501
2 601
3 701
4 454

JobTitle
1 Engineer
2 Senior Engineer
3 Manager
4 Senior Assistant

Employee2Office
1 1
1 2
1 3
2 2
2 4

Employee2JobTitle
1 1
1 2
1 3
2 4
2 3
Run Code Online (Sandbox Code Playgroud)

这是用于创建数据库和表的MySQL DDL:

create database MyOffice2;

use MyOffice2;

CREATE TABLE Employee (
      id MEDIUMINT NOT NULL AUTO_INCREMENT,
      name CHAR(50) NOT NULL,
      PRIMARY KEY (id)
    ) ENGINE=InnoDB;

CREATE TABLE Office (
  id MEDIUMINT NOT NULL AUTO_INCREMENT,
  office_number INT NOT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB;

CREATE TABLE JobTitle (
  id MEDIUMINT NOT NULL AUTO_INCREMENT,
  title CHAR(30) NOT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB;

CREATE TABLE Employee2JobTitle (
  employee_id MEDIUMINT NOT NULL,
  job_title_id MEDIUMINT NOT NULL,
  FOREIGN KEY (employee_id) REFERENCES Employee(id),
  FOREIGN KEY (job_title_id) REFERENCES JobTitle(id),
  PRIMARY KEY (employee_id, job_title_id)
) ENGINE=InnoDB;

CREATE TABLE Employee2Office (
  employee_id MEDIUMINT NOT NULL,
  office_id MEDIUMINT NOT NULL,
  FOREIGN KEY (employee_id) REFERENCES Employee(id),
  FOREIGN KEY (office_id) REFERENCES Office(id),
  PRIMARY KEY (employee_id, office_id)
) ENGINE=InnoDB;
Run Code Online (Sandbox Code Playgroud)


我对回答所选答案的说明:

PREP:

  1. (a)使用示例数据,通过更改<TAB>为逗号分隔来创建CSV .
  2. (b)使用MySQL DDL示例安装MySQL并创建示例数据库
  3. (c)安装Kettle(它是基于Java的,可以运行任何运行Java的东西)
  4. (d)下载KTR文件

数据流步骤:(我的笔记)

  1. 在Kettle中打开KTR文件,然后双击"CSV文件输入"并浏览到您创建的CSV文件.分隔符应已设置为逗号.然后单击"确定".
  2. 双击"插入员工"并选择数据库连接器,然后按照创建新数据库连接上的这些说明进行操作

rwi*_*ams 34

我根据您提供的内容整理了一个示例转换(右键单击并选择保存链接).我觉得有点不确定的唯一步骤是最后一个表输入.我基本上是将连接数据写入表中,如果已存在特定关系则让它失败.

注意:

这个解决方案并没有真正满足"所有方法应该包括一些来自验证和回滚策略,如果插入失败,或者无法保持参照完整性." 标准,虽然它可能不会失败.如果你真的想要设置复杂的东西我们可以,但这绝对可以让你进行这些转换.

替代文字

数据流逐步

1.我们首先阅读您的文件.在我的情况下,我将其转换为CSV,但标签也很好. 替代文字

2.现在我们将使用a将员工姓名插入Employee表combination lookup/update.插入之后,我们将employee_id附加到数据流中,idEmployeeName从数据流中删除.

替代文字

3.这里我们只是使用Select Values步骤将id字段重命名为employee_id 替代文字

4.插入作业标题就像我们做员工一样,并将标题ID附加到我们的数据流中,同时删除JobLevelHistory数据流.

替代文字

5.将标题ID简单重命名为title_id(参见步骤3) 替代文字

6.插入office,获取id,从流中删除OfficeHistory.

替代文字

7.将office id简单重命名为office_id(参见步骤3)

替代文字

8.将数据从最后一步复制到两个流中employee_id,office_id,employee_id,title_id分别使用值和.

替代文字 替代文字

9.使用表插入来插入连接数据.我已选择忽略插入错误,因为可能存在重复,PK约束会使某些行失败.

输出表

替代文字

替代文字

替代文字

替代文字

替代文字

  • 不要担心赞成我的任何帖子.如果你顺利的话,我会很高兴的.我觉得很难告诉你使用pentaho,然后让你盲目地去做. (2认同)