InterSystems IRISで階層型データを使用するためのPHPモジュール
PHP はその公開当初から、多くのライブラリや市場に出回っているほぼすべてのデータベースとの統合をサポートしていることでよく知られています(またそのことで批判を受けてもいます)。 にもかかわらず、何らかの不可解な理由により、グローバル変数については階層型データベースをサポートしませんでした。
グローバル変数は階層情報を格納するための構造です。 Key-Value型データベースにある程度似ていますが、キーを次のようにマルチレベルにできるという点で異なっています。
Set ^inn("1234567890", "city") = "Moscow"
Set ^inn("1234567890", "city", "street") = "Req Square"
Set ^inn("1234567890", "city", "street", "house") = 1
Set ^inn("1234567890", "year") = 1970
Set ^inn("1234567890", "name", "first") = "Vladimir"
Set ^inn("1234567890", "name", "last") = "Ivanov"この例では、マルチレベルの情報は、ビルトインのObjectScript言語を使用して、グローバル変数の**^innに保存されています。 グローバル変数^inn**は、ハードドライブに保存されています(これは、最初の「^」記号で示されています)。
PHP からグローバル変数を操作するには、PHP モジュールによって追加される新しい関数が必要となります。これについて、以下で説明します。
グローバル変数は、階層を操作するための多数の関数をサポートしています。固定レベルと縦型のトラバーサルツリーでツリー全体と個別のノードの削除、コピー、および貼り付けを行えます。 また、質の高いデータベースと同様に、ACID トランザクションもサポートされています。 これらは次の2つの理由により、非常に迅速に行われます(一般的なPCで、1秒間に105~106の挿入が行われます)。
- グローバル変数は SQL に比べると、より低レベルの抽象化である。
- ベースは数十年もの間グローバルスコープで稼働しており、この間に洗練され、コードは完全に最適化されてきた。
グローバル変数について詳しくは、「グローバル変数: データ管理の魔法の剣」という連載記事をご覧ください。
この業界では、グローバル変数は主に、医療、個人データ、銀行などの構造化されていないまばらな情報のストレージシステムで使用されています。
私はPHPを気に入っており、開発作業でも使用しているため、グローバル変数を使って色々と試してみたいと思いました。 IRISとCaché用のPHPモジュールは存在しなかったため、 InterSystemsに問い合わせ、作成するよう依頼しました。 InterSystemsは教育助成金の一環として開発を後援してくれたおかげで、私の院生とともにモジュールを作成することになりました。
一般的に、InterSystems IRISはマルチモデルDBMSであるため、ODBCを通じてSQLを使ってPHPから操作することができますが、私が興味を持っていたのはグローバルであったため、それに使用できるコネクタは存在しなかったのです。
それはさておき、このモジュールはPHP 7.xで利用できます(7.0~7.2でテストしました)。 現在、同じホストにインストールされているInterSystems IRISとCachéでのみ動作します。
OpenExchangeのModuleページ(InterSystems IRISとCachéの開発者向けのプロジェクトとアドオンのディレクトリ)。
開発者同士で関連する体験をシェアできるDISCUSSセクションが設けられています。
こちらからダウンロードしてください。
https://github.com/intersystems-community/php_ext_iris コマンドラインからリポジトリをダウンロードする場合:
git clone https://github.com/intersystems-community/php_ext_iris
モジュールの関数:
| PHP関数 |
| データの操作 |
|---|
| iris_set($node, value) |
| iris_get($node) |
| iris_zkill($node) |
| iris_kill($node) |
| iris_order($node) |
| iris_order_rev($node) |
| iris_query($CmdLine) |
| サービス関数 |
| iris_set_dir($FullPath) |
| iris_exec($CmdLine) |
| iris_connect($login, $pass) |
| iris_quit() |
| iris_errno() |
| iris_error() |
特にDCや使用したい方のために、Caché用php-moduleがセットアップされた仮想マシンを実行しています。
単なる好奇心で、私のPC(AMD FX-9370@4700Mhz 32GB、LVM、SATA SSD)のdockerコンテナーで新しい値をデータベースに挿入する速度をチェックするプリミティブテストを2つ実行しました。
- 100万個の新しいノードをグローバルに挿入するのに、1.81秒掛かりました(1秒あたり552Kの挿入)。
- 同じグローバルの値を1,000,000回更新するのに、1.98秒掛かりました(1秒当たり505Kの更新)。 興味深かったのは、挿入が更新よりも早く行われたということです。 どうやらこれは、迅速な挿入を目的としたデータベースの初期最適化の結果のようです。
明らかに、これらのテストは原始的であり、コンテナー内で実行されるため、100%の正確性または有用性があるとは考えられません。 PCIe SSDにディスクシステムを備えたより強力なハードウェアでは、1秒あたり数千万の挿入を達成可能です。
作成中の機能とその状況
- トランザクションを操作するための便利な関数を追加できます(iris_execで使用できます)。
- グローバル構造全体を返す関数は実装されていません。PHPからグローバルをトラバースする関数についても同様です。
- PHP配列をサブツリーとして保存する関数は実装されていません。
- ローカルデータベース変数へのアクセスは実装されていません。 iris_setを使用した方が良いですが、iris_execのみを使用してください。
- 逆順での縦型グローバルトラバースは実装されていません。
- メソッドを使ったオブジェクト経由のデータベースアクセス(現在の関数に類似)は実装されていません。
現在のモジュールはまだ本番対応とは言えません。高負荷やメモリリークについてのテストは行われていません。 ただし、必要だという方がいらっしゃれば、いつでもご連絡ください(Sergey Kamenev宛: sukamenev@gmail.com)。
結論
グローバルは特定のデータタイプ(医療、個人データなど)に強力で高速な機能を提供しているにも関わらず、長い間、PHPの世界とグローバル変数での階層型データベースの世界では、実質的に重なることがありませんでした。
このモジュールをきっかけに、PHPプログラマーがグローバル変数を試すようになり、ObjectScriptプログラマーがPHPでウェブインターフェースを簡単に開発できるようになることを願っています。
追伸 最後までお読みいただき、ありがとうございました!