職業訓練校での半年間

2013/10月中旬から半年間の記録を書き留める予定。
http://android.wktk.so/ があるのを知って開始しました。

カテゴリ: MySQL


1限目:てきとうに復習(join関連)

2限目:テーブル名を変更するエイリアス

3限目以降:PHP/MySQLの課題
    →モデルの写真撮影会のスケジュール登録
      K氏、全て託しました・・・!
      説明用:http://beauty.hotpepper.jp/CSP/bt/reserve/afterCoupon

[機能概要]
◎ログイン(Pear::Auth使う?)
◎新規会員登録(メール登録or直登録)
 ※メールの場合、送られてくるメールにDBに登録したアカウントと紐付けるパラメータつける
◎カレンダー
http://beauty.hotpepper.jp/CSP/bt/reserve/?storeId=H000264750をベースにする?
 ※「このクーポンで予約する」ボタンで遷移した先。
 #先月・今月・来月の表示。
○モデルの指定&検索
○モデル側の登録ページ
△お気に入りモデルの登録
 (スケジュールが登録されるとお知らせメールが会員に送られる)
○セキュリティ対策(下記のあたり)
 クロスサイトスクリプティング
 パラメータの改ざん
 クロスサイトリクエストフォージェリ
 参考:http://www.itmedia.co.jp/enterprise/articles/0506/16/news030.html


2限目分
まず下記4テーブル作成します。
#右側のカラム要素表示は「SHOW CORUML FROM テーブル名」で表示したものです。

【products】
WS000138WS000139

【supplier】
WS000008WS000007

【telbook】
WS000002WS000001

【order】
WS000005WS000006


さて本題。

「テーブル.カラム名」と記載する項目が多いと
コーディングするの面倒ですよね?
それをテーブル名を指定する部分で「order o」と別名を記述することで
記述量を減らすことが出来ます。
select o.farm_name, s.address, s.rep_name,t.tel,
p.name, p.price, o.arrival_date, o.order_num,
sum(order_num) AS stock, p.etc
FROM orders o
LEFT JOIN products p using(name)
LEFT JOIN supplier s using(farm_name)
LEFT JOIN telbook t using(rep_name)
結果
WS000009


上記ソースを改変して「GROUP BY ~ HAVING~」を追加。
※表示項目が少し変わってるので注意
select 
o.farm_name, s.address, s.rep_name,
t.tel,p.name, p.price, o.arrival_date, o.order_num,
sum(order_num) AS stock, p.etc
FROM orders o
LEFT JOIN products p using(name)
LEFT JOIN supplier s using(farm_name)
LEFT JOIN telbook t using(rep_name)
GROUP BY name
HAVING stock<30 
WS000010


ちょい説明詳しくします。
まずGROUP BY と HAVING抜いた状態だとこうなります。
order_numとstockの値が違ってて「んん?」ってなると思います。
WS000011
「GROUP BY name」と付けるとstock=70の内訳が判明します
WS000012
次に「HAVING」。stockが30のものは「津軽ファーム」のみなので、
「HAVING stock<30」とすると、1行だけが表示されます。
WS000010

課題の割り振りはざっくり決めたけど、テーブルの数、必要要素とか決めてない\(^o^)/
1人で決めるだけなら早いんだけどね、、、




同じ訓練生K氏のブログをチェック。

やはり正規化を続けて実習だったのか。
んー基本情報を取らないのであれば現時点ではスルーでいいかな。

というのも、新入社員にいきなりテーブルの設計投げてこないです。
基本的にプロジェクトで担当する場合、はじめは下記のどちらかになります。
#信頼ができてきたらorPLとして雇われたら設計も合わせて担当になるけど。
・PLが設計/構築
・詳細設計されたものを構築する(設計担当というか要件定義の人がいる場合こっち)

【結合コマンド各種】
条件下のもとにテーブル)を結合します。
Web系での主な使い道は画面表示(SELECT)。時々日々のデータ保存など(CREATE TABLE)。

内部結合(INNER JOIN)
http://www.pursue.ne.jp/jouhousyo/SQLDoc/select21.html

外部連結(LEFT JOIN, RIGHT JOIN)
http://www.pursue.ne.jp/jouhousyo/SQLDoc/select22.html

自然結合(NATURAL JOIN)
http://sasuke.main.jp/natural.html

・・・内部結合と自然結合、「SELECT * from ~」 の*部分をいじれば同じような動きをします。
条件を明示的に宣言するINNER JOINが多く用いられてると思います。


【using】
http://gooddays1.blog37.fc2.com/blog-entry-308.html



【備考】
http://careerzine.jp/article/detail/1407


「今30%くらいはDatabase触れてるんじゃないかな~」
「いやいや、基本4つの構文やった程度じゃ10%前後っしょ」って突っ込みそうでした。

