CakePHP1.3.6:データのメンテナンスパターン

前回は、HABTM(hasAndBelongsToMany)の関係にあるデータの保存について書いた。

順番が変ではあるが、データのメンテナンスパターンについて考えてみたい。
データの入れ方は、お客さんの希望で変わってしまうので決めつけることはできないが、自分的にはガイドラインを持ってないとこまるので覚書。

A hasOne Bの場合

以前取り上げた、UserとUserAttrがこのパターンに当てはまる。

  1. Aをメンテナンスすると同時にBをメンテナンスする。(AをプライマリにしてBをメンテナンスする)
  2. BをプライマリにしてAをメンテナンスすることはない。

つまり、1つのパターンしかない。

A belongsTo B

  1. Bをメンテナンスする。
  2. Aをメンテナンスするときに、Bを参照し、(AはBに従属しているという)関係性を付与する。

という場合は、Bをマスタ、Aはそれを参照するエンティティーという場合が典型的と思う。

A hasMany B

hasManyとbelongsToは、逆の関係にあるので、この関係は「B belongsTo A」となる。
ただし、「Many B belongsTo A」が正確。

  1. Aをメンテナンスする。
  2. Bをメンテナンスするときに、Aを参照し、(BはAに従属しているという)関係性を付与する。このとき、Aは複数のBから関係性を付与できる。

というパターンに帰着する。

例えば、Aが商品、Bが画像を表す場合を想定する。
このとき、上のパターンに反して、

  1. Bをメンテナンスする
  2. Aをメンテナンスするときに、Bを参照して関係性を付与する。

としたとしよう。A hasMany Bの場合、Bに「Aのprimary key」を外部キーとして「1つだけ」持つことになる。
なので、A(商品)を登録する際にB(画像)を参照した際、Aとの関係性が定義されていないB(つまり、外部キーが定義されていないBのレコード)を表示する必要がある。
上のやり方だと、B(画像)はA(商品)より先にメンテナンスするのだから、A(商品)をメンテナンスしていて、想定したB(画像)が既に他のA(商品)に紐付いていた場合、Bのメンテナンスに戻ことになり効率が悪い。これを回避するには、A hasMany Bではなく、A HABTM Bと定義しなおすことになるが、これでは仕様が変わってしまう。

つまり、この場合、

  1. 商品(A)をメンテナンスする。
  2. 画像(B)をメンテナンスするときに、商品(A)を参照して関係性を付与する。

のが適当である。

A HABTM B, B HABTM A

これは双方向。

  • Aをメンテナンスするときに、Bとの関係を付与する。
  • Bをメンテナンスするときに、Aとの関係を付与する。

さきのログで取り上げた、商品とカテゴリーの関係がこれにあたる。