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
関連記事
-
-
Jsヘルパーを使用してAjax更新
更新処理でページ遷移を伴う場合、ページ全体をレスポンスするのに対して、Ajax処理ではページの一部のレスポンスが可能となるためサーバからの通信量を抑えることが可能となります。デモ head
-
-
Cookieログイン
今回は、ログイン画面でよくみかけるクッキーログインの機能を使ってみます。 CakePHPには、Cookieコンポーネントがあります。(PHPのsetcookieメソッドのラッパー)メソッドはwr
-
-
ユーザ登録(仮登録・メール・本登録)
以前1.3版で投稿した「ユーザ登録」処理の2.x版を作成しました。フローは同じで以下のようにします。 1. メールアドレス・パスワードでユーザ登録 2. この時点では仮登録として、本登録用のU
-
-
独自のバリデーションルールを作成
CakePHPで組み込みバリデーションルールをつくる方法は、正規表現を定義する方法と独自メソッドを定義する方法の2つがあるようです。 参考 Custom Validation Rules 正規
-
-
selectボックスを実装
今まで、selectボックスのgroupを作成するのにSet::Combineを使用していましたが、意外と簡単にできることに気付いてしまったので、ご紹介。(自分だけ知らなかったことに気付いた と言った
-
-
Js/Cssファイルの読み込みや出力する方法
CakePHPのHTMLヘルパーにはjsファイルやcssファイルを読み込むためのメソッドが用意されています。ファイルを読み込むのに加えて、出力先を複数指定できるようになっています。 また、インライン
-
-
アップロードファイルのバリデーションルール
CakePHP 2.2や2.3になってファイルアップロードに対するルールがコアバリデーションに追加されているようで、まとめてみました。 コアバリデーション 関連しそうなルールは以下の4つの
-
-
CakePHP 2.x インストール
現在まで私が商用・非商用にリリースしているCakePHPアプリケーションは全て1.3.xベースで作成しています。 まだまだロードマップ的には大丈夫そうですが、お客さん向けに納品しているアプリケーショ
-
-
RSSフィードの取得
コンロトーラ public function getrssfeed() { try { $newsItems = $this->Rss->read( 'http://
-
-
Blowfishを使用してハッシュ化する
使用方法 Blowfishを採用してハッシュ化を行う場合、Securityクラスのhashメソッドを呼び出します。第2引数に'blowfish'を指定し、第3引数を指定しないもしくはfalseにしま
Comment
http://t.co/cbhroBOPba CakePHP 2.4 - hasOneアソシエーション ブログ投稿