質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • CakePHP

    2474questions

    CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

CakePHPでid(サロゲートキー)以外を主キーにする場合

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,231

smnsmn

score 164

プログラミングを始めたばかりの頃、DBでは主キーにid(サロゲートキー)を指定していたにも関わらず、
CakePHP側でプライマリーキーをuser_idに指定したために後で大変な思いをしました。

新たに、DBの設計を考えているのですが、
DBでの主キーをuser_id
CakePHP側でプライマリーキーをuser_id
にすれば、過去のような惨事は起きず、問題なくつかえると思うのですが、この場合user_idはユニークなランダム英数字10文字などでも問題無いのでしょうか?

また、このuser_idは外部キーとしても使われます。
例えばpostsテーブルのposterカラムにuser_idが入り、postとuserを紐付けます。

DB設計において、サロゲートキーは本来使わずにナチュラルキーを用いるべきだと、色々な記事で読みました。
ですが、フレームワークを使う以上、規約にのっとるべきだともありました。

user_idを主キーにするとインデックスをつけられない?でしょうか・・・?

長々書きましたが、

・CakePHPの規約にのっとり、id(サロゲートキー)を主キー・プライマリーキーとし、user_idを外部キーとする
・user_id(ユニークなランダム英数字10文字)を主キー、プライマリーキーにするのは問題無いが外部キーとして使うのはやめておいた方がいい
・user_idを主キー・プライマリーキー・外部キーとして用いる問題ない

どうするのが良いでしょうか?
アドバイス頂けますと幸いです。

よろしくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

問題を正しく認識できていない可能性がありますが、質問にコメントしてみます。

プログラミングを始めたばかりの頃、DBでは主キーにid(サロゲートキー)を指定していたにも関わらず、 
CakePHP側でプライマリーキーをuser_idに指定したために後で大変な思いをしました。

DB側で主キーがidだったなら、CakePHPもプライマリキーをidにすべきだったのではないでしょうか...
そうしなかった理由がよくわかりません...。

新たに、DBの設計を考えているのですが、 
DBでの主キーをuser_id 
CakePHP側でプライマリーキーをuser_id 
にすれば、過去のような惨事は起きず、問題なくつかえると思うのですが、この場合user_idはユニークなランダム英数字10文字などでも問題無いのでしょうか?

Cakephpに規約に従うならusersテーブルの主キーの名前はuser_idではなく、idにすべきだと思います。
Model側にプライマリキーのカラム名を指定すれば他のカラム名でも問題ないです。

また、このuser_idは外部キーとしても使われます。 
例えばpostsテーブルのposterカラムにuser_idが入り、postとuserを紐付けます。

Cakephpの規約に従うならusers.idとposts.user_idにすべきですが、
アソシエーションの設定を追加すれば違うカラム名でも問題ないです。

DB設計において、サロゲートキーは本来使わずにナチュラルキーを用いるべきだと、色々な記事で読みました。 
ですが、フレームワークを使う以上、規約にのっとるべきだともありました。

ケースバイケースかもしれないので、断言はできませんが...
ユニークなランダム英数字10文字という意味のない文字列はナチュラルキーとは呼ばないと思います。ランダムな英数字を使うぐらいなら、連番を使ったほうが普通だと思います。
user_idがユーザ名を意味する一意な文字列だったらナチュラルキーだと思いますが、それを外部キーに使うと、あとで変更するのが大変になるので、サロゲートキーを使うのが一般的なんだと思います。

user_idを主キーにするとインデックスをつけられない?でしょうか・・・?

主キーには必ずインデックスがつきます(たぶん)
※少なくとも英数字10文字なら問題はありません。

・CakePHPの規約にのっとり、id(サロゲートキー)を主キー・プライマリーキーとし、user_idを外部キーとする 
・user_id(ユニークなランダム英数字10文字)を主キー、プライマリーキーにするのは問題無いが外部キーとして使うのはやめておいた方がいい 
・user_idを主キー・プライマリーキー・外部キーとして用いる問題ない

