キューブの同期を使用する方法
ここでは、キューブの同期機能を使用して、キューブを最新の状態に保つ方法について説明します。
キューブの同期が機能する方法
ここでは、キューブの同期が機能する方法について簡単に説明します。内部的に、この機能には 2 つのグローバル、^OBJ.DSTIME と ^DeepSee.Update を使用しています。
最初に、キューブの初期ビルドを実行する必要があります。
InterSystems IRIS® データ・プラットフォームが、キューブによって使用されるソース・テーブル内で変更を検出すると、エントリを ^OBJ.DSTIME グローバルに追加します。これらのエントリには、追加、変更、または削除が行われた ID を示す目的があります。
キューブを同期する場合 (このページで後述する %SynchronizeCube() を使用)、最初に InterSystems IRIS は ^OBJ.DSTIME グローバルを読み取り、それを使用して ^DeepSee.Update グローバルを更新します。ID が ^DeepSee.Update グローバルに追加された後、InterSystems IRIS は ^OBJ.DSTIME グローバルから同じ ID を削除します。(以前のバージョンでは、キューブの同期機能は 1 つのグローバルのみ使用していました。新しいシステムでは競合条件を回避します。)
次に、InterSystems IRIS は ^DeepSee.Update グローバルを使用して、キューブのファクト・テーブルとディメンジョン・テーブルを更新します。これにより、キューブが最新状態になります。
以下の図は、このプロセス・フローを示しています。
サブセクションでは、以下の詳細について説明します。
キューブの同期が可能なとき
キューブ同期機能は、以下のすべての項目に当てはまるシナリオで使用できます。
-
キューブのベース・クラスが永続クラスである (ただし、リンク・テーブルではないこと)。
-
変更されたレコードがそのクラス内のレコードである。
キューブの同期が不可能なとき
キューブ同期機能は、以下のシナリオでは使用できません。
-
キューブのベース・クラスがデータ・コネクタである。("データ・コネクタの定義" を参照してください。)
-
キューブのベース・クラスがリンク・テーブルである。("リンク・テーブル・ウィザード" を参照してください。)
-
変更されたレコードがキューブで使用されるベース・クラスのエクステント内にない。つまり、変更されたレコードが別のテーブルに属している。
これらのシナリオでは、キューブ同期機能によって変更を検出できず、"キューブの手動更新" の説明に従って、手動でキューブを更新する必要があります。
また、キューブ同期は年齢ディメンジョン (つまり、[ディメンジョン・タイプ] が [年齢] であるディメンジョン) に影響しません。
ミラーリング環境におけるキューブの同期
Business Intelligence をミラー・サーバで使用する場合、^OBJ.DSTIME グローバルはアプリケーション・データの一部であり、ミラーリングする必要があることに注意してください (例えば、異なるデータベースにマップされている場合は、そのデータベースをミラーリングする必要があります)。^DeepSee.Update グローバルは Business Intelligence コードによって生成されます。そのため、キューブ定義とデータが含まれるデータベースにのみ存在します。
ミラー・サーバでは、^OBJ.DSTIME グローバルと ^DeepSee.Update グローバルを格納しているデータベースを読み取り/書き込みに設定しておく必要があります。これらのグローバルは、同じデータベースに両方とも格納することもできますが、上記の図では個別のデータベースに格納しています。
ミラー・サーバでの Business Intelligence の使用に関する詳細は、"推奨アーキテクチャ" を参照してください。
キューブの同期のグローバルの構造
ここでは、キューブの同期のグローバルの構造について説明します。この情報は、キューブの同期を使用するのに必要ではありません。しかし、これらのグローバルを他の目的で使用する場合を考慮して提供されています。
^OBJ.DSTIME
DSINTERVAL が設定されているかどうかによって、^OBJ.DSTIME グローバルには別の形式があります。
DSINTERVAL が設定されていない場合、このグローバルには以下のようなノードがあります。
ノード | 値 |
---|---|
^OBJ.DSTIME(class、increment、ID)。ここで、class はソース・クラスの完全なパッケージおよびクラス名です。increment は 0 です。ID は、所定のクラスの新規レコード、変更されたレコード、または削除されたレコードの ID です。 | 以下の値のいずれかです。
|
%SetDSTimeIndex() メソッドを使用することで、対応するレコードをソース・クラスから削除することなく、ファクト・テーブルからファクトを手動で削除できることに注意してください。
DSINTERVAL が設定されている場合、このグローバルには以下のようなノードがあります。
ノード | 値 |
---|---|
^OBJ.DSTIME(class、timestamp、ID)。ここで、class と ID は他のシナリオの場合と同じです。timestamp は、1840 年 12 月 31 日午前零時以降の秒数です | 他のシナリオの場合と同じ |
キューブの同期または再ビルドが行われるときに、不要なエントリは ^OBJ.DSTIME グローバルから削除されます。
^DeepSee.Update
^DeepSee.Update グローバルには以下のようなノードがあります。
ノード | 値 |
---|---|
^DeepSee.Update | 使用する次の increment の値を示す整数 |
^DeepSee.Update(class、increment、ID)。ここで、class はソース・クラスの完全なパッケージおよびクラス名です。increment は 0 または正の整数です。ID は、所定のクラスの新規レコード、変更されたレコード、または削除されたレコードの ID です。キューブが同期されるたびに、システムは次に大きい increment 整数値を使用して、このグローバルにノードを更新します。例を参照してください。 | ^OBJ.DSTIME グローバルの場合と同じ |
^DeepSee.Update("cubes"、cube、"dstime")。ここで、cube はキューブの論理名です | 特定のキューブに対する変更を記録するために、このグローバルでノードを作成するときに使用する increment の次の値を示す整数。 |
^DeepSee.Update("cubes"、cube、"lastDataUpdate")。ここで、cube はキューブの論理名です | このキューブが最後に同期化されたときの日付と時間 ($H 形式)。 |
次に例を示します。
^DeepSee.Update=3
^DeepSee.Update("DeepSee.Study.Patient",0,1)=0
^DeepSee.Update("DeepSee.Study.Patient",0,2)=0
^DeepSee.Update("DeepSee.Study.Patient",0,100)=0
^DeepSee.Update("DeepSee.Study.Patient",1,1)=2
^DeepSee.Update("DeepSee.Study.Patient",1,120)=0
^DeepSee.Update("DeepSee.Study.Patient",2,42)=0
^DeepSee.Update("DeepSee.Study.Patient",2,43)=0
^DeepSee.Update("DeepSee.Study.Patient",2,50)=0
^DeepSee.Update("DeepSee.Study.Patient",2,57)=0
^DeepSee.Update("cubes","PATIENTS","dstime")=3
^DeepSee.Update("cubes","PATIENTS","lastDataUpdate")="64211,63222.68"
^DeepSee.Update("DeepSee.Study.Patient",0) の下のノードは、最初の変更セットを表し、^DeepSee.Update("DeepSee.Study.Patient",1 の下のノードは、2 番目の変更セットを表します。その後も同様に続きます。
InterSystems IRIS が ^DeepSee.Update グローバルからノードを自動的に削除することはありません。このグローバルの削除の詳細は、"DSTIME の削除" を参照してください。
キューブ同期の有効化
キューブを同期する前に、そのキューブのキューブ同期機能を有効化する必要があります。そのためには、以下の操作を実行します。
-
キューブ同期がシナリオで可能になっていることを確認します。このページで前述の "キューブの同期が可能なとき" を参照してください。
-
以下のように、DSTIME パラメータをそのキューブで使用されるベース・クラスに追加します。
Parameter DSTIME = "value";
DSTIME パラメータは、3 つの文字列のいずれかをその value として受け入れます。"AUTO" が指定されている場合、^OBJ.DSTIME グローバルは、レコードの変更ごとに更新を受け取ります。これは、%SynchronizeCube() メソッド (以下のセクションで説明) を呼び出すと、すべての変更が ^DeepSee.Update に転写され、対応するキューブと同期されることを意味します。DSTIME が "MANUAL" に設定されている場合、そのベース・クラスのレコードへの変更の自動ジャーナリングは無効になります。値 "CONDITIONAL" を使用すると常に、クラスの DSCONDITION パラメータを指定することによって、^OBJ.DSTIME が同期させる変更を記録する条件を動的に指定できます (以下を参照)。
-
DSTIME パラメータを "CONDITIONAL" に設定する場合、以下のパラメータをベース・クラスに追加します。
Parameter DSCONDITION = expression
指定された expression が TRUE と評価された場合、^OBJ.DSTIME は、同期のために、指定のクラスのレコードの更新を受け取ります。DSCONDITION は実行時に実行される式ですが、通常のようにOpens in a new tab、そのパラメータ・タイプを COSEXPRESSION として明示的に指定する必要はありません。
-
必要に応じてベース・クラスに以下のパラメータも追加できます。
Parameter DSINTERVAL = 5;
このパラメータは主に、エントリが ^OBJ.DSTIME グローバルに保存される方法に影響を与えます。"キューブの同期のグローバルの構造" を参照してください。^OBJ.DSTIME グローバルの形式は、キューブの同期メカニズムの動作に影響を与えません。
-
ベース・クラスと、そのベース・クラスが使用するすべてのキューブ・クラスをリコンパイルします。
-
それらのキューブをリビルドします。
^OBJ.DSTIME グローバルのクリア
このセクションでは、^OBJ.DSTIME グローバルをクリアする方法について説明します。場合によっては、^OBJ.DSTIME グローバルを定期的にクリアできます。例えば、Business Intelligence でキューブを使用していない場合、^OBJ.DSTIME グローバルをクリアして領域を解放できます。
タスク・マネージャで、^OBJ.DSTIME グローバルを定期的にクリアするタスクを設定できます。そのためには、以下のように、OnTask() メソッドで新規タスクを作成します。
Method OnTask() As %Status
{
set classname=$ORDER(^OBJ.DSTIME(""))
while (classname="") {
//check to see if this classname is contained in ^DeepSee.Cubes("classes")
set test=$DATA(^DeepSee.Cubes("classes",classname))
if (test'=1) {
kill ^OBJ.DSTIME(classname)
}
set classname=$ORDER(^OBJ.DSTIME(classname))
}
q $$$OK
}
このタスクは、^OBJ.DSTIME エントリが Business Intelligence のキューブによって使用されていない場合、それらのエントリをクリアします。[タスクスケジューラウィザード] を使用して、必要な頻度で実行するようにタスクをスケジュールします。
%SynchronizeCube() の使用
プログラムでキューブを同期するには (つまり、キューブ・マネージャを使用しない)、%DeepSee.UtilsOpens in a new tab クラスの %SynchronizeCube() メソッドを呼び出します (これには以下のシグニチャがあります)。
classmethod %SynchronizeCube(pCubeName As %String, pVerbose As %Boolean = 1) as %Status
指定されているキューブ (pCubeName) に対して、このメソッドは前回の呼び出しより後に行われたすべての変更をソース・データから検出して適用します。
pVerbose が True の場合、メソッドはステータス情報をコンソールに書き込みます。このメソッドのその他の引数については、クラスリファレンスOpens in a new tabを参照してください。
%SynchronizeCube() は、以下の方法のいずれかで呼び出すことができます。
-
メソッドをベース・クラスのデータを変更するコードの一部から呼び出します。
これは、Patients サンプル内で使用されている方法です。
-
定期的に、%SynchronizeCube() を繰り返しのタスクとして呼び出します。
%SynchronizeCube() によって、No changes detected というメッセージが表示された場合、これは、キューブを再構築したことがないことを示しています。
DSTIME の削除
これまでの経緯と便宜上の理由から、DSTIME の削除という表現は、^OBJ.DSTIME グローバルから古いエンティティを削除することを表します。このグローバルは、かなり大きくなることがあるため、定期的に削除する必要があります。
特定のキューブの DSTIME を削除するには、以下の操作を実行します。
-
REST API の /Data/GetDSTIME を呼び出します。"GET /Data/GetDSTIME" を参照してください。引数として、キューブのソース・クラスのフルネームを渡します。
この REST 呼び出しは、特定のサーバ上でそのソース・クラスに対して処理された最後の ^OBJ.DSTIME タイムスタンプを返します。非同期ミラー設定の場合、この REST サービスから取得したタイムスタンプは、プライマリ・プロダクション・サーバで安全に削除できる直近のタイムスタンプになります。
-
返されたタイムスタンプを引数として使用して、%DeepSee.UtilsOpens in a new tab の %PurgeUpdateBuffer() メソッドを呼び出すことで、リモート・サーバで処理されたタイムスタンプ未満の ^OBJ.DSTIME を削除します。このメソッドの既定の動作では、ローカルの ^OBJ.DSTIME の最上位ノードが増分されます。これにより、Business Intelligence サーバに伝播される新しい同期ポイントが削除のたびに提供されるようになります。
その他のオプション
このセクションでは、その他の高度なオプションまたはあまり一般的でないオプションについて説明します。
DSTIME=MANUAL を使用する方法
システムで ^OBJ.DSTIME グローバルを自動的に更新する代わりに、ユーザが選択した時間にこのグローバルを更新することができます。そのためには、以下の操作を実行します。
-
DSTIME を、"AUTO" ではなく "MANUAL" に指定します。
-
その後、アプリケーション内で、%DeepSee.UtilsOpens in a new tab クラスのオブジェクトを追加、変更、または削除するたびに、または ^OBJ.DSTIME グローバルを更新するときに、このクラスの %SetDSTimeIndex() メソッドを呼び出します。
このメソッドには、以下のシグニチャがあります。
ClassMethod %SetDSTimeIndex(pClassName As %String, pObjectId As %String, pAction As %Integer, pInterval As %Integer = 0)
以下は、この指定の説明です。
-
pClassName は、追加、変更、または削除したオブジェクトの完全なパッケージとクラスの名前です。
-
pObjectId は、そのオブジェクトのオブジェクト ID です。
-
pAction は、オブジェクトを更新した場合は 0、オブジェクトを追加した場合は 1、オブジェクトを削除したか、オブジェクトを削除することなく対応するファクトをファクト・テーブルから削除したい場合は 2 です。pAction の値は、生成される ^OBJ.DSTIME ノードの値として使用されます。対応するレコードがソース・クラスに存在しない場合、または pAction に値 2 が指定されている場合、ファクトは同期中にキューブから削除されることに注意してください。
-
pInterval はオプションの整数です。これを正の整数として指定すると、^OBJ.DSTIME グローバルおよび ^DeepSee.Update グローバルでタイムスタンプ・サブスクリプトが使用されます。"キューブ同期の有効化" の DSINTERVAL パラメータの説明を参照してください。
-
次に、指定のキューブを更新する場合、前述のように %DeepSee.UtilsOpens in a new tab クラスの %SynchronizeCube() メソッドを呼び出します。
例
Patients サンプルには、データを変更し、同期または手動更新を必要に応じて使用するユーティリティ・メソッドが含まれています。それらのメソッドを試すには、このサンプルで提供されているダッシュボードを使用できます。
-
サンプルをインストールしたネームスペースでユーザ・ポータルを開きます。
-
Real Time Updates ダッシュボードをクリックします。
-
左上の領域にあるボタンをクリックします。これらのボタンのそれぞれが、このサンプル内のデータをランダムに変更するメソッドを実行する KPI アクションを実行します。アクションは、バックグラウンド・プロセスを開始する JOB を使用してメソッドを起動します。
-
[患者を追加] では、患者が追加されます。
このアクションは、患者を追加するたびに %SynchronizeCube() を呼び出しながら 100 人の患者を追加するメソッドを呼び出します。
-
[患者グループの変更] では、一部の患者に対する患者グループの割り当てが変更されます。
このアクションは、一定の割合の患者について患者グループの割り当てをランダムに変更し、その変更のたびに %SynchronizeCube() メソッドを呼び出すメソッドを呼び出します。
-
[一部の患者を削除] では、一部の患者が削除されます。
このアクションは、患者を削除するたびに %SynchronizeCube() を呼び出しながら 1% の患者を削除するメソッドを呼び出します。
-
[好きな色を変更] では、一部の患者の好みの色が変更されます。
このアクションは、一定の割合の患者の好みの色をランダムに変更するメソッドを呼び出します。この場合、変更されたデータは BI_Study.PatientDetails テーブルに格納されますが、このテーブルは Patients キューブのベース・テーブルではありません。したがって、%SynchronizeCube() の代わりに %ProcessFact() を使用する必要があります。
このコード・ブロックは、データの変更によって影響を受けるすべての患者を返す SQL クエリを実行します。その後、それらの患者を繰り返し処理し、患者ごとに Patients キューブを更新します。
-
[受診を追加] では、一部の患者の受診が追加されます。
このアクションは、BI.Study.PatientDetails の場合と同様のロジックを含むメソッドを呼び出します (前の項目を参照してください)。
-
[医者グループの変更] では、一部の一次診療医で医者グループの割り当てが変更されます。
このアクションは、BI.Study.PatientDetails の場合と同様のロジックを含むメソッドを呼び出します。
-
これらのメソッドは、ログの詳細を ^DeepSee.Study.Log グローバルに書き込みます。以下はその例です。
^DeepSee.Study.Log(1)="13 May 2011 05:29:37PM Adding patients..."
^DeepSee.Study.Log(2)="13 May 2011 05:29:38PM Current patient count is 10200"