第15回 更新処理を覚えよう - MySQL講座

PHP講座 HTML×CSS 初級編

サカイ先生のMySQL講座

Lecutures on PHP

第15回 更新処理を覚えよう (その3)

 このエントリーをはてなブックマークに追加

一律5%値上げ!

  • じゃぁ次は更新をやってみようか。これも簡単な課題を与えよう。うちの商品に「韋駄天」シリーズっていうのがあるんだ。商品名が「韋駄天」で始まっている。この韋駄天シリーズが原料高騰につきすべて基本価格(base_price)が5%値上げすることになった。そんなシナリオでの更新をやってみよう。
  • データベース的な言い方に変えると、「items テーブルの name カラムが "韋駄天" で始まるものの base_price カラムを 1.05 倍する」ということですね。
  • その通り。なお、実際には価格変更のためにこんな乱暴な更新方法をすることはまずないから、あくまでも練習用のシナリオだと思っておいてね。
  • わかりました。 ではまず現在の「韋駄天シリーズ」の登録状況を items テーブルで見てみます。
mysql> SELECT * FROM items WHERE name LIKE "韋駄天%";
+-----+----------+------------+
| id  | name     | base_price |
+-----+----------+------------+
| 239 | 韋駄天01 |      10620 |
| 240 | 韋駄天03 |      10270 |
| 241 | 韋駄天07 |       2210 |
| 242 | 韋駄天17 |      11850 |
| 243 | 韋駄天25 |       3510 |
| 244 | 韋駄天31 |       6010 |
| 245 | 韋駄天36 |      10170 |
| 246 | 韋駄天44 |       6640 |
| 247 | 韋駄天50 |       3550 |
| 248 | 韋駄天54 |       5320 |
| 249 | 韋駄天64 |       7620 |
| 250 | 韋駄天66 |       3270 |
| 251 | 韋駄天70 |       3250 |
| 252 | 韋駄天76 |       4770 |
| 253 | 韋駄天82 |       4610 |
| 254 | 韋駄天86 |      11040 |
| 255 | 韋駄天89 |       6460 |
| 256 | 韋駄天97 |       7400 |
+-----+----------+------------+
18 rows in set (0.01 sec)
  • 18種類あります。2,000円台から11,000円台まで幅広いラインナップですね。

この base_price を更新するには、UPDATE 文を使うのですね。

UPDATE テーブル名 
   SET カラム=値
 WHERE 条件

テーブル名は items、 条件はさっきSELECTしたのと同じでいいので、これでいいかな。

mysql> UPDATE items SET base_price=base_price*1.05 WHERE name LIKE "韋駄天%";
Query OK, 18 rows affected (0.05 sec)
Rows matched: 18  Changed: 18  Warnings: 0
  • そう。 base_price = base_price*1.05 というのが更新のポイントだね。もともとの値を1.5倍して base_price カラムに格納(更新)するというわけだ。
  • では、さっき先輩に誉められたので(笑)、今回も更新後のデータの確認をします。
mysql> SELECT * FROM items WHERE name LIKE "韋駄天%";
+-----+----------+------------+
| id  | name     | base_price |
+-----+----------+------------+
| 239 | 韋駄天01 |      11151 |
| 240 | 韋駄天03 |      10784 |
| 241 | 韋駄天07 |       2321 |
| 242 | 韋駄天17 |      12443 |
| 243 | 韋駄天25 |       3686 |
| 244 | 韋駄天31 |       6311 |
| 245 | 韋駄天36 |      10679 |
| 246 | 韋駄天44 |       6972 |
| 247 | 韋駄天50 |       3728 |
| 248 | 韋駄天54 |       5586 |
| 249 | 韋駄天64 |       8001 |
| 250 | 韋駄天66 |       3434 |
| 251 | 韋駄天70 |       3413 |
| 252 | 韋駄天76 |       5009 |
| 253 | 韋駄天82 |       4841 |
| 254 | 韋駄天86 |      11592 |
| 255 | 韋駄天89 |       6783 |
| 256 | 韋駄天97 |       7770 |
+-----+----------+------------+
18 rows in set (0.00 sec)
  • えーと、いくつかピックアップして見てみましたが、ちゃんと5%増しになっているようですね。バッチリです!
  • いま太郎君は「確認」をしたよね。 確認というのは期待した処理が実施されたかを確かめるほか、期待していないことは起こっていないということにも気をつかった方がいい。ちょっとわかりにくいかな。言い方を変えると、太郎君、確認作業で「オッケーじゃなかった」ってどういう状態だか考えてみてごらん。
  • はい。まず今確認したように、1.05倍になっていなかった場合ですね。値が変わってなかったり、何故か減っちゃったり、何故か値が変わっていないのがあったり。・・・・で、期待していないこと、、ですか。。 あ!! 韋駄天以外の値が変わっちゃってる可能性ですね!
  • そうなんだ。以前話したかもしれないけど、WHERE条件の指定間違いなどで大切なデータを滅茶苦茶にしちゃう事故って、特に初心者時代に起こしてしまうことも多いから、自信を持って「確実に正しく更新した」ことを確認する方法は早い時期から身につけておきたいね。
  • 今回の場合だと、どのようにして確認したらいいですか? items テーブルは件数が多いからこのまま全部を単純に比べるのはたいへんそうです。
  • そうだな。。特定のシリーズだけピックアップして比べる方法もあるし、、僕なら「韋駄天以外のpriceは変更されていない」ことを確認するために、更新の事前と事後にそれぞれ以下のSQLを発行して、変化がないことを確認するかな。
mysql> SELECT SUM(base_price), COUNT(*) FROM items WHERE name NOT LIKE "韋駄天%";
+-----------------+----------+
| SUM(base_price) | COUNT(*) |
+-----------------+----------+
|         3807050 |      618 |
+-----------------+----------+
1 row in set (0.01 sec)
  • なるほど! 韋駄天以外の商品の base_price の合計値を取っておけば、誤って値が変更されているものがあっても気づくというわけですね!
  • 複雑な更新の場合プラスマイナスでたまたま合ってしまうケースもあるかもしれないけど、今回の更新文ならまずこれで誤った更新に気がつくことができるね。

ちなみに COUNT(*) は別に見る必要もないのだけど(今回の base_price を変更する UPDATE で件数が変わることはないので)、一応「何件で幾らかぁ」と見えたらいいかな、という程度で出力させてみてるんだ。

  • それにしても、怖い文ですね。あんな短い命令で、18件とかそんなデータが一気に変わってしまうなんて。。
  • そうだね。うっかりWHEREをつけ忘れると全件更新されるから、実行前には SELECT で条件が合っていることを確認するなど、実行にあたっては慎重になりたいね。 じゃぁ、もっと怖い命令の話に移ろうか。

  



Pick Up Q&A

Q
負荷時のmysql_connect()エラー
 このエントリーをはてなブックマークに追加 
A
これはPHPというよりOSまたはMySQLのコミュニティで質問されたほうがいいと思います。 ぱっと思いついた範囲で記すと MySQL等のDBに「ある時点において同時に接続可能なクライアントの最大数」に制限があるよう...

>>続きを読む

今回のような実践的な経験がエンジニアのキャリアに繋がると思います。是非サービスを成功させて下さい!

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)