hasOne アソシエーション

hasOneアソシエーションはテーブル間で1つのレコードに対して他のテーブルに紐付くレコードが1つの場合にjoinする場合に使用します。
CakePHPのドキュメントにならってUserモデルとProfileモデルで例を。
本来ならば、テーブルに外部キーを設定し、整合性を担保させると思いますが、hasOneを使用するのに必須ではありません。
usersテーブル
CREATE TABLE IF NOT EXISTS `users` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `username` VARCHAR(255) NOT NULL, `password` CHAR(128) NULL, `status` TINYINT NULL, `created` DATETIME NULL, `modified` DATETIME NULL, PRIMARY KEY (`id`), UNIQUE INDEX `username_UNIQUE` (`username` ASC)) ENGINE = InnoDB
profilesテーブル
CREATE TABLE IF NOT EXISTS `lab`.`profiles` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `user_id` INT UNSIGNED NOT NULL, `first_name` VARCHAR(64) NULL, `last_name` VARCHAR(64) NULL, `bio` TEXT NULL, `created` DATETIME NULL, `modified` DATETIME NULL, PRIMARY KEY (`id`)) ENGINE = InnoDB
Userモデル
// app/Model/User.php public $hasOne = array( 'Profile' => array( // 'className' => 'Profile', // 'foreignKey' => 'User_id', // 'conditions' => array( 'Profile.status' => '1'), // 'fields' => // 'order' => 'Profile.created DESC', // 'dependent' => true ) );
className hasOne先のモデル名
conditions JOINする条件
fields 取得するカラム
order 並べ替え
dependent trueの場合、親(User)側レコードが削除された場合に子(Profile)も削除される。(これは別記事にて)
実行SQL
SELECT `User`.`id`, `User`.`username`, `User`.`password`, `User`.`status`, `User`.`created`, `User`.`modified`, `Profile`.`id`, `Profile`.`user_id`, `Profile`.`first_name`, `Profile`.`last_name`, `Profile`.`bio`, `Profile`.`created`, `Profile`.`modified` FROM `users` AS `User` LEFT JOIN `profiles` AS `Profile` ON (`Profile`.`user_id` = `User`.`id`) WHERE 1 = 1
レコード数増に伴う性能改善
レコード数が増えていくと、joinするのに時間がかかっていきますので、インデックスを張って下さい。
4000行のhasOne(Left Join)でDB/Cake両方のキャッシュをOFF
インデックスなしの場合→平均13秒ほど
インデックスありの場合→50ミリ秒ほど
(って、秒数はマシンスペックによります。)
MySQLでの外部キーとインデックスの作成はこちらを参考にして下さい。hasOneの場合はuniqueオプションを使用して下さい。
外部キー(foreign key)を作成するとインデックスもついてくる | MySQL
Models > Associations > hasOne
関連記事
-
-
Syslogログエンジン
2.4から「Syslog」ログクラスが追加され、簡単にSyslogを使用できるようになりました。 CakePHP側の設定はbootstrap.php内のCakeLogコンフィグのengineを'Sy
-
-
recursive設定によるfind()性能改善
CakePHPでは、モデルにアソシエーションを設定している場合、recursive(=>joinする階層)はデフォルトで0に設定されています。「recursiveゼロ」の意味するところとは、「1跨ぎま
-
-
radioボタンを実装
Radioボタンの実装は、セレクトボックスとほぼ同じです。 個人的にはラジオボタンをすすんで使用することは少ないのですが、2択くらいの選択肢であれば非常に便利ですよね。 今回は、その実装方法 デモ
-
-
(メール・URL・電話・郵便・IP) データ バリデーション
今回は、プロフィール情報に使用されるデータに絞ったバリデーションルールです。 バリデーションルール 以下の5つのバリデーションルールがコアに用意されています。 email メールアドレス
-
-
Js/Cssファイルの読み込みや出力する方法
CakePHPのHTMLヘルパーにはjsファイルやcssファイルを読み込むためのメソッドが用意されています。ファイルを読み込むのに加えて、出力先を複数指定できるようになっています。 また、インライン
-
-
Formヘルパーのinputタグのdiv/labelなどの設定
Formヘルパーのinputではデフォルトでは以下のようにdivで囲われて、labelが付与されて出力されます。 CSSのフレームワークなどであらかじめ決まったスタイルがある場合に便利に作られていま
-
-
入力文字列の長さ(文字数)をバリデーション
CakePHP 2には、コアバリデーションに文字列の長さを検証する関数が用意されています。 文字列長(コア)バリデーション minLength - 最小文字数以上であること maxLengt
-
-
CSS/JSをひとまとめにして軽量化するプラグイン「Minify plugin for CakePHP」
「Minify plugin for CakePHP」は、インクルードするCSSもしくはJSファイルをひとまとめにしてキャッシュ化してくれるプラグインです。 導入 ダウンロード・解凍し
-
-
CakePHP 2.x インストール
現在まで私が商用・非商用にリリースしているCakePHPアプリケーションは全て1.3.xベースで作成しています。 まだまだロードマップ的には大丈夫そうですが、お客さん向けに納品しているアプリケーショ
-
-
Blowfishを使用してハッシュ化する
使用方法 Blowfishを採用してハッシュ化を行う場合、Securityクラスのhashメソッドを呼び出します。第2引数に'blowfish'を指定し、第3引数を指定しないもしくはfalseにしま
Comment
http://t.co/cbhroBOPba CakePHP 2.4 - hasOneアソシエーション ブログ投稿