# Chapter 6 データベースの設計とドメインオブジェクト ## テーブル設計が悪いとプログラムの変更が大変になる ### データの整理に失敗しているデータベース ### 用途がわかりにくいカラム ### いろいろな用途に使う巨大なテーブル ### テーブルの関係がわかりにくい > [name=Yusaku Matsuki] > foreign keyってあんまりあまり使ってないかも ## データベース設計をスッキリさせる > [name=Yusaku Matsuki] > まとめ > - スキーマ名 / テーブル名 / カラム名に適切な名前をつけることで、意図が明確になり可読性が上がる。 > - 適切なデータ型を使うことでプログラムをシンプルに保つ。 > - NOT NULL制約 / 一意性制約 / 外部キー制約を使うことで先述した問題が解決される。 > > 所感・雑感 > - ドメインオブジェクトの作り方と同じで、小さい部品に分けて、それを組み合わせて使うということか。 > - 全部NOT NULL制約をかけてみると言うのは実践したい。 ### 基本的な工夫を丁寧に実践する - データベース設計で大切なのは、基本的な仕組みをきちんと使うとこと。 - 名前を省略しない - 適切なデータ型を使う - 制約をきちんと使う #### 名前を省略しない - 意味の明確な普通の単語を使うべき。 - かつてはテーブル名やカラム名の文字数制限があった。 - 現在は緩和されているので、単語を2つ3つ組み合わせた名前は問題ない。 #### 適切なデータ型を使う - 適切なデータ型の指定は、不正なデータを防ぐ基本。 - 不適切な型を指定してしまうと、不正データの混入を防ぐためのif文が増え、プログラムが複雑になる。 - 長さ無制限のTEXT型やLargeObject型ですべてを済ませてはいけない。 #### 制約を必ず使う - データーベース設計をきちんとやると3つの制約は自然に満たされる。 - NOT NULL制約 - 一意性制約 - 外部キー制約 - この制約のないからうやテーブルは設計として問題があることを疑ったほうが良い。 ### NOT NULL制約が導くテーブル設計 - NULLは「未知」ということ。データベースは「既知」を記録するための仕組みなので、NULLを持ち込むのは掟破り。 - カラムにはNULLを含まないのがデータベースの基本。 - 演算と検索を行う際にNULLがあるとコードが複雑になる。 - NULLを含んだデータ演算の結果はすべてNULLになる。 - 演算不能を意味し、有効なデータではない。 - 検索条件の対象とするカラムにNULLがあると意図と違う結果になる可能性がある。 - すべてのカラムにNOT NULL制約にすることで正規化が進む。 - NULL値が必要なカラムは別テーブルに分ける。 - 「NULL逃れ」をしてはいけない。 - 値がない場合に「unkown」や「9999」を入れてはだめ。 ### 一意性制約でデータの重複を防ぐ - 一意性制約を徹底することで、データの重複や不正なデータの混入を防ぐことができる。 - 重複したデータは不整合の原因になりがち、1つの事実に対して複数の記録が存在している可能性があるため。 - 一意性制約は主キーだけでなく、すべてのカラムとその組み合わせが候補になる。 - どのカラムの組み合わせが一意になる/ならないかを常に気にかけるとよい。 ### 外部キー制約でテーブル間の関係を明確にする - 一意性制約とNOT NULL制約を追加することでテーブルが正規化される。 - 正規化する際にテーブル間の関係を明確にすることが重要。 - テーブルを分割していくと、データとデータの意味が失われてしまうため。 - 外部キー制約を使って、データ間の関係を記録することを強制しなくてはならない。 ## コトに注目するデータベース設計 ## 参照をわかりやすくする工夫 ## オブジェクトの設計とテーブル設計 ### オブジェクトとテーブルは似てくる - オブジェクトとテーブルは似てくるが、同じものではない。 ### 違うものとして明示的にマッピングする - オブジェクトは、データとロジックを一体に考える。 - 部分から段階的により大きなプログラムを組み立てていく。 - テーブルは、データの管理が本質。 - データの整合性を確保するために、関連するデータを全体的に洗い出して関係を明確に設計するトップダウンのアプローチが重要。 | 特性 | オブジェクト | テーブル | | -------- | -------- | -------- | | 目的 | データとロジック、特にロジックの整理 | データの整理 | | 関心事 | 導出や加工のロジック、データを使った判断ロジック | 導出や加工物になるデータ | | アプローチ | 部分から全体 | 全体から部分 | | 設計変更のリズム | 頻繁 | ゆるやか | - オブジェクトの設計とテーブルの設計は大きく異なる。 - 設計の着眼点や設計家前のプロセスは別の道を歩む。 - よってオブジェクトとテーブルを自動的にマップングするアプローチはうまく行かない。 - どちらかの設計のアプローチがやリズムに大きく制約され、結果、それぞれの変更の足かせになる。 ### オブジェクトはオブジェクトらしく、テーブルはテーブルらしく - オブジェクトはオブジェクトとして、テーブルはテーブルとして設計と改善を進め、オブジェクトとテーブルのマッピングは、両方の設計の震度に合わせながら明示的に定義するようにする。 - こうすることでお互いの設計変更の影響をマッピング定義に局所化でき、オブジェクトの設計とテーブルの設計をより良いものにできる。 - オブジェクトとテーブルのマッピングのしくみとして、様々なフレームワークがある。 - ドメインオブジェクトとほかのデータ形式との変換は、ある程度、定型的な記述が必要。 - フレームワークによっては、変換の指定を簡略化するために、ドメインオブジェクトの記述に約束事を強制するものがある。 - クラス名やメソッド名の命名方法 - フレームワークが要求するメソッドの追加 - マッピングの情報をアノテーションで埋め込む - ドメインオブジェクトにフレームワークの都合を持ち込んではいけない。 - ドメインオブジェクトの設計をフレームワークの都合に合わせ始めると、データベース操作などの具術的な関心事が混在する。 - 結果、業務ロジックの整理が曖昧になる - またコードも業務の関心事以外のフレームワークに合わせるための記述が増る。 - フレームワークの都合を意識しながらの変更になるため、変更がやりにくくなる。 #### オブジェクト設計とテーブル設計の独立性を保ちやすいフレームワーク - MyBatisオブジェクト設計とテーブル設計は本質的に異なる空間の活動という発想で設計されたツール。 - オブジェクト設計とテーブル設計の独立性を保ちながら、オブジェクトとテーブルのマッピングを実現するために便利な仕組みを用意している。 - ドメインオブジェクトを業務ロジックの整理の手段に限定して使うことができ、結果、業務の関心事に一致した、わかりやすく、変更を楽で安全にするアプリケーション設計がやりやすくなる。 - 既存データベースを使ってアプリケーションを開発するときも、既存のテーブル設計にあまり制約されず、オブジェクト指向の良さを生かしたアプリケーション設計がやりやすくなる。 - マッピングはある程度煩雑になるが、テーブル設計とオブジェクト設計の独立性を維持できるため、比べもにはならないメリットが有る。 ### 業務ロジックはオブジェクトで、事実の記録はテーブルで - ドメインオブジェクトの設計に、データベース設計の知識や都合を持ち込んではいけない。 - ドメインオブジェクトは、業務の関心事を整理するための手段。 - 業務で扱うデータを判断/加工/計算するための業務ロジックを記述する手段。 - 事実を正しく記録するための手段であるデータベース設計とは別の設計対象。 - 業務アプリケーションの設計では、ドメインオブジェクトの設計、データベスの設計どちらも中核の関心事。 - 両者を適切に関連付けることが必要。 - そのためにはドメインオブジェクトとテーブルを機械的にマッピングする方法は好ましくない。 - 設計に不要な制約を持ち込み設計を歪める。 - ドメインオブジェクトとテーブルは別々に正しく設計するべき。 ## 第6章のまとめ ###### tags: `ISBN-978-4-7741-9087-7`