トピック

概論ページの先頭へ

このガイドラインでは、データベースのリバース エンジニアリングを行い、その結果のデータ モデル テーブルを設計モデル設計クラスにマップする際のステップを説明します。データベース設計者がこのプロセスを用いることにより、データベース変更の開発作業を、発展的な開発サイクルの一部として行えます。データベース設計者は、プロジェクトの開発ライフサイクルを通して、リバース エンジニアリング プロセスを管理する必要があります。多くの場合、リバース エンジニアリング プロセスは、プロジェクトのライフサイクル初期に行われ、データ設計の変更を反復的に行うことにより、以降のデータベースのリバース エンジニアリングの手間を省きます。

データベースのリバース エンジニアリングのプロセスと、結果のデータ モデル要素を設計モデル要素に変換するプロセスの主なステップは、次のとおりです。

  • データベース内の永続データの物理レイアウトを表すテーブルを含む物理データ モデルを作成する。このステップは、リレーショナル データベース管理システム (RDBMS) の付属ツールや、最新のビジュアル モデリング ツールにより、自動的に行えます。
  • 物理データ モデルのテーブルを、設計モデルの設計クラスに変換する。このステップは、自動化ツールによる初期変換と、変換後の手動調整により行えます。
  • 設計モデルのクラス間の関連を定義する
  • 対応するデータ モデル要素に行ったアクションを基に、設計モデルのクラスに操作を定義する
  • 設計モデルのクラスをサブシステムにグループ化し、必要に応じてパッケージ化する

RDBMS データベースまたは DDL スクリプトのリバース エンジニアリングによるデータ モデルの生成ページの先頭へ

データベースまたはデータ定義言語 (DDL) スクリプトのリバース エンジニアリング プロセスでは、一般的に、モデル要素のセット (テーブル、ビュー、ストアド プロシージャなど) からデータ モデルのシステム定義パッケージを生成します。データベース設計者は、データベースの複雑さに応じて、リバース エンジニアリングを行ったモデル要素を、論理的関連を持つ一連のテーブルを含む問題領域パッケージに分ける必要のある場合があります。

データ モデル要素から設計モデルへの変換 ページの先頭へ

次の手順により、データ モデルのモデル要素から設計クラスを作成できます。クラス モデル内のデータベースの構造を複写することは、比較的、単純明快です。以下に示す手順に、データ モデル要素を設計モデル要素変換するためのアルゴリズムを示します。

次の表は、設計モデル要素とデータ モデル要素間の一般的なマッピングをまとめたものです。

データ モデル要素

対応する設計モデル要素

テーブル クラス
属性

非依存リレーションシップ

関連

共通テーブル

 

関連クラス

多対多関連

限定子付き関連

依存リレーションシップ

コンポジット集約

基数

 

多重度

 
列挙句による制約のチェック <<ENUM>> クラス
スキーマ パッケージ

データ モデルの要素には、設計モデルに直接対応しないものがあります。これらの要素には、テーブルスペースとデータベースそのものがあり、これはデータベースの物理的なストレージ特性をモデル化し、コンポーネントとして表されます。この他にも、データベース ビューは、「仮想」テーブルであり、設計モデル内では意味を持ちません。また、テーブルの主キーの索引とデータベース トリガ ファンクションは、データベースの最適化に使用されるもので、データベースとデータ モデルの環境においてのみ意味を持つものです。

テーブルからクラスへの変換 ページの先頭へ

変換するテーブルごとに、テーブルを表すクラスを作成します。各列に対応して、クラスの属性を設定し、適切なデータ タイプを指定します。属性のデータ タイプとそれに対応する列のデータ タイプを、可能な限り合わせるようにします。

データベース テーブル「顧客」があり、下の表に示す列で構成されているとします。

列名 データ タイプ
顧客 ID 番号
名前 可変長文字列
番地 可変長文字列
市町村 可変長文字列
都道府県 可変長文字列
郵便番号 可変長文字列
可変長文字列

顧客」テーブルの定義

ここから始めて、下の図に示す構造をしたクラス「顧客」を作成します。

「顧客」クラスの定義

当初の「顧客」クラス

この当初の「顧客」クラスにおいて、「顧客 」テーブル内の各列に対応する属性があります。各属性の可視性は public となっています。元のテーブル内のどの列も照会可能であるからです。

属性の左側の "+" アイコンは、属性が「public」であることを示しています。デフォルトの設定では、RDBMS テーブルから導出される属性はすべて「public」です。その理由は、RDBMS では一般に、任意の列を制約なく照会できるからです。

「埋め込み」または暗黙的なクラスの把握 ページの先頭へ