ここまでの話を総括すると、Cakephpで自分が実装するならCakephpの規約に従って...
※別にCakephpでなくても、これに近い設計にすると思いますが

  • usersテーブルの主キーはidとしてauto incrementで自動採番にしますね。
    ※ランダムな英数字にする必要性は特にないかと(特別な理由があれば別ですが)
  • postsテーブルのusersテーブルへの外部キーは、posts.user_idにしますね。

なお、今までid以外を主キーとするテーブルをCakephpでたくさん扱ってきましたが、
特別な設定が必要だったりする程度で、そんなに苦労したこともないですよ。
※複合主キーだとやや制限はあるかもしれませんが、それでもそんなに困った記憶はないです。

不明な点や誤解等あれば、コメントお願いします。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/11/09 12:04

    解答、ありがとうございます。

    >DB側で主キーがidだったなら、CakePHPもプライマリキーをidにすべきだったのではないでしょうか...
    これに関しては恥ずかしながら、本当に初めたばかりでよく分からずに、idと別でユニークなuser_idを振っており、idがあるにもかかわらずfindなどの条件でidを使わずuse_idを使っていたからです。

    >ユニークなランダム英数字10文字という意味のない文字列はナチュラルキーとは呼ばないと思います。ランダムな英数字を使うぐらいなら、連番を使ったほうが普通だと思います。
    なるほど、そうなのですね。
    ランダムな英数字は例えば、idが会員番号だとしたら、user_idは表示用の会員IDのようなものです。
    例えばそのユーザーのマイページを表示するときに、/hoge/user/xxxxxxxx
    みたいにidではなくuser_idを表示したり、と言った感じです。
    (この場合、やはりidを主キー、user_id(というよりはuser_nameみたいな感じ?)で扱うべきな気もします・・・)

    追加で質問です。
    ・userテーブルの主キーをサロゲートキーにするときに、idではなくuesr_idというカラム名にするのもよくないでしょうか?

    cakephpの規約に
    -------------------------------------------------------------
    hasMany,belongsTO,hasOne中の外部キーはデフォルトで関連するモデルの単数形の名前に_idを付けたものとして認識される。
    ケーキ職人がケーキを複数持っているbakers hasMany cakesなら
    cakesテーブルはbaker_idを外部キーとしてbakersテーブルのデータを参照します。
    -------------------------------------------------------------
    とありましたが、この場合、cakesテーブルが持っているbaker_idをもとに、bakersテーブルのidを参照する。
    という意味でしょうか?

    長々となり、すみません。
    もしよろしければご回答頂けますと幸いです。

    キャンセル

  • 2016/11/09 12:22

    > 例えばそのユーザーのマイページを表示するときに、/hoge/user/xxxxxxxx
    > みたいにidではなくuser_idを表示したり、と言った感じです。
    > (この場合、やはりidを主キー、user_id(というよりはuser_nameみたいな感じ?)で扱うべきな気もします・・・)

    なるほど、それだったらuser_nameの方が適切だと思います。

    > とありましたが、この場合、cakesテーブルが持っているbaker_idをもとに、bakersテーブルのidを参照する。という意味でしょうか?

    そうです。bakersの単数形bakerに_idを付けたbaker_idがデフォルト値です。ただ、規約にそっていなくても、アソシエーションの定義に設定(foreignKey)すればいいだけなので必ずしも守らなくてもいいと思いますよ。自分は長いテーブル名の場合などは、短縮した名前にすることがよくあります。
    例)post_comment_photosテーブルだったらデフォルトpost_comment_photo_idですが、photo_idに短縮するなど。

    キャンセル

  • 2016/11/09 19:38

    丁寧に解説頂きありがとうございます。
    とても勉強になりました。
    もっとDBについて勉強して行きたいと思います。

    キャンセル

同じタグがついた質問を見る

  • CakePHP

    2474questions

    CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。