etl - Talend 将平面文件规范化为关系数据库表

标签 etl talend database-normalization

我们有一个单一的源表,它是扁平的——我们需要将给定记录中的不同字段插入到多个表中。我们成功地使用了一次lastInsertID,但我们正在努力解决如何在后续相关表中再次从同一源行重新添加字段。

例如,如果我们有一个邮寄地址(即将出现的愚蠢示例,但适合共同讨论)

-----------Source----------
First Name
Middle Name
Last Name
Address 1
Address 2
City
State
Zip

-----------Targets-------------

People
 address_id
 First Name
 Last Name

Address
 address_id
 state_id
 zip_id
 Address 1
 Address 2

States
 state_id
 State Name

Zip
 zip_id
 Zip Code

此外,我们无法确定是否不需要将同一列添加到多个表中。

Talend 中这种数据标准化的最佳实践是什么?

最佳答案

我会迭代地处理这个问题,每一步都对表的一部分进行标准化。

您应该能够一步将个人数据从地址、州和邮政编码数据中标准化,然后将州从地址和邮政数据中标准化,最后将邮政数据从地址的其余部分中标准化.

作为一个例子,按照您问题中的示例,这里有一些工作可以做到这一点:

首先,我们应该创建示例数据。我将在本示例中使用 MySQL,但相同的原则适用于任何主要的 RDBMS。

让我们首先创建一个空表:

DROP DATABASE IF EXISTS normalisation;

CREATE DATABASE IF NOT EXISTS normalisation
CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE IF NOT EXISTS normalisation.denormalised (
    FirstName VARCHAR(255),
    MiddleName VARCHAR(255),
    LastName VARCHAR(255),
    Address1 VARCHAR(255),
    Address2 VARCHAR(255),
    City VARCHAR(255),
    State VARCHAR(255),
    Zip VARCHAR(255)
) ENGINE = INNODB;

为此,我们需要使用一些示例数据填充它,这可以使用 Talend 的 tRowGenerator 组件轻松完成:

Row generating job layout

我已经配置了 tRowGenerator 来为我们提供一些半合理的测试输出:

tRowGenerator component

我还添加了一个额外的步骤,使用以下 tMap 配置将一些同居者添加到约 1/3 的地址:

tMap configuration to add co-habitors to some addresses

现在我们已经轻松生成了测试数据,我们可以继续实际规范化这个非规范化表中的数据。

如上所述,我们的第一步是将人员数据标准化。我们首先为人员数据和其余地址数据创建必要的表:

CREATE TABLE IF NOT EXISTS normalisation.person (
    Person_id BIGINT AUTO_INCREMENT PRIMARY KEY,
    FirstName VARCHAR(255),
    MiddleName VARCHAR(255),
    LastName VARCHAR(255),
    Address_id BIGINT
) ENGINE = INNODB;

CREATE TABLE IF NOT EXISTS normalisation.addressStateZip (
    Address_id BIGINT AUTO_INCREMENT PRIMARY KEY,
    Address1 VARCHAR(50),
    Address2 VARCHAR(50),
    City VARCHAR(50),
    State VARCHAR(50),
    Zip VARCHAR(50),
    UNIQUE KEY addressStateZip (Address1, Address2, City, State, Zip)
) ENGINE = INNODB;

然后,我们通过获取所有地址类型数据来填充这两个表,仅获取唯一的行,然后将其放入 addressStateZip 临时表中:

Normalise people data job layout

上述作业的第二部分然后将 addressStateZip 数据与初始非规范化表进行比较,并收集连接以获取 person 表的 Address_id:

tMap configuration to get Address_id for person table

剩下的步骤现在非常相似。

接下来,我们为地址和邮政编码数据创建状态表和另一个临时表:

CREATE TABLE IF NOT EXISTS normalisation.state (
    State_id BIGINT AUTO_INCREMENT PRIMARY KEY,
    State VARCHAR(255),
    UNIQUE KEY state (State)
) ENGINE = INNODB;

CREATE TABLE IF NOT EXISTS normalisation.addressZip (
    Address_id BIGINT AUTO_INCREMENT PRIMARY KEY,
    Address1 VARCHAR(50),
    Address2 VARCHAR(50),
    City VARCHAR(50),
    State_id BIGINT,
    Zip VARCHAR(50),
    UNIQUE KEY addressStateZip (Address1, Address2, City, State_id, Zip)
) ENGINE = INNODB;

现在我们需要从 addressStateZip 表中获取唯一的状态并将其放入状态表中:

Normalise state data job layout

第二部分与之前一样,然后使用 State_id 而不是实际状态将数据创建到 addressZip 临时表中:

tMap configuration to get State_id for addressZip table

现在,我们终于可以创建邮政编码表,然后将其链接到正确的地址表:

CREATE TABLE IF NOT EXISTS normalisation.zip (
    Zip_id BIGINT AUTO_INCREMENT PRIMARY KEY,
    ZIP VARCHAR(255),
    UNIQUE KEY zip (ZIP)
) ENGINE = INNODB;

CREATE TABLE IF NOT EXISTS normalisation.address (
    Address_id BIGINT AUTO_INCREMENT PRIMARY KEY,
    Address1 VARCHAR(50),
    Address2 VARCHAR(50),
    City VARCHAR(50),
    State_id BIGINT,
    Zip_id BIGINT,
    UNIQUE KEY addressStateZip (Address1, Address2, City, State_id, Zip_id)
) ENGINE = INNODB;

使用与状态数据相同的方法,我们获取所有唯一的邮政编码并将它们放入邮政编码表中:

Normalise zip data job layout

和以前一样,我们现在可以将 Zip_id 放入新的完成的地址表中:

tMap configuration to get Zip_id for address table

为了检查,我们现在可以运行以下查询来获取所有数据:

SELECT p.FirstName, p.MiddleName, p.LastName, a.Address1, a.Address2, a.City, s.State, z.Zip
FROM normalisation.person AS p
INNER JOIN normalisation.address AS a ON a.Address_id = p.Address_id
INNER JOIN normalisation.state AS s ON s.State_id = a.State_id
INNER JOIN normalisation.zip AS z ON z.Zip_id = a.Zip_id;

既然您已经完成了设置,您可能还想向表中添加一些外键约束:

ALTER TABLE normalisation.person
ADD FOREIGN KEY (Address_id) REFERENCES address(Address_id);

ALTER TABLE normalisation.address
ADD FOREIGN KEY (State_id) REFERENCES state(State_id),
ADD FOREIGN KEY (Zip_id) REFERENCES zip(Zip_id);

关于etl - Talend 将平面文件规范化为关系数据库表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27391606/

相关文章:

sql - 无法将变量值传递给 ssis 中的存储过程

java - 在将 CSV 字段导入数据库之前修改它们

MySQL:规范化内容类型、类别和子类别

database-design - 如何理解第五范式?

MySQL - 行到列

postgresql - Postgres 的 ETL 选项

sql-server - 如何刷新 OLE DB 目标编辑器表选择

java - Talend Open Studio 将作业导出为 Web 服务并在不带 URL 参数的情况下调用它

java - 从 Windows 机器加载 Hive 表(Load data local inpath)

mysql - 考试重新标准化歌曲(singerID、singerName、songID、歌曲名称、歌曲长度、歌曲流派)