d. データベース設計演習(4/4)
2017年度資料
CakePHP の bookmark チュートリアルの演習は前回までで終了したものとする。
先回の演習の応用例についてコメント: 前回の資料に応用例を記載したので参照する。
今回から、期末課題の制作を進める。
期末課題の提出物
・ fp フォルダ を zip ファイルにアーカイブして Webclassにアップロード
・ データベースのエクスポートファイルを Webclassにアップロード
の2点を期日までに提出する。
■提出〆切
・7月31日(月)
間に合うように取り組むこと。締切日当日に 0からスタートでは難しいと予測。こまめに相談に来ること。
データベースの設計に問題があるか不安な受講生は、確認を求めてください。
■期末課題採点基準:(30点満点+)
・データベースの設計 正規化 ・ テーブル間の関係 (20点)
・サンプルデータ (5点)
・独自の工夫(カスタマイズビューの作成・操作メニューの作成・Webリンク・並べ替え・集計機能・セキュリティなど)(5点~)
PHPのコード、モデルとビューとコントローラーは、 cake bake で自動的に作成してもよい。
テーブルが1つしかないデータベースの制作でもかまわないが、複数テーブルのデータベースに対して、評価を半減する。
データベースの構造についての減点分を、独自の工夫でカバーするように取り組む。
ログイン認証やセキュリティなど高度な設定については、各自で調べて取り組むことする。
CakePHP のサイトのほか、Webに豊富に情報がある。
https://book.cakephp.org/3.0/ja/index.html
作業例
bookmarkチュートリアル を作成したときと同様に、CakePHP用のフォルダを作成しCakePHPを設定する。
※レポートフォルダの fp(期末課題用CakePHP)を丸ごとxamppのhtdocsにコピーして、名前を修正 fp としておく。
期末課題の作成デモ:
ボードゲーム貸し出し管理データベースの作成
作業の概要:
d:\xampp\htdocs\ に cakephpのフォルダをレポートフォルダからコピーして、フォルダ名を fp に変更する。
PHPMyAdminで 期末課題データベースを作成する。
PHPMyAdminの新規テーブル作成 か SQL コマンドで、テーブルを作成する。
cake bake コマンドを使用して、モデル、コントローラー、ビューの生成を行う。
・データベースを切り替える。
CakePHPとMySQLの接続設定を編集
vscode で fp/config/app.php
を編集。データベースの名前は、各自の企画のものを指定する。
232~234行目付近。赤文字の部分、データベースのユーザ名やパスワードは例のとおりに設定する。データベース名(太字)の部分は各自のデータベースに合わせて修正する。
return [
// More configuration above.
'Datasources' => [
'default' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'localhost',
'username' => 'root',
'password' => '',
'database' => 'boardgame',
'encoding' => 'utf8',
'timezone' => 'UTC',
'cacheMetadata' => true,
],
],
// More configuration below.
];
保存する。
・xampp の phpMyadmin でデータベースとテーブルを作成する。
データベース名 と 文字コードを指定して作成
テーブルをSQLで作成:
※ CakePHPの規約 テーブル名は 複数形 を指定する(単語の末尾に s)。 フィールド名は単数形を指定する。
CakePHPによる開発で使用する テーブル設計のコツ
以下の規約に従うと、苦労が少ない。
・テーブル名は 英単語 の 複数形 を使う
・テーブル名とフィールド名には PHPやMySQLの予約語 を使用しない。
使用できない単語の例) for select list character release など
・テーブル名は 単語を2個以上使わない。どうしても2個以上の単語で名前をつける際は、スネークケース ( _ で単語をつなぐ)
・フィールド id を主キーとして持つ。auto_incremental 設定もしておく。
・フィールド名は 単語を2個以上使わない。どうしても2個以上の単語で名前をつける際は、スネークケース ( _ で単語をつなぐ)
・外部キーをフィールドとして持つ場合、別のテーブル名(複数形)のidフィールドを参照するものとする。
フィールド名は 別のテーブル名の単数形_id とする。
・テーブル間の多対多をあらわすテーブルの名前は テーブル名1_テーブル名2 とする。テーブル名は複数形のままつかう。テーブル名を並べる順番はアルファベット順。
ゲームテーブル: ID ゲーム名 説明 を登録
create table games (
id int not null auto_increment primary key,
name varchar(20) not null,
description text,
created datetime,
modified datetime
);
※ 赤文字の部分、テーブル名 games(複数形)やフィールド名 name (単数形)は、各自の企画に合わせて変更が必要。
※ id フィールドは必須。上記の例同様に各自の企画のテーブルにも id フィールドを設定する。
利用者テーブル: ID 利用者名 を登録
create table users (
id int not null auto_increment primary key,
name varchar(20) not null,
created datetime,
modified datetime
);
※ 上記以外のフィールドを追加してもよい。
貸出テーブル:ゲームID 利用者ID 日付 を記録 ※規約に従っていないので、来週にコードを修正して対応する。
create table games_users (
user_id int not null,
game_id int not null,
date datetime,
PRIMARY KEY (game_id, user_id),
FOREIGN KEY user_key(user_id) REFERENCES users(id),
FOREIGN KEY game_key(game_id) REFERENCES games(id)
);
※ テーブル名 games_usersは このテーブルは games テーブルと users テーブルの多対多の関係を記録するテーブルであるので、 テーブル名をアルファベット順に並べて _ でつないだ名前をつける(CakePHPの規約)。
※ 外部キーの設定 user_id や game_id の部分は、テーブル名を単数形にして _id を付加したフィールド名を用いている(CakePHPの規約)。複合主キーの設定(PRIMARY KEY)や、外部キーの設定(FOREIGN KEY)の設定は、対応するフィールドに応じて名前を変更すること。
↑
貸し出しテーブルの設計上の問題点:
bookmarkチュートリアルの設定を流用しているので発生
ゲームを返却した場合は、貸し出し記録を削除する。貸し出し履歴は保存されない。仕様。
user_id と game_id が複合キーで主キーとなっている。ゲームと利用者は多対多の関係である:
1人で複数のゲームを借りることが出来る
1つのゲームを複数の利用者で共有して借りることが出来る
ゲームを返却するには、借りた利用者全ての記録を削除する必要がある
ある利用者が借りているゲームを返却することなくもう一度借りることは出来ない。 ←これはOK
※テーブルの構造に関する CakePHPの規約
・テーブルの外部キーのフィールド名は、参照先テーブル users の主キーが id なら user_id という名前を指定する。
【参照】 CakePHPの命名規約まとめ http://qiita.com/nvtomo1029/items/1147b8796af3d906c3a9
サンプルデータの入力
各テーブルに動作確認用のデータを入力する。
日付と時刻の入力には、 関数の NOW() を指定するとよい。現在の日付と時刻を入力できる。
以上で、課題作成の要求水準25点クリア
残り 5点 (30点満点) は、各自の工夫を評価する。
課題提出
・期末課題のデータベースのER図
xampp のデザイナ画面を利用して、スクリーンショットを撮影して提出。画像を Webclass にアップロード。
デザイナ画面は、テーブルの関連が分かるように整理してからスクリーンショットを撮影すること。
・データベースのスナップショット
xampp から データベースをエクスポートする。
127.0.0.1.sql というファイルがブラウザにダウンロードされる。そのまま Webclass にアップロードする。
2016年度資料
メモ:
データベース mytest の提出について。
phpMyAdmin から データベース mytest学籍番号 を エクスポートして レポートフォルダ に提出。
ページの一番下に、【裏技】解説があります。
お勧めのテキストエディター: sublime text 3 。ただし日本語入力がインライン化されていないので要対応。
やり方→proxy の設定が必要 http://keidrun.tumblr.com/post/73152267421/tipssublime-text-sublime-text-3%E3%81%A7package
やり方→http://keidrun.tumblr.com/post/73033053898/tipssublime-text-sublime-text
期末課題の作成:
作成ファイル
Controller
xxxxController.php -> scaffold のみのシンプルなものでよい。
Model
xxxxxxx.php
テーブルが2つ以上ある場合、テーブル間の関係(1対多など)を、アソシエーション機能で設定しておくこと。
今回の授業では、なるべく楽をして課題を作成する方法について解説予定。
ポイント1 CakePHP の設定を簡単に済ます。 Blogシステムの設定を流用する。
ポイント2a PHPプログラムをしない。 Controller と Model を必要最低限で用意する。 ビューは scaffold のレイアウトを利用する。 今回解説する方式。
ポイント2b PHPプログラムをしない。 CakePHP の bake コマンドで、必要なコードを自動生成する。 次回解説する方式。
ポイント3 CakePHPの解説サイトをネットで検索、CakePHP + やりたいこと(例:ユーザ認証、ページ付け、画像投稿、カレンダー、など)のキーワードでヒットした記事を参考にする。
■期末課題の提出物
blog を作成したときと同様に、データベース名のフォルダを作成し、CakePHPを準備する。
・学籍番号+データベース名 のフォルダ
例) 3113999boardgame
・学籍番号+データベース名.sql のエクスポートファイル
例) 3113999boardgame.sql
の2点を期日までに提出する。
■提出〆切
・7月31日(日)
間に合うように取り組むこと。締切日当日に 0からスタートでは難しいと予測。相談に来ること。
■期末課題採点基準:(30点満点+)
・データベースの設計 正規化 ・ テーブル間の関係 (20点)
・サンプルデータ (5点)
・独自の工夫(カスタマイズビューの作成・操作メニューの作成・Webリンク・並べ替え・集計機能・セキュリティなど)(5点~)
ビューとコントローラーは、 scaffold で単純に作成してもよい。
テーブルが1つしかないデータベースの制作でもかまわないが、複数テーブルのデータベースに対して、評価を半減する。
データベースの構造についての減点分を、独自の工夫でカバーするように取り組む。
ログイン認証やセキュリティなど高度な設定については、各自で調べて取り組むとする。
CakePHP のサイトのほか、Webに豊富に情報がある。
http://book.cakephp.org/2.0/ja/getting-started.html
作業例
新規に CakePHP を htdocs に設定して課題を作成してもよい。
しかし、設定の手間を省くため、
ここでは、第10~12回(a. b. c.) で作成した blog システムをコピーして修正しながら作業を進める。
ボードゲーム貸し出し管理データベースの作成
d:\xampp\htdocs\ に cakephpのフォルダを新規にコピーして、フォルダ名を期末課題の名前に変更する。
PHPMyAdminで 期末課題データベースを作成する。
PHPMyAdminの新規テーブル作成 か SQL コマンドで、テーブルを作成する。
bake コマンドを使用して、database.php、モデル、コントローラー、ビューの生成を行う。
以下は、2015-2016年度版の方法
・D:ドライブのXAMPP のドキュメントルート(htdocs) にある、blog フォルダをコピーして名前を変更する。
blog → boardgame
フォルダの名前は、各自の企画のものを指定する。
・データベースを切り替える。
D:\XAMPP\htdocs\boardgame\app\Config の database.php を編集
'database' => 'blog',
を
'database' => 'boardgame',
に変更。 データベースの名前は、各自の企画のものを指定する。
・CakePHPの debugレベルが 0 になっていたら、 2 に戻し(システム完成後 0にする)、
次の Blog を参考に、モデルのキャッシュファイルを削除する。
http://www.hangout.co.jp/blog/archives/145
例)
D:\XAMPP\htdocs\boardgame\app\tmp\cache\models にある、
myapp_cake_model_default_データベース名_テーブル名
のファイルを削除。
・データベースとテーブルを作成する。
データベース名 と 文字コードを指定して作成
テーブルをSQLで作成:
※ CakePHPの規約 テーブル名は 複数形 を指定する(単語の末尾に s)。 フィールド名は単数形を指定する。
ゲームテーブル: ID ゲーム名 説明 を登録
create table games (
id int not null auto_increment primary key,
name varchar(20) not null,
description text
);
利用者テーブル: ID 利用者名 を登録
create table users (
id int not null auto_increment primary key,
name varchar(20) not null
);
貸出テーブル: 利用者ID ゲームID 日付 を記録
create table rentals (
id int not null auto_increment primary key,
user_id int not null,
game_id int not null,
date datetime
);
※テーブルの構造に関する CakePHPの規約
・テーブルの外部キーのフィールド名は、参照先テーブル users の主キーが id なら user_id という名前を指定する。
・複合キーはテーブルに持たせない。
【参照】 CakePHPの命名規約まとめ http://qiita.com/nvtomo1029/items/1147b8796af3d906c3a9
サンプルデータの入力
各テーブルに動作確認用のデータを入力する。
Modelの準備:
※ ファイル名の先頭と単語の先頭は大文字。単数形。
Game.php
アソシエーションの設定。ゲーム と 貸出 は 1対多 の関係。 あるゲームは何度も貸し出可能。$hasManyを指定する。
<?php
class Game extends AppModel {
public $hasMany = 'Rental';
}
User.php
アソシエーションの設定。利用者 と 貸出 は 1対多 の関係。 ある利用者はゲームを何度も借りられる。
<?php
class User extends AppModel {
public $hasMany = 'Rental';
}
Rental.php
アソシエーションの設定。貸出とゲーム、貸出と利用者 は、多対1の関係。 $belongsToを以下のように指定する。
<?php
class Rental extends AppModel {
public $belongsTo = array(
'User', 'Game'
);
}
【参照】 モデルのアソシエーション設定のまとめ http://qiita.com/rana_kualu/items/1be3457e7b58950399b9
Controllerの設定:
ビューは作成せずに scaffold を利用して、モデルとデータベースの接続を確認する。
※ ファイル名 コントローラー名は複数形(モデル名の末尾にsがつく) 単語の先頭は大文字。
GamesController.php の準備。
<?php
class GamesController extends AppController {
public $scaffold;
}
以下のURLをブラウザで表示確認: urlの一部がコントローラー名に対応していることに注意。
http://localhost/boardgame/games/
UsersController.php と RentalsController.php も同様に設定し、動作を確認する。
※cakePHPの scaffold 機能では、テーブルのフィールドに name か title があると、その値をレコードの表示名として利用するようになっている。
上記の表示例では、 Rentals テーブルのレコードで、 user_id と game_id の部分が、 users テーブル と games テーブルの name フィールドの値で表示されている。
※※ scaffoldで、テーブルの表示名用フィールドを name や title 以外に変更するには、 cakePHPの モデル を修正する。
例)
モデルに以下の行を追加
public $displayField = 'custom_name';
↑で'custom_name' の部分を、scaffoldのプルダウンメニューで表示される項目のフィールドに修正する。
以上で、課題作成の要求水準25点クリア
残り 5点 (30点満点) は、各自の工夫を評価する。
例えば、
検索: CakePHP Scaffold カスタマイズ
で、スキャフォールドの修正方法を探して、設定する。 表示項目の 選択(不要なものをOFF) や、表示順の並べ替えなど。
(ヒント) scaffold 機能を利用したままで、カスタムビューを作成せずに工夫できる内容を考える。
・デバッグモードを 0 にして、SQLの実行文や、エラーを非表示に設定する。(本番運用環境設定)
・D:\XAMPP\htdocs\boardgame\app\View\Layouts の default.ctp を編集して、Webページの
ヘッダーやフッター、背景のデザインを修正する。 HOME のリンク先をTOP ページに変更など。
・ルーティングの設定
例)
http://localhost/boardgame/ の短いURLで、 http://localhost/boardgame/rentals/ を表示するように、
app/Config/routes.php を修正。
・ データの表示順の指定
例)
上のボードゲーム貸出し管理DBで、貸し出し状況の一覧表示を 日付の降順にするには、Rental.php モデルを修正する。
$order に モデル名 . 並べ替えるフィールド名 ASC(昇順) または DESC(降順を指定)
class Rental extends AppModel {
public $order = "Rental.Date DESC";
・表示項目の設定
MySQLで表示項目を制限するテーブルのビューを作成する。
例)
ゲームテーブルの表示で、id name description の3項目の表示を、 id name だけの表示に制限する。
MySQLに、 games に対するビュー game2s を作成して登録する。
create view game2s as
SELECT `games`.`id`, `games`.`name`
FROM `games`
ORDER BY `games`.`name` ASC
CakePHP に、モデル Game2 と コントローラー Game2sController を作成する。
※ Scaffold の利用したビューの作成では、 モデルの id フィールドを省略するとエラーになる。
チャレンジ: 以下の作業は、調査・デバッグで、かなりの時間を必要とします。時間に余裕がある場合は挑戦してみましょう。
・ビューの作成
Blogシステムの作成と同様に、ビューを作成する。 Scaffold をオフ にして、PHPのプログラムで表示画面を作成する。
・ログイン画面の作成
CakePHPで、ログイン認証を設定する方法を調べ、ログイン画面を作成する。
・WebAPIの利用
データベースに登録したフィールドの内容と、 WebAPIを組み合わせ、ビューで利用する。
例) 位置情報、商品画像、etc
裏技1: blog データベース全体をエクスポートし、別のデータベースとしてインポートできるかもしれない。そうした場合、blogシステムのクローンが作成される。テーブルのフィールド名を再設計すれば、blogシステムを改造して、期末課題が作成できるかもしれない。
裏技2: CakePHP の bake コマンドで、phpやctpのコードを自動生成。楽ちんコースはこちら。