データベース設計とCakePHP

元記事はこちら

By Frank

CakePHPアプリケーションをはじめるには、まず適切なデータベースを用意します。特にデータ層(モデル層)で、アプリケーション構造の重要な部分になります。この記事はCakePHPアプリケーションのための構造化されたデータベースとデータ層の構築の方法を概念的に示します。

モデリング

なによりもまず、データベースの設計をしていることを忘れましょう!そうではなく、オブジェクトとプロパティを定義しているのです。これらのオブジェクトを「エンティティ(要素)」と呼びます。各エンティティのプロパティを「アトリビュート(属性)」と呼びます。1つのアトリビュートは1つのエンティティに所属します。エンティティの一例はユーザです。このユーザは多くのアトリビュートを持ちます。名前やパスワード、eメールアドレスです。

たいてい、プロジェクトには多くの要求のリストとアプリケーションのための機能設計があるものです。これらの文書はアプリケーションのための非技術的な説明を含み、これをもとにデータベースモデルの作成へと進みます。しかし、何をモデル化するのでしょうか?

名詞の抽出

機能設計では多くの名詞が出てきます。ある名詞はアプリケーション上のエンティティか、エンティティのアトリビュートになります。これを割り当てる一番簡単な方法は、表にこれらすべての語を置いて、それらがアプリケーションで何を示すのか書いてみることです。極めて退屈な作業かもしれません。しかし漏れをなくすのには最適です。以下に例を示します。

「CakePHPでの慣例」という列を追加しました。後に示す概念モデルで使用するエンティティ名になります。物理モデルを作成したら、名称は変更できません。「users」のかわりに「User」というテーブルを作成してしまったら、それはCakePHPの慣例に従っていない、ということになります。

訳者注:CakePHPでは、テーブル名は名詞の複数形を使用します。

データベースの概念モデル

これで概念モデルの基礎ができました。いよいよ作成です。最初にエンティティとアトリビュートをモデルに追加します。以下に、わたしたちが決めたデータ型とカラム名を示します。繰り返しますが、データベースを作成しているのではありません。外部キーについては忘れてください。CakePHPの慣例に沿うことを考えておきます。先の表のように、モデルの名称は複数形になります。以下はエンティティです。

別の少し妙な点はプライマリ識別子の名称です。 ‘user_id’や’project_id’などを使いました。CakePHPの慣例に沿っていないことは分かっています。しかし、全てのエンティティで’id’を使用していたら、プログラミングは標準化の規約のために不可能になってしまいます。プライマリ識別子はあとで’id’に戻せますし、あるいは別の主キーをCakePHPのモデル内で設定できます。