テーブルとクラスの直接的な対応づけの結果として得られるクラスの中には、別のクラスへ分離できる属性が含まれていることがよくあります。ある属性が、導出された多くのクラスの中に含まれる場合、特にその可能性が高いです。そのように「同じ属性が繰り返し現れる」原因は、性能上の理由からテーブルが非正規化されているか、データ モデルが単純化されすぎている可能性があります。その場合、対応するクラスを 2 つ以上に分割して、正規化されたテーブルのビューを反映するようにします。

上の「顧客」クラスを定義した後に「住所 」クラスを定義するとします。この「住所」クラスには住所に関するすべての情報が含まれています (システムには住所に関してほかにも情報があるものと想定します)。すると、これらのクラスの関連は下の図のようになります。

改定後の「顧客」クラスと抽出された「住所」クラス

この 2 つのクラスの間の関連は集約です。顧客の住所は顧客の一部であると考えられるからです。

外部キー関係の取り扱い ページの先頭へ

テーブル内の各外部キー関係について、関連するクラス間の関連を設定し、外部キーである列に対応する属性をクラスから削除します。外部キーである列が当初属性として表されていた場合、それをクラスから削除します。

下に示すような「注文」テーブルがあるとします。

列名 データ タイプ
番号 番号
顧客 ID 可変長文字列

注文」テーブルの内容

上に示した「注文」テーブルにおいて、「顧客 ID」列は外部キーによる参照を表しています。つまり、この列の内容は「注文」に関連する「顧客」の主キーの値です。このことを設計モデルでは下の図に示すように表します。

設計モデルにおける外部キー関係の表現

外部キーは 2 つのクラス「注文」と「品目」の間の関連を表します。

多対多関係の取り扱い ページの先頭へ

RDBMS データ モデルでは多対多の関係をいわゆる結合テーブルまたは関連テーブルで表します。そのような中間テーブルを使用することによって、2 つの別々のテーブルの主キーを組み合わせて格納して、多対多の関係を表現できます。結合テーブルが必要となる理由は、外部キーによる参照では 1 つの値しか指定できないことです。1 行がほかのテーブル内の多数の行に関係する場合、それらの組み合わせを指定するために結合テーブルが必要となります。

製品」は任意の複数の「供給業者」から供給され、「供給業者」は任意の数の「製品」を供給できるとします。「製品」と「供給業者」の 2 つのテーブルの内容は下のように定義されています。

製品テーブル     供給業者テーブル    
列名 データ タイプ   列名 データ タイプ  
製品 ID 数字   供給業者 ID 数字  
名前 可変長文字列   名前 可変長文字列  
説明 可変長文字列   番地 可変長文字列  
価格 数字   市町村 可変長文字列  
      都道府県 可変長文字列  
      郵便番号 可変長文字列  
      可変長文字列  

「製品」テーブルと「供給業者」テーブルの定義

どの製品がどの供給業者によって提供されているかを知るためには、「製品 - 供給業者」テーブルによって 2 つのテーブルをリンクする必要があります。その内容を下に示します。

製品 - 供給業者テーブル
列名 データ タイプ
製品 ID 数字
供給業者 ID 数字

製品 - 供給業者テーブルの定義

この結合テーブルには製品と供給業者の主キーが含まれていて、両者を組み合わせる働きをしています。このテーブル内の 1 行は、ある具体的な供給業者が提供する、ある具体的な製品を示します。供給業者 ID 列が、ある具体的な供給業者に合致するすべての行によって、その供給業者から提供されるすべての製品が表されます。

設計モデルにおいては、この中間テーブルは冗長です。なぜなら、オブジェクト モデルでは多対多の関連を直接表せるからです。「供給業者」クラスと「製品」クラス、それらの関係を図 8 に示します。また、「供給業者」クラスから抽 出された「住所」クラスも併せて示します。

「製品」クラスと「供給業者」クラスの表現

汎化の導入 ページの先頭へ

内容が類似したテーブルを見かけることがよくあります。データ モデルには汎化の概念がありません。したがって、2 つ以上のテーブルが内容的に似ていることを表す方法がありません。ときには、内容が類似している原因は、性能を上げるために非正規化されていることにあります。前に示した、抽出して別のテーブルにすることのできた「暗黙的」な「住所」テーブルはその例です。別のケースとして、大部分の基本的な特徴が同じであるテーブルが 2 つあるとします。その場合、汎化した親クラスを抽出し、2 つ以上のサブクラスを残すことができます。汎化が可能な事例を知るために、相違点よりも類似点の方が多い、いくつかのテーブル内の繰り返し列を見てみましょう。

下に示す「ソフトウェア製品」と「ハードウェア製品」の 2 つのテーブルがあります。

ソフトウェア製品テーブル     ハードウェア製品テーブル  
列名 データ タイプ   列名 データ タイプ
製品 ID 数字   製品 ID 数字
名前 可変長文字列   名前 可変長文字列
説明 可変長文字列   説明 可変長文字列
価格 数字   価格 数字
バージョン 数字   アセンブリ 数字

「ソフトウェア製品」テーブルと「ハードウェア製品」テーブル

