送金が途中で止まったら
データベースのデータを変えるには、INSERT で追加し、UPDATE で書き換え、DELETE で削除します。そして、トランザクションを使うと、いくつもの変更を「全部成功か、全部なかったこと」にできます。
電子マネーで友だちに500円を送る場面を考えます。自分の残高が減ったあとで止まり、相手の残高が増えなかったら、500円が消えます。
このレッスンのゴール
メモ
データを失わずに、安全に変更できる。
キーワード
| ことば | いみ | れい |
|---|---|---|
| INSERT | 表に新しい行を追加する文 | INSERT INTO shelf |
| UPDATE | 既にある行の値を書き換える文 | SET stock = 0 |
| DELETE | 行を削除する文 | |
| トランザクション | いくつもの変更を、ひとまとめにしたもの | |
| コミットとロールバック | 変更を確定することと、取り消すこと | |
| 写し(コピー) | 練習用に作る、本物とは別の表 |
学生が入力するセルは、このプレビューでは空白です。
始める前に
メモ
上のバーの Start the lab を押し、マシンが動き出すまで待ってください。ショップの商品は読むだけで、練習は必ず、自分のデータベースの写しの上でします。ターミナルを開き直したときは、最初の2つの Run をもう一度押します。
証明書を受け入れる設定
printf '[client]\nssl-verify-server-cert=0\n' > ~/.my.cnfここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
クライアント用の短い名前
alias db='mariadb -h db -u student -pstudent -t -e'ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
自分のデータベースを作る
db "CREATE DATABASE IF NOT EXISTS student_club; DROP TABLE IF EXISTS student_club.shelf"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
キッチン用品を写す
db "CREATE TABLE student_club.shelf AS SELECT id, name, price, stock FROM shop.products WHERE category_id = 4"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
INSERT は行を足す
INSERT INTO 表 (列) VALUES (値) と書くと、新しい行が1つ増えます。列の数と値の数は、同じにします。
書かなかった列には、標準の値か NULL が入ります。決まりに反する値は、データベースが断ります。
ふきんを1つ足す
db "INSERT INTO student_club.shelf (id, name, price, stock) VALUES (100, 'Dish Cloth', 3.50, 40)"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
UPDATE は WHERE で行を選ぶ
UPDATE 表 SET 列 = 値 WHERE 条件 で、条件に合う行だけを書き換えます。
安全な順番は3段です。まず同じ条件の SELECT で、対象の行を見ます。次に UPDATE します。最後にもう一度 SELECT して、確かめます。
1段目: まず行を見る
db "SELECT id, name, stock FROM student_club.shelf WHERE stock < 10 ORDER BY id"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
2段目: その行だけを変える
db "UPDATE student_club.shelf SET stock = stock + 5 WHERE stock < 10"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
3段目: もう一度見る
db "SELECT id, name, stock FROM student_club.shelf ORDER BY id"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
試す: 残高を減らす
-- 田中さんの残高を、300円減らします。
UPDATE wallet SET yen = yen - 300 WHERE owner = '田中';
SELECT owner, yen FROM wallet ORDER BY id;
-- WHERE を消すと、何が起きるかを、考えてから試しましょう。
DELETE は行を消す
DELETE FROM 表 WHERE 条件 は、条件に合う行を消します。消した行は、そのままでは戻りません。
UPDATE と同じように、先に同じ条件の SELECT で見てから、DELETE します。
ふきんを取り除く
db "DELETE FROM student_club.shelf WHERE id = 100"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
よくある間違い
注意
WHERE を書き忘れると、UPDATE も DELETE も、表の全部の行に働きます。エラーは出ません。必ず先に SELECT で見て、WHERE が付いているか確かめます。
間違いを、写しの上だけで
db "UPDATE student_club.shelf SET stock = 0; SELECT id, name, stock FROM student_club.shelf ORDER BY id"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
トランザクションは全部かゼロ
トランザクションは、いくつもの変更を、ひとまとめにしたものです。COMMIT で全部を確定し、ROLLBACK で全部を取り消します。
送金なら、「自分の残高を減らす」と「相手の残高を増やす」は、ひとまとめです。途中で止まったら、ロールバックで、最初に戻します。
例: 途中で止まったとき
| トランザクション | 自分の残高 | 相手の残高 | 合計 |
|---|---|---|---|
| なしで、途中で止まる | 500円減る | 変わらない | 500円消える |
| あり、全部成功して COMMIT | 500円減る | 500円増える | 変わらない |
| あり、途中で ROLLBACK | 変わらない | 変わらない | 変わらない |
学生が入力するセルは、このプレビューでは空白です。
全部消して、ロールバックする
db "START TRANSACTION; DELETE FROM student_club.shelf; ROLLBACK; SELECT COUNT(*) AS still_there FROM student_club.shelf"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。