Pentaho Kettleを使用して、参照整合性を維持しながら単一のテーブルから複数のテーブルをロードするにはどうすればよいですか?
質問
ファイル/テーブルで定義されている関係を維持して、MySQL上の複数のテーブルに100,000以上のレコードを含む単一のファイルからデータをロードする必要があります。関係はすでに一致しています。ソリューションは、MySQLの最新バージョンで動作する必要があり、INNODBエンジンを使用する必要があります。 Myisamは外国の鍵をサポートしていません。
私はPentaho Data Integration(別名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
ノート: 単一のテーブルデータベースは完全に正規化されています(単一のテーブルがそうかもしれません) - たとえば、「ジョン・スミス」の場合、ジョン・スミスは1人しかいません。意味参照整合性の競合につながる重複はありません。
MyOffice
データベーススキーマには次の表があります。
Employee (nId, name)
Office (nId, number)
JobTitle (nId, titleName)
Employee2Office (nEmpID, nOfficeId)
Employee2JobTitle (nEmpId, nJobTitleID)
したがって、この場合。テーブルは次のように見えます。
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
データベースとテーブルを作成するための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;
選択した回答に応じた私のメモ:
準備:
- (a)サンプルデータを使用し、変更してCSVを作成します
<TAB>
コンマが区切られています。 - (b)MySQL DDLサンプルを使用してMySQLをインストールし、サンプルデータベースを作成します
- (c)ケトルをインストールします(Javaベースで、Javaを実行するものはすべて実行されます)
- (d)KTRファイルをダウンロードします
段階的にデータフロー: (私のノート)
- KettleでKTRファイルを開き、「CSVファイル入力」をダブルクリックし、作成したCSVファイルを参照しました。デリミッターはすでにコンマに設定する必要があります。次に、[大丈夫]をクリックします。
- 「従業員の挿入」をダブルクリックし、DBコネクタを選択し、次の方向に従ってください 新しいデータベース接続の作成
解決
サンプルをまとめました 変換(右クリックしてリンクの保存を選択) あなたが提供したものに基づいて。私が少し不確かだと感じる唯一のステップは、最後のテーブル入力です。私は基本的に、結合データをテーブルに書き込み、特定の関係がすでに存在する場合に失敗させます。
ノート:
このソリューションは、「すべてのアプローチには検証の一部を含める必要があり、挿入が失敗した場合、または参照整合性を維持できない場合のロールバック戦略を含める必要があります。」基準は、おそらく失敗することはありません。あなたが本当に複雑なものをセットアップしたいなら、私たちはできることですが、これは間違いなくあなたがこれらの変換を使ってあなたを動かすべきです。
ステップごとにデータフロー
1. 私たちはあなたのファイルを読むことから始めます。私の場合、私はそれをCSVに変換しましたが、タブも問題ありません。
2. 次に、従業員の名前を従業員のテーブルに挿入します combination lookup/update
. 。挿入後、employee_idをDataStreamに追加します。 id
を削除します EmployeeName
データストリームから。
3. ここでは、選択した値ステップを使用して、 id
employee_idからフィールド
4. 従業員と同じようにジョブタイトルを挿入し、タイトルIDをDataStreamに追加して削除します JobLevelHistory
データストリームから。
5. title_idへのタイトルIDの簡単な名前の変更(ステップ3を参照)
6. オフィスを挿入し、IDを取得し、ストリームからOfficeHistoryを削除します。
7. Office IDのOffice_idへの簡単な名前の変更(ステップ3を参照)
8. 最後のステップから値を値の2つのストリームにコピーする employee_id,office_id
と employee_id,title_id
それぞれ。
9. テーブル挿入を使用して、結合データを挿入します。重複している可能性があり、PKの制約がいくつかの行に失敗する可能性があるため、挿入エラーを無視するように選択しました。