青い色で示した列は同じであることに注目してください。この 2 つのテーブルの定義はほとんどが共通であり、少ししか違いません。その中から共通の部分を「製品」クラスとして抽出し、「製品」クラスのサブクラスとして「ソフトウェア製品 」と「ハードウェア製品」を残すことができます。その様子を下の図に示します。

「ソフトウェア製品」クラスと「ハードウェア製品」クラスから「製品」クラスへの汎化

すべてのクラス定義を一緒にまとめて、受注処理システムの統合クラス図を下に示します (主要なクラスのみ)。

受注処理システムの統合クラス図

設計モデル内への RDBMS の振る舞いの複写 ページの先頭へ

振る舞いを複写することはもっと困難です。なぜなら、リレーショナルデータベースは通常はオブジェクト指向ではなく、オブジェクト モデル内のクラス操作と類似する点がないように見えるからです。下記の手順を踏むと、上で挙げたクラスの振る舞いを再構築する助けとなります。

  1. 各属性を取得、設定する操作を用意します。オブジェクトの属性の値を設定、変更、照会する手段が必要です。オブジェクトの属性にアクセスする唯一の方法はクラスに用意されている操作を通じて処理することです。したがって、そのような操作をクラスに定義する必要があります。属性の値を設定する操作を用意する際に、関連する列に作用する妥当性検証制約があるならば、それを組み込むようにします。妥当性検証制約がない場合、単に属性を取得 設定できるようにするだけでもかまいません。そのためには、上のダイアグラム (属性名の左にアイコンが示されているもの) のように、それらの属性の可視性を「public」にします。
  2. 関連するテーブルに作用する各ストアド プロシージャごとのクラスに対する操作を作成します。ストアド プロシージャは DBMS の内部で起動される実行可能なサブルーチンです。そのロジックを設計モデルに翻訳する必要があります。ストアドプロシージャがただ 1 つのクラスに対してのみ作用する場合、ストアド プロシージャと同じパラメータ、戻りタイプを持つクラスに対する操作を用意します。その操作におけるストアド プロシージャの振る舞いを文書化します。その際、その操作がストアド プロシージャによって実装されることをメソッド記述に注記するようにします。
  3. クラス間の関連を管理する操作を用意します。2 つのクラスの間に関連がある場合、関連を設定し、管理し、解除する手段が必要です。オブジェクト間の関連はオブジェクト参照を通じて管理されます。したがって、「注文」と「明細品目」との間に関連を設定する (つまり、「明細品目」を「注文」に追加する) ためには、「注文」に対する操作を起動して、「明細品目」を引数 (たとえば、Order.add(aLineItem)) として渡します。また、関連を解除する手段 (たとえば、Order.remove(aLineItem)) と関連を更新する手段 (たとえば、Order.change(aLineItem,aNewLineItem)) も必要です。
  4. オブジェクトを削除できるようにします。使用する言語でオブジェクトの明示的な削除をサポートする場合、参照の一貫性をチェックする振る舞いをそのクラスのデストラクタに追加します。連鎖的削除の場合のような参照の一貫性制約がデータベースに存在する場合、その振る舞いを適切なクラスに複写する必要があります。たとえば、「注文」を削除するときはそれに関連するすべての「明細品目」も削除しなければならないという制約がデータベースに定義されている可能性があります。使用する言語でガーベッジ コレクションをサポートしている場合、あるオブジェクトがガーベッジ コレクションされたときに、それに関連するすべての行が削除される仕組みを用意します。それは (難しそうですが) 思った以上に難しいので、注意してください。なぜなら、ガーベッジ コレクションされるオブジェクトを参照しているデータベース クライアントが存在しないことを確認する仕組みを実装する必要があるからです。それは実行環境 / 仮想マシンのガーベッジ コレクション機能に頼るだけでは十分ではありません。それは単純に 1 クライアントの目で世界を見ているだけだからです。
  5. 照会によって暗示される振る舞いを処理します。テーブルにアクセスする Select ステートメントを調べて、情報がどのように検索され操作されるかを明らかにします。Select ステートメントによって直接返される各列に関して、関連する属性の「public」プロパティを「true」に設定します。その他のすべての属性のプロパティは「private」とすべきです。Select ステートメント内で計算される各列について、その計算を行って値を返す操作を関連するクラスに組み込みます。Select ステートメントを検討するときは、ビュー定義に組み込まれている Select ステートメントも含めます。

設計モデルの要素の構成 ページの先頭へ

テーブルからクラスへの変換により作成された設計クラスは、アプリケーションの全体的なアーキテクチャ構成をもとに、必要に応じて適当な設計パッケージ / 設計サブシステムに構成する必要があります。アプリケーション アーキテクチャの概要については、「概念: レイヤリング」と「概念: ソフトウェア アーキテクチャ」を参照してください。



Rational Unified Process   2003.06.15