[CakePHP] HABTMの更新画面を自力で作ってみる

前回のエントリでは簡単なサンプルを作ってhasAndBelongsToMany(HABTM)の振る舞いを確認した。だけど、フロンエンドはscaffold任せで何もコーディングしていないので、今回は自力でビューやコントローラを定義してサンプルを作ってみる。

コントローラ定義

ビュー定義

HABTMで紐付けされているテーブルからのデータ選択はどうやったらできるのかいろいろ試行錯誤した結果、なんと $this->Form->input(‘Part’) の1行だけで実装できてしまうことが判明。CakePHP恐るべし。

動作

CakePHP-the-rapid-development-php-framework-Products-Mozilla-Firefox_00

CakePHP-the-rapid-development-php-framework-Products-Mozilla-Firefox_01

CakePHP-the-rapid-development-php-framework-Products-Mozilla-Firefox_02

[CakePHP] 簡単なサンプルを作ってHABTMの動きを確かめる

CakePHP初心者ゆえクックブックを読んだだけではどうもしっくりこないので、簡単なサンプルを作ってhasAndBelongsToMany(HABTM)の動きを確かめてみる。

アソシエーション: モデル同士を繋ぐ — CakePHP Cookbook 2.x ドキュメント
http://book.cakephp.org/2.0/ja/models/associations-linking-models-together.html

例題は「製品」対「部品」の多対多リレーション

例題として「製品」と「部品」の多対多リレーションを定義してみる。ある「部品」は特定の「製品」にしか使われていないかもしれないし、またある「部品」は複数の「製品」に使われているかもしれない。すなわち、「製品」と「部品」の間には排他関係の無い多対多のリレーションが存在する。

テーブル定義

あくまでサンプルなので、テーブルには最低限のカラムしか持たせていない。

モデル定義

コントローラ定義

とりあえずscaffoldに頼る。

実行

実行すると期待通りの動作が確認できた。

まずは製品一覧を表示。

CakePHP-the-rapid-development-php-framework-Scaffold-Index-Products-Mozilla-Firefox_00

製品を[View]すると、製品に(多対多リレーションで)紐付けされている部品のリストも表示される。

CakePHP-the-rapid-development-php-framework-Scaffold-View-Products-Mozilla-Firefox_00

製品を[Edit]すると、紐付けする部品を複数選択可能なリストボックスが表示される。

CakePHP-the-rapid-development-php-framework-Scaffold-Edit-Products-Mozilla-Firefox_00

Scaffoldを使ったお陰で簡単に実装できた。自力でコントロールを書いて実装するとなると大変そう。

[CakePHP] 多対多のリレーション定義でのHABTMとhasMany throughの使い分け

CakePHPの4つのアソシエーションのうち、hasOne(1対1)、hasMany(1対多)、belongsTo(多対1)の3つに関しては理解が容易。だけど初心者としては、残りの1つ、hasAndBelongsToMany(HABTM)(多対多)のアソシエーションに関しては更なる理解が必要だなと思ったので、少し突っ込んで調べてみる。

HABTMの特徴

まずはクックブックを読んでHABTMの特徴を頭に入れる。

「このアソシエーションは、結合される2つのモデルがある場合に使われます。」
言い換えると、2つのテーブルを結合するために使われるということ。

「hasManyとHABTMの大きな違いはHABTMモデル間のリンクは排他的ではない、ということです。」
レシピと材料のテーブルがある場合、hasManyだと、あるレシピで使われている材料は他のレシピには使えない(排他的)けど、HABTMだと、材料が既にあるレシピで使われていても他のレシピでも使える(排他的ではない)ということ。

アソシエーション: モデル同士を繋ぐ — CakePHP Cookbook 2.x ドキュメント
http://book.cakephp.org/2.0/ja/models/associations-linking-models-together.html

HABTMとhasMany throughの使い分け

クックブックによると、多対多のリレーションを定義できるのはHABTMに限らない。

多対多のリレーションを定義するには2つの方法がある。

  • hasAndBelongToMeny (HABTM)
  • hasMany through

