質問: array( 'Post' => array( 'className' => 'Post', 'type' => 'INNER', 'foreignKey' => 'post_id', 'conditions' => array('status' => 0), 'fields' => array( 'post', 'title', 'text', 'count', 'created' ) )); ``` 上記を踏まえて質問です。 1まず、基本的に他の機能でも`id`でデータをselectしたり、updateということはなく、だいたいは`post_id`でやっています。 やり始めた頃はインデックスもよく分からず、見よう見まねでDBのインデックス、主キーに`id`を指定していましたが、 この状態ではインデックスは全く意味がないのでは?と思いました・・・。 複合インデックスは好ましくないと見かけたのですが、`post_id`にもインデックスを付けることでインデックスの役割を果たしてくれるようになるのでしょうか? 2また、DBとCakePHP側で主キーが違うせいで色々ややこしくなっています。 下記のような状態はやはりよくないですよね・・・? `post_id`でしか記事とコメントを紐付けられないので、アソシエーションするならprimarykeyは`post_id`のままにしておくしかありません。でも下記のような問題も起きるので、 アソシエーションをやめてjoinにするのがいいのか・・・?と悩んでいます。 A. `id`をプライマリキーに`save()`で情報を上書きしようとすると、 CakePHP側では`post_id`が主キーになっているため、その`id`は既に存在するから新しくcreateできないよ!と、 怒られて上書きができない。そのため、`updateAll`しか使えない。 B. `findById()`なら`id`のほうが主キーとして扱われるが、`read()`だったら`post_id`が主キーとして扱われる。 突っ込みどころが多いと思いますが、どのようにするのが良いか意見頂けると幸いです。 よろしくお願い致します。
回答: 主キーをCakePHP側か実テーブル側に合わせるべきでしょうね。 ただcommentの方はpost_idを主キーにすると関連が1:1になってしまうので、 postとcommentが1:N(1:多)であるならidをそのまま主キーとするか、 post_idともう一つ連番などの識別用の列を用意して複合主キーにするとかですかね。 ただ恐らくデータが入っていると思うので、 今のテーブルをリネーム(post_bkなど)して 正しくテーブル定義し直したものに、 ``` INSERT INTO post SELECT * FROM post_bk ``` とかで一括移行すると良いと思います。 主キー重複には要注意ですが。 **追記1** CakePHPほとんどかじってないから見当違いなこと言ってるかも...。 1と2にも返答しておくと、 1はUNIQUE制約を張れば主キーと似たようなことはできますが、 違いとしとしてNULLが許容される点とNULLに限っては重複が認められる点があります。 まぁNOT NULL制約を合わせてつけるとNULL自体登録不可に出来るのでより主キーっぽくは出来ますが。 (UNIQUE INDEXも勝手に貼られたと思います。) 2は範疇外であまり分からないのですが、 save時にpost_idが重複してこけるのであれば、 save呼び出し前にユニークなpost_idを採番できてないだけとかありませんか? **追記2** 質問にあまり関係のない蛇足ですが... 1.post_idは必ず採番される 2.post_idは必ず一意に定まる 上記の要件があるのでしたら主キー制約が張れないにしろ、 UNIQUE制約とNOT NULL制約は、 よっぽどの理由がない限りはpost_idには付与した方が良いです。 (既にしてるということであれば以下もスルーで...) 制約は**ビジネスルールの再現、データ整合性の保証**を可能にするので。 付加的な要素として他の開発者にも意図を伝える手段にもなり得ます。 洗練されたテーブル設計は、 それだけである程度のビジネスルールを浮き彫りに出来ることを知っておいて損はないです。