いま知るべきオブジェクトデータベースの世界(2)

受発注システムで体験するオブジェクトデータベース

インターシステムズジャパン株式会社
テクニカルコンサルティング部 教育サービス部部長
佐藤 比呂志
2009/9/18

問い合わせ処理の実装

 次に、オブジェクト指向プログラミングで、なんらかの問い合わせ処理を行うケースについて考えましょう。

 こんな処理が現実に必要かどうかはさておき、以下では注文明細の項目に指定した色のものが含まれる注文を検索し、リストして、その中から注文を選んで、注文書を表示するというプログラミングです(後半は、前例とほぼ同じ処理になります)。

OrderPrint2() {
        Read "色 ?",color
    Set query = ##class(%ResultSet).%New("%DynamicQuery:SQL")
    Do query.Prepare("SELECT DISTINCT TheOrder->ID AS OID FROM Sample.OrderItem WHERE TheProductStock->Color = ?")
    Do query.Execute(color)
    Write "Order ID",!	
    While (query.Next()) {
      Set oid=query.Get("OID")
      Write oid,!
    }
    Read "enter OID ",oid
        Set ord=##class(Sample.Order).%OpenId(oid)
        Write !,?30,"注文明細書",!
        Write "注文番号 ",oid,!
        Write "〒",ord.Customer1.Address1.Zip," ",ord.Customer1.Address1.Pref,ord.Customer1.Address1.City,ord.Customer1.Address1.Street,!
    Write "電話番号 ",ord.Customer1.Telno,!
    Write ord.Customer1.Name," 御中",!
    Write !
    Write "商品名",?30,"サイズ",?45,"    色",?55,"数量",?60,"金額",!	
    Write "--------------------------------------------------------------------",!
    For i = 1 : 1: ord.Items.Count() {
            Write ord.Items.GetAt(i).TheProductStock.TheProductSize.TheProduct.Name
            Write ?30,$J(ord.Items.GetAt(i).TheProductStock.TheProductSize.SSize,4)
            Write ?45,$J(ord.Items.GetAt(i).TheProductStock.Color,6)
            Write ?55,$J(ord.Items.GetAt(i).Quantity,4)
            Write ?60,$J($FN(ord.Items.GetAt(i).TheProductStock.TheProductSize.Price*ord.Items.GetAt(i).Quantity,","),8)
        Write !

    }
    Write "--------------------------------------------------------------------",!
    Write "合計",?60,$J($FN(ord.Total,","),8)
} 

 Cachéでは、問い合わせ処理には、SQLを使います。ただし、SQLといってもオブジェクト指向風の味付けがしてあります。

 SQLを記述するときに、オブジェクト参照と同様にカスケード参照ができるとなにかと便利です。その最大のメリットは、結合のための追加の条件記述が必要ない点です。

 Caché SQLのカスケード参照には、->を使います。SQLでは、.は別の意味ですでに使われていますので、この用途には使用できません。上の処理で使われている以下のSQL文の意味を考えてみましょう。

SELECT DISTINCT TheOrder->ID AS OID FROM Sample.OrderItem WHERE TheProductStock->Color = ?

 これは、Sample.OrderItemテーブルのTheProductStockカラムが指すProductStockテーブルの色が、パラメータで指定された値に一致するSample.OrderItemレコードを取得して(複数行)そのレコード単位にTheOrderカラムが指すOrderテーブルのIDを取得する、という処理になります。これを一般的なSQLで表現すると、3つのテーブル(Sample.OrderItem、Sample.ProductStock、Sample.Order)の結合処理になります。

 Caché SQLの->は、暗黙結合と呼ばれます。暗黙結合を使うとSQL文が非常にすっきり記述できると感じませんか?

 ここでも示したように、現実のアプリケーションでは、なんらかの問い合わせ処理で処理対象を絞って、その個々の処理対象に対して処理を進めていくというスタイルが一般的だと思われます。従って、オブジェクト指向データベースプログラミングといっても、オブジェクト参照だけでことが足りるわけではなく、なんらかの問い合わせ言語の処理が含まれます。

 Cachéの場合は、この問い合わせ用にフルセットのSQLを用意し、かつオブジェクト指向風な拡張がなされています。