その使い分けの基準については、以下のページが参考になる。

“HABTMの中間モデルの利用について” フォーラム – CakePHP Users in Japan
http://cakephp.jp/modules/newbb/viewtopic.php?topic_id=2819&forum=6

上記仮定において話を進めます。A, BはCの中間テーブルを元にしたhabtmな関係ですが、今回のようにCに中間データ以外の情報を載せるときには、$hasAndBelongsToManyを使用すると、用意されているひどく単純な処理から外れるのが難しいか、または細かいデータ取得の制御に向いていません。
これは重い足枷となります。よってhasMany throughという方法をとるのが一般的なプラクティスです。
詳細は http://book.cakephp.org/2.0/ja/models/associations-linking-models-together.html#hasmany-through を見てください。

クックブックにも以下の説明がある。

  • HABTMの中間テーブルは付加データを持つことをサポートしていない。
  • なぜなら、hasAndBelongsToManyアソシエーションはデータを一旦削除してから、そのあとでデータを保存するため。
  • そのため、新しいレコードが挿入されるとき、外部キーID以外の追加フィールドのデータが失われてしまう。

ただし、最近のバージョンでは改良されているみたいだけど。

バージョン 2.1 で変更.
unique に keepExisting を指定すれば、追加フィールドのデータを失うことなく保存できます。 unique キーについてはHABTM association arrays を参照してください。

ということで、とりあえず僕の結論としては、多対多のリレーション定義は以下のルールに従うことにする。

  • アソシエーションに付加データが無い場合はHABTM
  • アソシエーションに付加データがある場合はhasMany though

[CakePHP] 自習用に超簡単なサンプルを書いてみた

CakePHPのアーカイブにはサンプルが含まれていないので、自習用に超簡単なサンプルを書いてみた。簡易掲示板的なソフトで、テーブルは利用者(user)と投稿(post)の2つだけ。利用者を投稿に紐付けして、Scaffoldでデータ管理を行いつつ、インデックスページにページネーション付きで投稿を一覧表示する。とっても簡単なソフトだけど、僕のような超初心者が勉強するためのたたき台にはちょうどいいかも。

テーブル作成。

データベース定義

モデル定義

コントローラ定義

ビュー定義

動作画面

cakephp_01

cakephp_02

cakephp_03

[MySQL] テーブル構造を変更するためのSQL文例

普段の作業にはphpMyAdminを使っているので、僕はSQLにはあまり明るくない。だけど、同じスキームで複数のデータベースを運営しているので、スキーム変更を一括して行うためにはSQLを書かなければならない。

というわけで、自分が良く使いそうなSQL文例を覚え書きしておく。構文については参考サイトに大変解りやすく説明されているので参照のこと。

参考サイト

MySQL: 既存テーブルの構造の変更 – ALTER TABLE文、CHANGE COLUMN句
http://www.yukun.info/blog/2008/11/alter-table-add-drop-change-modify.html

[MySQL] utf8_general_ci と utf8_unicode_ci の違い

データベースのコレーション(Collation: 適合順序)について。

これまであまり深く考えずにutf8_general_ciを設定することが多かったけど、書籍やネットで見かけるサンプルにはutf8_unicode_ciを使っているものも少なくない。これらの振る舞いの違いは何なのか、一度しっかり押さえておきたい。

とりあえず公式サイトのマニュアルを探したら記述が見つかった。

MySQL :: MySQL 3.23, 4.0, 4.1 Reference Manual :: 9.1.12.1 Unicode Character Sets
http://dev.mysql.com/doc/refman/4.1/en/charset-unicode-sets.html

For any Unicode character set, operations performed using the xxx_general_ci collation are faster than those for the xxx_unicode_ci collation. For example, comparisons for the utf8_general_ci collation are faster, but slightly less correct, than comparisons for utf8_unicode_ci. The reason for this is that utf8_unicode_ci supports mappings such as expansions; that is, when one character compares as equal to combinations of other characters. For example, in German and some other languages “ß” is equal to “ss”. utf8_unicode_ci also supports contractions and ignorable characters. utf8_general_ci is a legacy collation that does not support expansions, contractions, or ignorable characters. It can make only one-to-one comparisons between characters.