ところで、プライマリ識別子に二つ以上のアトリビュートを設定することはできません。CakePHPは現時点でサポートしていませんし、将来そうすることもありません。(参照:https://trac.cakephp.org/ticket/1923

先に挙げたモデルでは、1つのエンティティにつき3つの欄があります。一番上の欄はエンティティ名です。二番目の欄はアトリビュートです。下線のあるアトリビュートは、マークされているとおり、プライマリ識別子です。その後ろにはデータ型があり、その後ろにはフラグがあります。必須項目であるかどうかを意味します。一番下の欄は識別子です。

さて、モデル内で相互に関連付ける必要のあるエンティティとアトリビュートが揃いました。以下のように追加しました。

  • 1人のユーザは0以上のプロジェクトに属する
  • 1つのプロジェクトは1人以上の所有者(ユーザ)がいる
  • 1回のリリースは1人のユーザに属する
  • 1人のユーザは0回以上のリリースができる
  • 1つのプロジェクトは0回以上のリリースがある
  • 1つ以上のリリースは1つのプロジェクトに属する

結果は以下のとおりです。

これはCakePHPを使用するうえでとても重要なモデルです。このモデルを概念データベースモデルといいます。このモデルから数クリックで簡単にデータベース全体を生成できます。このモデルを正しく作成すれば、データベースのための作業はそれほど必要ありません。

この概念データベースモデルでは、エンティティ同士のリレーション(関連付け)が分かります。モデルの関連付けに使われているダッシュ(|)は「1」の意味で、円(○)は「0」の意味です。1本の先は「1」の意味で、三叉は「それ以上」を意味します。それで、

  • ユーザ - 0以上 - プロジェクト
  • プロジェクト - 0以上 - ユーザ
  • リリース - 1以上 - ユーザ
  • ユーザ - 0以上 - リリース
  • プロジェクト - 0以上 - リリース
  • リリース - 1以上 - プロジェクト

関連付けの名称を「projects_users」のようにつけました。これはCakePHPのテーブルの結合の慣例に沿ったものです。ときおり(多対多の場合だけですが)別のテーブルを用意して2つのエンティティを結合します。これは「結合テーブル」と言います。この記事の後のほうでまた解説します。

訳者注:この「結合テーブル」にはいろいろな呼び方があり、「中間テーブル」「リレーションテーブル」などとも呼ばれます。

物理データベースモデル

さて、概念データベースモデルができました。物理データベースモデルの生成ができます。ついにデータベースのお時間です。物理データベースモデルでは、エンティティはテーブルとなり、アトリビュートはカラムとなることが分かるでしょう。このデータベースマップをたった3クリックで作成しました。

3つではなく4つの項目があることに気づくでしょう。4番目は「projects_users」というものです。これは先に述べた結合テーブルです。多対多のリレーションをもとに生成されました。リリーステーブルをよく見ると、”project_id” と “user_id” が追加されていることがわかります。ほかのリレーションの結果追加されたものです。概念データ型がMySQLのデータ型に置き換えられていることも分かるでしょう。(”Variable characters (100)” としていたものが “varchar (100)”になっています。)これら全ては、CakePHPがするように自動的に調整されるものです。ここに追加すべき唯一のものは、主キーの識別フラグを「auto increment」(自動インクリメント)にすることです。

このダイアグラムから(数クリックで)SQLのCRATE文を生成できます。phpMyAdminにペーストしてデータベース全体を作成します。

CakePHPのモデル

データベースを作成しましたので、CakePHPアプリケーションをはじめましょう。ここではCakePHPアプリケーションのはじめ方については述べません。マニュアルに書いてありますので、そちらをまず読みましょう。ここではアプリケーションのデータソースとなるModelクラスについて扱います。

先に作成した概念データベースモデルから作成しているので、モデルについてはすぐに分かるでしょう。エンティティは必要なモデルになっています。ここで行うことはエンティティ名をキャメルケースにして単数形にすることです。

訳者注:キャメルケースとは wikipedia キャメルケース

概念データベースモデルの関連付けは、CakePHPのモデルクラスにおける関連付けになります。概念データベースモデルが大元の設計図であり手軽なドキュメントにもなるということなのです。CakePHPのモデルと関連付けを表すように概念データベースモデルを更新しました。

Happy baking!

Phally

これは1つの方法にすぎません。方法の良し悪しではなく、これはわたしの方法でありみなさんにお分かちしたいと思ったものです。質問やコメントがあれば、遠慮なくお知らせください。この記事ではSybase PowerDesignerを使用しました。物理データベースモデルはMySQL Workbenchのようなアプリケーションを使用しました。MySQL Workbenchを使用しない理由は、多対多のリレーションで、外部キーをテーブルに挿入するという方法で即座に解決しようとするからです。これではアプリケーションのモデルを正確に表すことにならないので概念データベースモデルを作成できません。それで、MySQL Workbenchはこの記事で示した方法には十分対応できないでしょう。

(翻訳終わり)

モデルの関連付けは設計者の腕の見せどころですね。CakePHPのモデルの関連付けではbelongsToやhasManyなど、英語表現がそのまま採用されるものもありますので、英語で覚えたほうが話は早いかもしれませんね。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です