メモリにロードされるタイミングは

 以上で、オブジェクト指向データベースを使ったアプリケーション構築のエッセンスの説明は終わりです。ここで、高度な性能を要求されるデータベースアプリケーション構築の経験のある方は、1つの疑問を持たれることと思います。

 今回の例題は、1つの注文を表示する処理ですので、容量的にはたかがしれていますが、もし大量の関連オブジェクトがひも付いているオブジェクトを処理する必要がある場合に、それらの関連オブジェクトは、どのタイミングでプログラム上のメモリにロードされるのでしょうか?

 これは、RDBを使って、オブジェクトモデルを構築する場合にも考慮すべき問題です。1つの実装パターンとしては、最初に必要なSQLを連続で発行して、あらかじめ後の処理に必要なオブジェクトモデルを事前に構築する方法が考えられます。

 この方法は、今回の例題を処理するには、何の問題もない方法ですが、仮に注文明細が1万を超えるように大量に存在する場合には、処理時間、メモリ使用量など問題になってきます。その場合は、1行づつフェッチしながら処理を進めていく必要があり、その部分の処理が煩雑になるでしょう。

 再度例題プログラムを眺めてみましょう。一見すると、データベースからオブジェクトの実体を取得している可能性のある処理は、OpenId()メソッドしかないように見えます。

 それでは、このOpenId()を実行した時点で注文オブジェクトとそれに関連するそのほかのオブジェクトの実体すべてをプログラムのメモリ上にロードするのでしょうか? この例題の場合には、それでも問題ないでしょうが、関連するオブジェクトが100万存在すると、おそらくメモリが足らなくなるでしょう。同時に処理時間もかかることでしょう。

 実は、関連オブジェクトに関しては、参照が発生した時点にロードされます。具体的にはカスケード参照されたオブジェクトがメモリに展開されていないことを検知した場合に、データベースからそのインスタンスをメモリにロードします。この一連の操作をCachéではスィズリングと呼びます。スィズル(Swizzle)とは、飲み物をかき混ぜるスティックという意味があるそうです。徐々に浸透していくという意味で使われているのだと思います。O/Rマッパーなどでも同等の機能があり、それはレイジーロード(怠け者のロード)と呼ぶのが一般的なようです。Cachéはこのスィズリングにより、大量関連オブジェクトのロードの問題を回避しています。

難しいことはデータベースで。だからプログラマは集中できる

 オブジェクトデータベースを使うことにより、裏方の難しいことはデータベースシステムが面倒を見てくれて、開発者はビジネスロジックに集中できます。この裏方の難しい仕事のでき具合は、アプリケーションの性能に大きく影響します。

 O/Rマッパー使うとオブジェクトデータベースと同様にプログラマーの仕事は、大分軽減されます。しかし、内部でSQLに逐一変換しなければならないという制約上、性能の向上には限界があります。これが、O/Rマッパーがなかなか普及しない1つの要因ではないかと思います。

筆 者 略 歴
インターシステムズジャパン株式会社
佐藤 比呂志(さとうひろし)

大手SI、先進的企業のIT部門にて、大規模開発プロジェクトに従事後、米国大手ソフトウェア会社にてソフトウェア製品開発マネージャを務めた後、1996年より仕様策定、共同開発などでCachéの日本対応に尽力。

その後、同製品のプロダクトマネージャに。2001年インターシステムズコーポレーション入社。2003年インターシステムズジャパン株式会社設立と同時に転籍。テクニカルコンサルティング部・教育サービス部部長。

現在、ITmedia オルタナティブ・ブログにて「隠れた財産」を執筆中。

>>> インターシステムズジャパン株式会社

前のページへ 3/3

Index
受発注システムで体験するオブジェクトデータベース

Page 1
データモデルの構築
Cacheでのプログラミング実例

Page 2
プログラマによって差が出ない記法
RDBではどう表現されるか
→ Page 3
問い合わせ処理の実装
メモリにロードされるタイミングは
難しいことはデータベースで。だからプログラマは集中できる

いま知るべきオブジェクトデータベースの世界


Database Expert フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Database Expert 記事ランキング

本日月間