抜粋拙訳

  • xxx_unicode_ciよりもxxx_general_ciのほうが処理が速い。
  • たとえばutf8_general_ciはutf_8_unicode_ciよりも速いけど精度は落ちる。
  • その理由はutf8_unciode_ciは拡張したマッピングをするから (1つの文字が他の文字の組み合わせと等しいか比較する)。

もっと具体的に言ってくれないとわからない・・・

参考サイト

ネットを探すと解りやすく説明したサイトが見つかった。

utf8_general_ci
– 英字の大文字小文字は区別しない。
– 全角半角は区別する。
utf8_unicode_ci
– 英字の大文字小文字は区別しない。
– 全角半角も区別しない。
– さらに濁音、半濁音、ひらがな、カタカナも区別しない。
– 「は」で検索すると「は」「ば」「ぱ」「ハ」「バ」「パ」「ハ」がヒットする。

utf8_general_ciとutf8_unicode_ci – 技術メモ
http://seesaawiki.jp/notepad/d/utf8_general_ci%A4%C8utf8_unicode_ci

問題
select * from member where namae like ‘%サトウ%’;
こんなSQLで、namaeがサトウ、サトウ、さとう、サトウ(一部半角)何でもマッチさせたい!

【MySQL】大文字小文字、全角半角区別しないでマッチする検索をしたい at softelメモhttp://www.softel.co.jp/blogs/tech/archives/1877

[MySQL] ソート後のレコード順位を取得する

特定のレコードが、テーブルをある条件でソートした後に先頭から何番目にあるか、を知るにはどうするか?

そのレコードより前に位置するレコードを数えればよい

たとえば、生徒名簿にテスト得点が記録されているとして、鈴木太郎のテスト順位(得点の高い順)は何番か?

たとえば、商品一覧に発売日が記録されているとして、商品Aは何番目(発売日の古い順)に発売したか?

面倒なのは上に示したように、レコードから順位を逆引きしたい場合だけ。順位からレコードを取得するテーブルの順引きは簡単。普通にテーブルをソートしてLIMITで順位をオフセットとして与えてやれば済む。

やりたいことはできたけど、処理時間に関しては考察が必要かもしれない。

参考サイト

MySQLでソート後の順位を取得する方法を教えて下さい。 例えば、.. – 人力検索はてな
http://q.hatena.ne.jp/1336143424

[MySQL] MySQL Workbenchで既存データベースのER図を表示する

SQL Workbenchを起動。

MySQL-Workbench_00

まずは[MySQL Connections]の[+]アイコンをクリックしてMySQLへの接続を定義する。

Setup-New-Connection_01

データベースサーバーの情報を入力して[OK]ボタンを押下する。

MySQL-Workbench_01

接続が定義されると画面にイルカのセルが追加される。

SnapCrab_MySQL-Workbench_2014-7-22_15-33-46_No-00

画面下側の[Models]の[>]アイコンをクリックして、表示されたメニューから[Create EER Model from Database]を選択。後は画面に表示されるメッセージに従って操作し(ほとんど全てデフォルトのまま)。途中データベースを選択すると、そのデータベースのER図が画面に表示される。

MySQL-Workbench_001

ER図の描画機能はほんの一部で、他にもデータベースの設計・管理に役立つ多彩な機能が備わっているらしい。使い込んで行きたい。

参考サイト

mysqlのWorkbenchで実DBからER図を自動生成 – end0tknrのkipple – web写経開発
http://d.hatena.ne.jp/end0tknr/20110506/1304636491

MySQL WorkbenchでER図を作成する方法
http://promamo.com/?p=1979

[MySQL] ER図を描けるフリーソフトを探す

ER図を書きながらデータベーススキームを設計したい。というわけで、ER図を描けるフリーソフトを探してみた。

まとめページ

