【IRIS/Cache】他DBのグローバルが見たい!書きたい!

本記事は、他DBに存在しているグローバルの保存・参照方法について紹介します。

※この記事は下記の方向けになります。
  • 他のDBにあるグローバルを操作(保存・参照)したい方
  • 数点ある方法の内、どれを採用すればよいか悩んでいる方

はじめに

「他のデータベース(DB)のグローバルを参照したい」と考えた事はありませんか?

別のデータベースに保存されているグローバルの値を取得($get等)する必要がある場合、どのような方法を使用すればよいでしょうか。

一般的には、グローバルマッピングやネームスペースの切り替えが用いられると思います。
また、ネームスペースの切り替えには、明示的な方法と暗示的な方法の2種類があります。

本記事では、下記3種の方法について、メリット・デメリットを検証しつつ、解説していきたいと思います。

他DBのグローバル参照方法
  • グローバルマッピング
  • ネームスペース切り替え(明示的・暗黙的)
  • 拡張グローバル参照

グローバルマッピング

システムの構築時等で、良くお世話になる方法ですね。

システム構築を検討する際、DB毎にグローバルを振り分けているかと思います。

例)DB振り分けのサンプル

  • マスタ用のDB
  • メインデータ(有効なデータ)のDB
  • 履歴用のDB 等々

システムの規模等によりますが、DB毎にグローバルがまとまっているので、管理が非常に楽になります。

設定方法

コマンドでも設定可能ですが、管理ポータルから行うのが楽です。

※コマンドでの設定方法

[システム管理] > [構成] > [ネームスペース] に進みます。

設定対象ネームスペースの「グローバルマッピング」をクリックします。

「新規」ボタンをクリックし、マッピング先のDB名・グローバル名(サブスクリプトは任意)を入力し、「OK」ボタンをクリックします。

その後、「変更を保存」ボタンをクリックして設定が完了となります。
 ※「変更を保存」は忘れないでクリックしましょう。

データの確認

管理ポータルでグローバルを確認すると、「Location」列にグローバル・デフォルトDBとは異なるDB名(ディレクトリ)が表示されます。
 ※下記例では、「D:\irisDB\test64」のDBを読み込んでいる

メリット・デメリット

【メリット】

・ロジックを組む上で、どのDBにデータが格納されるかを意識する必要がない。
・他DBのグローバルを参照する上では、最も効率が良い。

【デメリット】

・マッピングを行ったグローバル名と同名のグローバルが他のDBから参照できなくなる。

DB名=Cのグローバルマッピングを「Sample」として設定した場合、DB名=A, Cに存在するグローバル「^Sample」は、読み書きが不可となる。

ネームスペース切り替え

ネームスペースの切り替えは、「明示的」と「暗黙的」の2種類の方法があります。
各々の特徴を解説します。

明示的

ネームスペースを指定して切り替えます。
ごく一般的な方法ですね。

zn "ネームスペース名"

// 使用例
zn "test64"
zw ^Sample
^Sample("test")="他データベースです!"

暗黙的

暗黙的なネームスペース切り替えは、DBのディレクトリを指定します。

下記は、暗黙的なネームスペースの切り替えコマンドになります。

// 現在のネームスペース
zn "^^." // 例:「^^d:\irisdb\sample-data\>」と表示される

// -------------------------------------------------
// 指定のDBに切り替える方法
//zn "^^[DBのディレクトリ]"

// -------------------------------------------------
// 参考例
zn "^^D:\IRISDB\TEST64"
 
^^d:\irisdb\test64\>zw ^Sample
^Sample("test")="他データベースです!"

メリット・デメリット

【メリット】

・一度ネームスペースを切り替えてしまえば、DBを気にせずデータの読み書きが行えるようになる。

【デメリット】

・ネームスペースを切り替えるため、何か不具合発生や戻し損ねた時は事故が発生してしまう危険がある。

ネームスペースの切り替えについて、詳細に記載した記事になります。
是非参照してください。

拡張グローバル参照

ブラケット構文

キャレット(^)とグローバル名の間に「[“xxx”]」を挟むことで、他DBのグローバルを操作する事が可能になります。

この「xxx」にネームスペースを入力すれば、明示的なネームスペース参照となり、DBのディレクトリを入力すれば暗黙的なネームスペース参照となります。

明示的なネームスペース参照のサンプル

w ^["ネームスペース名"]グローバル名

// 例 「TEST64」ネームスペース
zw ^["TEST64"]Sample
^["TEST64"]Sample("test")="他データベースです!"

暗黙的なネームスペース参照のサンプル
ディレクトリの前にキャレット(^)を2つ入力する

w ^["^^ディレクトリ名"]グローバル名

// 例 「TEST64」ディレクトリ
zw ^["^^D:\IRISDB\TEST64"]Sample
^["^^D:\IRISDB\TEST64"]Sample("test")="他データベースです!"

環境構文

