2つのデータベースには共通項があり、紐づけたいということがあります。
例えば、片方は個人情報を含む名簿、片方は匿名化された利用履歴のようなもの。利用履歴には年齢や性別が載っていない場合、それらの属性での分析ができません。
2つのデータベースに共通鍵を設けておき、紐づけることで1つのデータベースとして取り扱うことができます。
OriginalとAddition
早速、つくってみました。
元となるデータベースをOriginal、付加情報として用いるデータベースをAdditionとして試作しています。
/*/ データテーブル格納 /*/
DataSet dataSet_Coupling = new DataSet();
dataSet_Coupling.Tables.Add(dataTable_Addition.Copy());
dataSet_Coupling.Tables[dataSet_Coupling.Tables.Count - 1].TableName = "dt_Addition";
int_Col_Addition_Count = dataSet_Coupling.Tables["dt_Addition"].Columns.Count;
dataSet_Coupling.Tables.Add(dataTable_Original.Copy());
dataSet_Coupling.Tables[dataSet_Coupling.Tables.Count - 1].TableName = "dt_Original";
int_Col_Original_Count = dataSet_Coupling.Tables["dt_Original"].Columns.Count;
/*/ カラム設定(重複回避) /*/
for (int_CoNum = 0; int_CoNum < int_Col_Addition_Count; int_CoNum ++)
{
dataSet_Coupling.Tables["dt_Original"].Columns.Add("追加_" + dataSet_Coupling.Tables["dt_Addition"].Columns[CoNum].ColumnName);
}
/*/ データ接続用DataRow /*/
DataRow[] dtRow_Child_Row;
dataSet_Coupling.Relations.Add(
"DB_RelationName",
dataSet_Coupling.Tables["dt_Original"].Columns["ID_Y"],
dataSet_Coupling.Tables["dt_Addition"].Columns["ID_Z"],
false);
/*/ 受け側(Original)のレコードの分だけループ /*/
foreach (DataRow dataRow_Row in dataSet_Coupling.Tables["dt_Original"].Rows)
{
dtRow_Child_Row = dataRow_Row.GetChildRows("DB_RelationName");
if (dtRow_Child_Row.Length != 0)
{
for (int_CoNum = 0; int_CoNum < int_Col_Addition_Count; int_Col_Number++)
{
dataSet_Coupling.Tables["dt_Original"].Rows[int_Record_Count][int_CoNum + int_Col_Original_Count] = dtRow_Child_Row[0][int_CoNum ].ToString();
}
}
int_Record_Count++;
}
dataSet_Coupling.WriteXmlSchema(str_XSD_File_Name);
dataSet_Coupling.WriteXml(str_XML_File_Name);
1つのデータベースに2つのテーブル
今回は『dataSet_Coupling』というデータセット(DataSet)に、2つのテーブルを設けました。
1つ目は『0』(ゼロ)、2つ目は『1』(ワン)ですが、それだとわかりづらいので『dt_Addition』と『dt_Original』というテーブル名(TableName)を付けています。
追加する側の dt_Addition を先に設定した理由は、2つが同じテーブル名(TableName)であった場合、受け側のテーブル名を温存したいためです。2つ同じテーブル名は許容されないので、先に追加する側を登録してテーブル名を dt_Addition に変更しています。すなわち、 dt_Original というテーブル名にせず、元のままにしても大丈夫です。
テーブルに追加(Add)の指示をして、コピー(Copy)でデータテーブルを丸ごとコピーしています。
2回のコピーで、2つのデータテーブルがデータセット内に存在することになります。
/*/ データテーブル格納 /*/
DataSet dataSet_Coupling = new DataSet();
dataSet_Coupling.Tables.Add(dataTable_Addition.Copy());
dataSet_Coupling.Tables[dataSet_Coupling.Tables.Count - 1].TableName = "dt_Addition";
int_Col_Addition_Count = dataSet_Coupling.Tables["dt_Addition"].Columns.Count;
dataSet_Coupling.Tables.Add(dataTable_Original.Copy());
dataSet_Coupling.Tables[dataSet_Coupling.Tables.Count - 1].TableName = "dt_Addition";
int_Col_Original_Count = dataSet_Coupling.Tables["dt_Original"].Columns.Count;
カラム名
受け側のデータテーブル『dt_Original』には、まだ元となるデータテーブルのデータがコピーされただけです。
ここに、新しいカラムを追加します。
今回は、追加する側のテーブルからすべて引き継ぐコードを作ったので、 for 文でカラムを追加しています。
受け側のカラム名と重複しないように、頭に『追加_』という文字を付けています。これは『SUB』でも『補』でも何でも良いです。
/*/ カラム設定(重複回避) /*/
for (int_CoNum = 0; int_CoNum < int_Col_Addition_Count; int_CoNum ++)
{
dataSet_Coupling.Tables["dt_Original"].Columns.Add("追加_" + dataSet_Coupling.Tables["dt_Addition"].Columns[CoNum].ColumnName);
}
1つずつ紐づけ
データセットのリレーション(Relations)を使って2つのデータベースを紐づけます。
リレーション名は何でも良いです。今回は『DB_RelationName』にしています。
第2項目は受け側のデータベースです。
第3項目は追加する側のデータベースです。
それぞれ、どのカラムの内容で紐づけるか決めます。今回は『ID_Y』と『ID_Z』が共通鍵になっていることにして、この2つをキーにしています。
主キー、プライマリキー、ユニークキー、リレーショナルキー、なんと呼ぶのが良いかわかりません。
/*/ データ接続用DataRow /*/
DataRow[] dtRow_Child_Row;
dataSet_Coupling.Relations.Add(
"DB_RelationName",
dataSet_Coupling.Tables["dt_Original"].Columns["ID_Y"],
dataSet_Coupling.Tables["dt_Addition"].Columns["ID_Z"],
false);
データ追記
受け側のデータテーブルには、カラムは新設されましたがデータが格納されていません。
受け側のデータテーブルを1レコードずつ、最初から最後まで foreach を使って追記していきます。
追加する側の dt_Addition の項目が空欄である場合、あるいは紐づくレコードが存在しない場合は、受け側のデータテーブルには空欄(Null)が記録されます。
/*/ 受け側(Original)のレコードの分だけループ /*/
foreach (DataRow dataRow_Row in dataSet_Coupling.Tables["dt_Original"].Rows)
{
dtRow_Child_Row = dataRow_Row.GetChildRows("DB_RelationName");
if (dtRow_Child_Row.Length != 0)
{
for (int_CoNum = 0; int_CoNum < int_Col_Addition_Count; int_Col_Number++)
{
dataSet_Coupling.Tables["dt_Original"].Rows[int_Record_Count][int_CoNum + int_Col_Original_Count] = dtRow_Child_Row[0][int_CoNum ].ToString();
}
}
int_Record_Count++;
}
dataSet_Coupling.WriteXmlSchema(str_XSD_File_Name);
dataSet_Coupling.WriteXml(str_XML_File_Name);
おわりに
今回は、2つのでデータテーブルを結合させる処理を実装しました。
以前、植え込み型の医療機器の管理システムを構築した際に使った技術ですが、すっかり忘れていました。
受け側のデータテーブルは保留し、追加する側のデータテーブルを次々と用意していけば、一度の処理でいくつものデータを追加していくことも可能です。以前は患者テーブル、病院テーブル、保険テーブルなどいろいろなものを持ったデータベースでしたので、もっと複雑でした。
システムの終了時に、データテーブルを抹消するコードを入れておけば、個人情報流出も防げるかなと思います。
最後までお読みいただき、ありがとうございました。
関連記事
- [C#備忘録]2つのDataTableを紐づける | AmpiTa Project
- [C#備忘録]DataGridViewをXMLファイルへ反映 | AmpiTa Project
- [C#備忘録]XML・DataTable条件絞込・該当レコード指示 | AmpiTa Project
- [C#備忘録]複数のNumericUpDownから最適値を探す | AmpiTa Project
- [備忘録]PHP7.4⇒8.0 アップ … ウェブページのデータベース接続構文を変更 | AmpiTa Project
- [C#備忘録]高DPIへの対応(目標未達) | AmpiTa Project
- [C#備忘録]HTMLファイルでレポート | AmpiTa Project
- [C#備忘録]画像ファイル出力 | AmpiTa Project
- [C#備忘録]Excelファイルをインポート | AmpiTa Project
- [C#備忘録]XMLファイルで集計 | AmpiTa Project