ER図を描けるフリーソフト、お薦めは? – 人力検索はてな
http://q.hatena.ne.jp/1129877761

色々なER図作成ツール – 文系プログラマによるTIPSブログ
http://treeapps.hatenablog.com/entry/20110505/p1

ExcelERD

ExcelERDの詳細情報 : Vector ソフトを探す!
http://www.vector.co.jp/soft/winnt/business/se358397.html?y

DBDesigner

fabFORCE.net
http://www.fabforce.net/dbdesigner4/index.php

matalab: フリーのER図作成ソフト「DBDesigner4」がいい!
http://matalab.blogspot.com/2010/12/erdbdesigner4.html

ER図モデリングツール DBDesigner: プログラマの思索
http://forza.cocolog-nifty.com/blog/2004/10/er_dbdesigner.html

ERMaster

ER Master (Eclipse用プラグイン)
http://ermaster.sourceforge.net/index_ja.html

ユカイ、ツーカイ、カイハツ環境!(11):DB設計の神ツール「ERMaster」なら、ここまでできる (1/3) – @IT
http://www.atmarkit.co.jp/ait/articles/1001/21/news128.html

A5:SQL Mk-2

A5:SQL Mk-2 – フリーの汎用SQL開発ツール/ER図ツール
http://www.wind.sannet.ne.jp/m_matsu/developer/a5m2/

「A5:SQL Mk-2」という変態(←褒め言葉)なソフトがあった – そろそろ脳内ビジネスの話をしようか
http://blogs.bizmakoto.jp/noubiz/entry/16683.html

設計書/ER図の出力も。高機能データベースメンテナンスソフトウェア·A5:SQL Mk-2 MOONGIFT
http://www.moongift.jp/2011/11/20111123-3/

データベースを使った開発をする時に便利なフリーソフト
http://blog.satt.jp/article/286580331.html

MySQL Workbench

MySQL :: MySQL Workbench
http://www-jp.mysql.com/products/workbench/

モデリングツールから管理・開発統合環境に進化したMySQL Workbench 6.0 | Think IT(シンクイット)
http://thinkit.co.jp/book/2013/10/21/4571

[MySQL] 外部キー制約を設定してリレーションを頑強にする

MySQL覚え書き。必須じゃないけど考慮しておくといざというときに役に立ちそうな「外部キー制約」。

外部キー制約とは

あるテーブルから別のテーブルを参照するために、別のテーブルのIDを「外部キー」として格納している場合、別のテーブルのIDが勝手に変更されたり削除されたりすると、2つのテーブル間の紐付けができなくなってしまう。これを避けるために、テーブル間の連携で使われる値に一定の条件を設けておくと良い。これを行うのが「外部キー制約」である。

外部キー制約を設定することで

  • 参照する側に挿入されるデータを、参照される側に存在しているデータのみに限定することができる。
  • 参照される側の値を変更した場合には、エラーを表示するか、参照する側のデータを同様の値で更新またはNULL値を挿入することができる。
  • 参照される側の値が削除される場合も、エラーを表示するか、参照する側のデータを削除またはNULL値を挿入することができる。

外部キー制約の設定方法

定義済みのテーブルに対して外部キー制約を設定するには以下のようにする。

更新時と削除時の制約条件はマニュアルを参照のこと。手っ取り早く更新と削除を禁止してエラーとするならRESTRICTと指定する。

外部キー制約を設定しておくことで、例外的なデータベース操作が行われたときのフェイルセーフを向上させることができそうに思える。システムを強固にするために、考慮しておくに越したことはない。

参考サイト

MySQL :: MySQL 5.1 リファレンスマニュアル :: 13.5.6.4 FOREIGN KEY 制約
http://dev.mysql.com/doc/refman/5.1/ja/innodb-foreign-key-constraints.html

今から始める MySQL入門(8):外部キー制約を活用する (1/3) – @IT
http://www.atmarkit.co.jp/ait/articles/0707/17/news113.html

MySQL 外部キー制約(FOREIGN KEY) | MySQL入門~bituse~
http://bituse.info/mysql/17