キャレット(^)とグローバル名の間に「|“xxx”|」を挟むことで、他DBのグローバルを操作する事が可能になります。

ブラケット構文は「[]」を使用しましたが、環境構文では「||」に変わります。

明示的なネームスペース参照のサンプル

w ^|"ネームスペース名"|グローバル名

// 例 「TEST64」ネームスペース
zw ^|"TEST64"|Sample
^|"TEST64"|Sample("test")="他データベースです!"

暗黙的なネームスペース参照のサンプル
ディレクトリの前にキャレット(^)を2つ入力する

w ^|"^^ディレクトリ名"|グローバル名

// 例 「TEST64」ディレクトリ
zw ^|"^^D:\IRISDB\TEST64"|Sample
^|"^^D:\IRISDB\TEST64"|Sample("test")="他データベースです!"

メリット・デメリット

【メリット】

・どのDBからでもグローバルの操作が行える
・メンテナンス用として操作するのであれば、特別な設定も不要なので優秀と言える

【デメリット】

・間接的に参照するため、処理が遅くなる

速度検証

メリット・デメリットを記載しましたが、実際にどの程度処理に影響するのかを確認しないと始まりません。

書き込みと読み込みの速度を検証してみたいと思います。
 ※グローバルキャッシュを消すため、実行毎にIRISを再起動させる。

検証する項目
  • グローバル・デフォルトデータベース
  • グローバルマッピング
  • ネームスペース切り替え(明示的)
  • ネームスペース切り替え(暗黙的)
  • 拡張グローバル参照(ブラケット構文(明示的))
  • 拡張グローバル参照(ブラケット構文(暗黙的))
  • 拡張グローバル参照(環境構文(明示的))
  • 拡張グローバル参照(環境構文(暗黙的))

書き込みの速度検証

下記サンプルを使用して、1,000万件のデータの書き込み速度を検証したいと思います。

ClassMethod MakeGbl(cnt As %Integer = 10000000) As %Float
{
	s ns = "NEWDB" // 検証対象のネームスペース
	, path = "^^D:\IRISDB\NEWDB" // ↑のディレクトリ
	
	s start = $zh
	
	//new $namespace
	//s $namespace = ns
	//s $namespace = path
	
	f pos=1:1:cnt s ^Sample(pos)="他DBへのアクセス方法についての速度調査"
	//f pos=1:1:cnt s ^[ns]Sample(pos)="他DBへのアクセス方法についての速度調査"
	//f pos=1:1:cnt s ^[path]Sample(pos)="他DBへのアクセス方法についての速度調査"
	//f pos=1:1:cnt s ^|ns|Sample(pos)="他DBへのアクセス方法についての速度調査"
	//f pos=1:1:cnt s ^|path|Sample(pos)="他DBへのアクセス方法についての速度調査"
	s time = $zh - start
	q time
}

実行結果は下記になります。

結果を見る限りこの程度であれば、各項目間で顕著な差が見られないようです。
各項目の差は誤差程度だと思います。

読み込み速度検証

下記サンプルを使用して、1,000万件のデータの読み込み速度を検証したいと思います。

ClassMethod ReadGbl(cnt As %Integer = 10000000) As %Float
{
	s ns = "NEWDB" // 検証対象のネームスペース
	, path = "^^D:\IRISDB\NEWDB" // ↑のディレクトリ

	s start = $zh

	//new $namespace
	//s $namespace = ns
	//s $namespace = path
	
	s pos=""
	f { s pos=$o(^Sample(pos),1,val) q:pos=""  }
	//f { s pos=$o(^[ns]Sample(pos),1,val) q:pos=""  }
	//f { s pos=$o(^[path]Sample(pos),1,val) q:pos=""  }
	//f { s pos=$o(^|ns|Sample(pos),1,val) q:pos=""  }
	//f { s pos=$o(^|path|Sample(pos),1,val) q:pos=""  }
	s time = $zh - start
	q time
}

実行結果は下記になります。

読み込みに関しては、「拡張グローバル参照」と「それ以外の項目」で、若干差が感じられる結果となりました。

「拡張グローバル参照」と「それ以外の項目」内の平均速度を見ると、グループ内では誤差程度の差しか発生していないのが分かります。

また、両グループの処理速度差は、あまり出ていないのがビックリです。
もっと差が開くと思っていました。

とは言え、業務で拡張グローバル参照を使用するのであれば、良く検証する必要があると思います。

おわりに

いかがだったでしょうか。
この記事では、他DBのグローバルを参照する方法について解説しました。

基本的には、業務で使用するのであれば「グローバルマッピング」「ネームスペース切り替え」で対応し、保守で使用する場合には「拡張グローバル参照」での運用で良いかと思います。

ただ、「拡張グローバル参照」については、滅多に使用する機会が無いため、割と記述方法を忘れがちになると思います。

そんな時は、この記事を見返していただけると幸いです。