Hitachi

ノンストップデータベース HiRDB Version 10 解説


3.5.2 サブタイプと継承

〈この項の構成〉

(1) サブタイプ(subtyping)

従業員のうち,特に営業部員の情報について管理することを考えます。「営業部員」は,「従業員」という抽象的な概念に対して,より具体的で特殊な(特化した)概念であると考えられます。営業部員についての情報は,従業員が持つ情報に加えて,営業活動についての情報があると考えられます。そこで,「営業部員」は,「従業員」であることに加えて,属性「担当顧客」や操作「顧客総数」などを持つことにします。

営業部員について,実世界の情報と抽象データ型による概念モデルを次の図に示します。

図3‒40 実世界の情報と抽象データ型による概念モデル(営業部員の場合)

[図データ]

HiRDBでは,あるデータ型を基にその型を特化した抽象データ型をサブタイプとして定義できます。

例えば,定義系SQL文 CREATE TYPEのサブタイプ句を使用して,t_従業員を基に,t_営業部員を次に示すように定義できます。

  CREATE TYPE t_営業部員 UNDER t_従業員(
      担当顧客  VARCHAR(3000),
 
      FUNCTION 顧客総数 ( …   )
      RETURNS INTEGER
        …
      )

なお,t_従業員のような,サブタイプに対する上位の抽象データ型をスーパタイプといいます。

(2) 代替可能性(substitutability)

「営業部員」は「従業員」でもあります。HiRDBでは,サブタイプで特化した(下位の)抽象データ型の値をその上位の抽象データ型の値としても扱えます。例えば,社員表では次に示すSQLで,t_営業部員の値をt_従業員の値として列の値にできます。

注意事項

t_営業部員の値もt_従業員の値と同様に扱えるようにするために,このSQLを実行する前に,ALTER ROUTINEを実行し,SQLオブジェクトを再作成しておく必要があります。

INSERT INTO 社員表 VALUES ( 51, t_営業部員(:name AS CHAR(16),…) )

このように,下位の抽象データ型の値が上位の抽象データ型の値としてみなされることを代替可能性(substitutability)といいます。

(3) 継承(inheritance)

「営業部員」は「従業員」でもあるので,「従業員」と同様に「氏名」や「性別」の属性を持ち,「勤続年数」算出の操作が適用できると考えられます。

図「実世界の情報と抽象データ型による概念モデル(営業部員の場合)」のように,HiRDBではサブタイプで特化した(下位の)抽象データ型にその上位の抽象データ型に定義された属性とルーチンが引き継がれます。

このように,下位の抽象データ型が,上位の抽象データ型の属性及びルーチンを引き継ぐことを継承(inheritance)といいます。

例えば,継承によってt_営業部員の値に対して属性「氏名」と操作「勤続年数」が利用できるようになるため,t_営業部員の値を列値に挿入した社員表について,次に示すSQLのように,先に示したSQLを変更することなく実行できます。

注意事項

このSQLを実行する前に,ALTER ROUTINEを実行し,SQLオブジェクトを再作成しておく必要があります。

SELECT 社員番号, 従業員..氏名, 勤続年数(従業員)
  FROM  社員表
  WHERE 勤続年数(従業員) >= 10

サブタイプと継承で,次に示す効果が期待できます。

(4) 多重定義(override)

「従業員」に対して「報酬」を査定する操作を考えます。報酬の査定は,例えば,「基本給」,「勤続年数」,「勤続年数に基づく報酬率」によって設定された情報を基に,作業状況を評価して査定することが考えられます。

一方で,継承によって「従業員」に定義される操作「報酬」は自動的に「営業部員」に引き継がれます。しかし,特に営業部員については,一般的な従業員の査定方法とは異なり,営業活動で注文を受けた「顧客総数」などを基に,営業部員特有の査定をすることが考えられます。

実世界での従業員,営業部員についての操作を次の図に示します。

図3‒41 実世界での従業員,営業部員についての操作

[図データ]

例えば,「従業員報酬」や「営業部員報酬」のような,それぞれの抽象データ型ごとに異なる名称のルーチンを定義するとします。その場合,代替可能性で「従業員」の値と「営業部員」の値を統一的に扱えるのにもかかわらず,それぞれの値の型によって呼び出すルーチンの名称を変更しなければならなくなります。そのため,アプリケーションでは次に示す操作系SQLを実行できなくなります。

×  SELECT   社員番号, 従業員..氏名, 従業員報酬(従業員)
    FROM     社員表

…「営業部員」に対して,営業部員特有の報酬査定を実行できません。

×  SELECT   社員番号, 従業員..氏名, 営業部員報酬(従業員)
    FROM     社員表

…「営業部員」でない「従業員」に対しても,営業部員特有の報酬査定を実行してしまいます。

HiRDBでは,上位の抽象データ型で定義されたルーチンと同じ名前のルーチンを下位の抽象データ型を定義するときに上書きして定義できます。このように上書きして定義することを多重定義(override)といいます。

多重定義を次の図に示します。

図3‒42 多重定義

[図データ]

また,多重定義されたルーチンの実行では,その引数となる値の型に応じて,HiRDBが自動的に適切な定義に従って実行します。多重定義によって,呼び出すルーチンの名称を値の型によって変更する必要がなくなります。そのため,次に示す操作系SQLを実行できます。

注意事項

このSQLを実行する前に,ALTER ROUTINEを実行し,SQLオブジェクトを再作成しておく必要があります。

SELECT   社員番号, 従業員..氏名, 報酬(従業員)
    FROM     社員表

…多重定義したルーチン「報酬」によって,実行時にそれぞれの引数の値に応じたルーチンが実行されます。

このSQLの実行では,t_従業員型の値に対しては,t_従業員型に定義されたルーチン「報酬」が実行され,t_営業部員型の値に対しては,t_営業部員型に定義されたルーチン「報酬」が実行されます。

なお,上記のSQLのように,アプリケーションではルーチンが多重定義されているかどうかを意識しないでルーチンを呼び出せます。また,多重定義によってルーチンを追加した場合でも,アプリケーションを変更しないでSQLを実行できるようになります。