だってデータベースの機能(バックアップファイルとかindexファイルとか)や
データベースやテーブルの要素を変えるalterやデータ削除のtruncate,ユーザ作成の・・・(略
などなど覚えることたっぷりですからね(-_-;)
Oracleに至ってはPL/SQLっていうSQLにJavaみたいなプログラミング要素も出てきますし。おすし。
そいや習得に時間かかるのはわかるけど
ネット介したプログラム作ってる人でデータベースの知識ほぼなしって
面接官からしたら「使えねーなコイツ」って烙印押されるんですがそれは・・・


無題
<(念)Databaseは奥が深い



1限目:
基礎4つのうちSELECT,INSERT、そしてCREATEでテーブル作りました。
下記のような感じで作りました。
 WS000133WS000134



2限目:
私の参考書をもとにちょっとレベルアップ。
【リピート(繰り返し)】
※REPEAT関数を用いて、rateの数字に応じて★を表示
select REPEAT('★',rate)as rates from test1.study1
WS000136
 
【テーブルコピー】
※study1のテーブルとまったく内容が同じstudy2というテーブルを生成
CREATE TABLE study2 as SELECT * FROM study1


【カラムの変更】
※100->150に変更する
ALTER TABLE study2 MODIFY title VARCHAR(150)
WS000137


【テーブル削除】
drop table study2



【AUTO_INCREMENT】
後から変更する場合は下記が無難。
●truncate
●AUTO_INCREMENTが付与されているカラムを削除
 ->カラムの追加&AUTO_INCREMENTを付与する。
 http://weblogs.tail-lagoon.com/WebPC/2008/03/18/15/

データがおかしくなった時にSQL発行して補完することがあるけど、
これでいける?
http://d.hatena.ne.jp/IT7C/20120827/1346028253
 
ただまぁ不整合が起きると怖いから重複項目については
物理削除せず論理削除で対応。
(=deleteせずフラグで制御する。

オートインクリメント振ってなければ、物理削除してもOKといえばOKだけど
そもそも商用での扱い上、物理削除はやはりおススメされてないみたい。
=オートインクリメントの再振りは考えなくてOK
http://okwave.jp/qa/q1934291.html
http://purazumakoi.hatenablog.com/entry/2013/08/14/114035

客<「削除したやつ、やっぱ戻して!」

コレよくあるけど物理削除を選んでると、復旧が手間ですね。
http://purazumakoi.hatenablog.com/entry/2013/08/14/114035



3限目~5限目:
正規化について
http://www.kogures.com/hitoshi/webtext/db-seikika/
http://www.atmarkit.co.jp/ait/articles/0605/11/news124.html


↑を簡略的にいくと
初級システムアドミニストレータ 正規化 過去問題 解説が分かりやすいです。

 
4・5限目は問題を解いてました
http://www.pursue.ne.jp/jouhousyo/sysadSeikika/sysadSeikika_Q.htm

問い4だけはむーりー・・・。
あとはデータとか文言だから何とかなるけどさぁ。。


【備考】
jsp/servlet@O/Rマッパー
http://d.hatena.ne.jp/kotatuneko24/20120902/1346571365

 

79,80日目は体調不良(80日目は土曜だから休みだと思ってた)だったので飛んでます。
 dropboxの中身をみた感じは復習だった模様。

【79日目】
下記チャットシステムの答え合わせ(↓を参照)


【79日・80日】
 スケジュール表@Lesson36-38(表示・登録・削除・修正)

 
そして今日も課題
スケジュール表のレベルアップ版
指定カラム&昇順or降順をセレクトボックスから選択して
並び替えボタンを押したらその順序に並び替えた結果を再表示。
価格.comの製品一覧をイメージしてください。


 
構築のイメージはついたから今日は課題未着手。 

それよりも会社からの出向先より採用取れたので
SQLというかRDBMSの勉強してました。
基礎からのMySQL 改訂版 (プログラマの種シリーズ SE必修! )
西沢 夢路
ソフトバンククリエイティブ
2012-05-01



PL/SQLはOracleのみの機能なので、
別途お勉強予定です。。。
プロとしてのOracle PL/SQL入門 改訂版 (Oracle現場主義)
アシスト教育部
ソフトバンククリエイティブ
2010-03-18



Softbankシリーズ多いな、俺(~_~)
毎度おなじみのtechcoreさんでサクッと勉強するのもありだけどw

そして今どきServletを使う現場とはね、、、
http://servletmania.blog137.fc2.com/
ネットが使えない現場なので、ファイル入出力も頭に入れていこう。。

【自分用メモ】
入社日が決まったら学校に退校日を連絡する
(用紙の記入がいる)


 

雪やばす\(^o^)/
また今週2度目の雪かきとか嫌だわぁ。。。

話し変わりまして、就活してないけど終わったっすw
面接もせず、前の会社より好条件なのはいいね★

てか、よくよく考えてみたらオペレータや1/3以上を占めてたから
その割りを食えば給与安くもなってたわな。


さて授業。
昨日作ったデータベース名をしょっぱなから変更したら
「tst1」に権限追加できない。。。(アカウントが既に存在するから「させねぇよ!」、と)
なのでSQL文で直接追加。
GRANT ALL PRIVILEGES ON test1.* TO tst1 IDENTIFIED BY  'tst1' WITH GRANT OPTION 
---------------------------------------------------------------------------------
【ALL PRIVILEGES】:全権限付与(アクセス、参照、変更、登録など)
【ON test1.*】 データベース[test1]配下にある全てのテーブル
【TO tst1】権限を付与するアカウント(新規でも可)
【IDENTIFIED BY  'tst1'】パスワードは「tst1」
【WITH GRANT OPTION】対象テーブルの権限書き換えを許可
---------------------------------------------------------------------------------

下記サイト様に助けてもらいました\(^o^)/
http://sasuke.main.jp/useri.html

基礎を理解しておけば今後の理解早くなるのは間違いない!
特集:基礎から理解するデータベースのしくみ

さてPHP/MySQLによるコラボのお時間です。
JAVAと違ってodbcの設定がなくて楽だわぁ・・・。

WS000119

登録押下後、http://localhost/phpmyadminへアクセスして、
test1/scheduleに下記のようにデータが登録されてれば成功です!!
WS000120

★36-1.php
<?php
//selectboxに値をセットする
function showOption($start, $end, $step=1){
  for($i=$start; $i<=$end; $i+=$step){
    print('<option value="'.$i.'">'.$i.'</option>');
  }
}
?>
<!DOCTYPE html>
<html>
<head>
  <title>PHP入門教室</title>
</head>
<body>
<h3>スケジュール登録</h3>
<form method="POST" action="schedule_input.php">
  <div>
    <label for="title">予定名:</label><br />
    <input type="text" id="title" name="title" size="50" maxlength="255" />
  </div>
  <div>
    日付:<br/>
    <select id="year" name="year" >
      <?php showOption(2012,2020); ?>
    </select>
    <label for="year">年</label>
    <select id="month" name="month" >
      <?php showOption(1,12); ?>
    </select>
    <label for="month">月</label>
    <select id="day" name="day" >
      <?php showOption(1,31); ?>
    </select>
    <label for="day">日</label>
  </div>
  <div>
    開始時間:<br />
    <select id="hour" name="hour" >
      <?php showOption(0,23); ?>
    </select>
    <label for="hour">時</label>
    <select id="minute" name="minute" >
      <?php showOption(0,59,15); ?>
    </select>
    <label for="minute">分</label>
  </div>
  <div>
    <label for="memo">備考</label><br/>
    <textarea id="memo" name="memo" rows="4" cols="40"></textarea>
  </div>
  <input type="submit" value="登録" />
</form>
</body>
</html>


★schedule_input.php

<?php
try{
  //DBへアクセス
  $db = new PDO('mysql:host=localhost;dbname=test1;charset=utf8',
    'testuser','testpass');
  //どのカラムにデータを登録していくか指定。Value側は「//値セット」部分の布石。
  $play = $db->prepare('INSERT INTO schedule(title,date,time,memo)
    VALUES(:title,:date,:time,:memo)');
  //値のセット
//INT型の場合、変な挙動をすることがあるので、PDO::PARAM_INTを第3引数につける
//(今回はINT型使ってないので、文字用の「PARAM_STR」にしてる $play->bindValue(':title', $_POST['title']); $play->bindValue(':date', $_POST['year'].'/'.$_POST['month'].'/'.$_POST['day']); $play->bindValue(':time', $_POST['hour'].':'.$_POST['minute'], PDO::PARAM_STR); $play->bindValue(':memo', $_POST['memo']); //実行? $play->execute(); //接続解除 $db = NULL; //ここでアクセス成功したか失敗したかすぐ遷移して分からないのでパラメータつける $access = 'success'; //接続や処理に失敗したらココでキャッチ }catch(PDOException $e){ $access = 'failed'; die('エラー:'.$e.getMessage()); } //この処理を裏で行ったら元のページへ戻す。 header('Location: http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']).'/36-1.php?'.$access);

ちなみに、PDOにはprepare以外にも直接SQL文を指定するexec()もある。
http://www.php.net/manual/ja/pdo.exec.php

試しに「words」というテーブルをcreateするものを作ってみた。
★test1.php
<?php
try{
$db = new PDO('mysql:host=localhost;dbname=test1;charset=utf8','testuser','testpass');
$db->query('SET NAMES utf8');

//データベースを定義する
$create_query = <<<__SQL__
  CREATE TABLE words(
    word_id INT PRIMARY KEY AUTO_INCREMENT,
    title TEXT,
    body TEXT
  );
__SQL__;
$db->exec($create_query);
print('テーブルを作成しました');
}catch(Exception $e){
  print('失敗'.$e->getMessage());
}
?>




このページのトップヘ