第3章:リレーショナルデータベースへのマッピング:エンタープライズアプリケーションアーキテクチャパターン(PoEAA)、メモ
第3章:リレーショナルデータベースへのマッピング
序論
一章で紹介されていた、プレゼンテーションレイヤ、ドメインレイヤ、データソースレイヤのうち、データソースレイヤに関する話題。
つまり、リレーショナルデータベースの扱いのことである。
3.1 アーキテクチャに関するパターン
ドメインロジックとSQLアクセスを分離し、異なるクラスに配置することが賢明
クラスを組織化する適切な方法は、データベースのテーブル構造に基づいて、データベーステーブルごとに一つのクラスを持つようにすること
ドメインモデルの場合、ドメインオブジェクトがデータベースからの読み込みと保存を行い、アクティブレコードになる
つまり、アクティブレコードでは、ドメインオブジェクトがデータベーステーブルとの通信方法を知っている
ドメインモデルが豊富になり、複雑になると、テーブルとドメインクラスとの一対一の組み合わせは失敗し始める
これに対する優れた方法は、ドメインオブジェクトとデータベーステーブルとのとのマッピングを間接参照のレイヤに任せること
データマッパーは、ドメインオブジェクトとデータベーステーブルを分離するもの
ドメインモデルの場合は、o\rマッピングツールを真剣に考えるべき
3.2 振る舞いに関する問題
振る舞いに関する問題は、さまざまなオブジェクトをデータベースに読み込ませる方法と保存する方法
オブジェクトを読み込んで修正する際は、使用するデータベースが一貫性のある状態でなければならない
つまり、並行性の問題がある
この問題を解決するためのパターンは、ユニットオブワーク
ユニットオブワークとは、データベースマッピングのコントローラとしての役割を果たすオブジェクトとして考える
一意マッピングの目的は、正確な一意性を維持する事
3.3 データの読み込み
データの読み込み時にはパフォーマンスの問題が発生する
1度に複数の行の取得を行うこと。特に、複数の行を取得するために、同じテーブルに繰り返しクエリを発行してはいけない
例えば、主キーで特定可能な50人を取得しなければならない場合、200人を取得するクエリを構築し、そこから必要な50人を分離させるためのロジックを実行すれば良い。50個の個別クエリよりも、不必要な行を戻す1つのクエリを使用する方が適切
データベースでは、多くの最適化を行う事ができる
共通して参照されるデータのクラスタ化
インデックスの慎重な使用
データベースのメモリキャッシュ機能
など
3.4 構造的なマッピングに関するパターン
構造的なマッピングとは、メモリ上のオブジェクトとデータベーステーブルとのマッピング
3.4.1 関係のマッピング
外部キーマッピング、一意マッピング、多対多などの関連
3.4.2 継承
シングルテーブル継承(STI):階層にあるすべてのクラスを格納するために1つのテーブルを使用する(つまり、1つのテーブルにすべてつっこむ)
typeカラムを持つ
メリット:すべての要素を同じテーブルに配置でき、修正が容易になること。JOINを回避することができ、アクセス速度が速いこと。新しい型を追加する際のマイグレーションが簡単(基本的にはtypeの値を追加するのみ)
デメリット:全ての可能な部分型に対応する列であるtypeを持つ必要があり、nil
具象テーブル継承(CCI):階層にある各具象クラスを格納するために1つのテーブルを使用する(各階層ごとにテーブルを作る)
メリット:
デメリット:
クラステーブル継承(CTI):階層にあるクラスごとに1つのテーブルを使用する(クラスごとにテーブルを作る)
メリット:
デメリット:
3.5 マッピングの構築
リレーショナルデータベースへのマッピングを行う際は以下の3つの状況に直面する
自分でデータベースのスキーマを自由に設計できる場合
すでに決まっているスキーマに合わせなければならず、変更が一切できない場合
既存のスキーマに合わせる必要はあるが、一部の変更については相談や調整ができる場合
3.5.1 2重のマッピング
3.6 メタデータの使用
メタデータマッピングは、データベースの列をオブジェクトのフィールドにマッピングする方法を詳述したメタファイルへマッピングを集約することに基づいている
→ 「どのデータベースの列が、プログラムのどのオブジェクトのフィールド(属性)に対応するか」を、 プログラムのコードの中ではなく、別の“設定ファイル(=メタファイル)”にまとめて書いておく方法、ということ。
3.7 データベース接続
クエリはレコードセットを返す
3.8 その他の要点