このレッスンでやること
データベースは、情報をテーブル(表)に入れて保管します。テーブルは表計算の表に似ています。列は 1 種類の情報、行は 1 つのもの、たとえば 1 人のお客さんを表します。
SQL は、データベースに話しかけるための言語です。このレッスンでは、小さなネットショップのデータベースに新しいテーブルを 1 つ足し、行を入れ、質問をし、行を 1 つ変えて、行を 1 つ消します。
始める前に
メモ
このレッスンの上にあるバーのラボを起動を押し、「実行中」と出るまで待ちます。最初の起動は、ショップのデータベースを作るので、少し時間がかかります。下の実行ボタンは、それぞれのコマンドをラボのターミナルに順番に入力します。すべて同じセッションで動きます。様子を見たり、自分でコマンドを打ったりしたいときは、バーのターミナルを開く(新しいタブ)を押します。
1. ターミナルにサインインの方法を教える
MySQL は自分でセキュリティ証明書を作ります。そのため、最初のコマンドで「その証明書を受け入れてよい」とデータベースのクライアントに伝えます。通信は今までどおり非公開です。2 つ目のコマンドは、shop データベースにサインインして SQL を 1 つ実行する長いコマンドに、sql という短い名前を付けます。これ以降は、sql と、引用符で囲んだ SQL 文だけを打てばよくなります。
printf '[client]\nssl-verify-server-cert=0\n' > ~/.my.cnfここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
alias sql='mariadb -h db -u student -pstudent shop -t -e'ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
2. すでにあるテーブルを見る
ショップには、すでにテーブルがあります。SHOW TABLES でその一覧が出ます。テーブルごとに入っている情報がちがいます。customers は買う人、products は売っている商品です。
sql "SHOW TABLES"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
3. テーブルの中を見る
DESCRIBE は、テーブルの列を、名前や型などといっしょに表示します。Key の列に注目しましょう。PRI は主キーという意味です。主キーは、行ごとに値がちがう列で、1 つの行だけを指し示します。ここでは id が主キーです。
sql "DESCRIBE customers"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
sql "DESCRIBE products"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
4. 新しいテーブルを作る
いよいよ自分のテーブル wishlist(ほしいものリスト)を作ります。どのお客さんがどの商品をほしがっているかを入れるテーブルです。CREATE TABLE で作り、かっこの中に列を並べます。
id INT AUTO_INCREMENT PRIMARY KEY:整数で、行が増えるたびに MySQL が数えて入れてくれます。これが主キーです。customer_idとproduct_id:どのお客さんか、どの商品か。ほかのテーブルの行のidが入ります。priority:どれくらいほしいか。1(とてもほしい)から 5 までです。何も指定しなければ 3 になります。UNIQUE KEY:同じお客さんと同じ商品の組み合わせを、2 回入れることはできません。FOREIGN KEY:その id がcustomersとproductsに実際にあることが条件です。ショップにない商品をほしがることはできません。
文は長いですが、実行するのは一度だけです。
sql "CREATE TABLE wishlist (id INT AUTO_INCREMENT PRIMARY KEY, customer_id INT NOT NULL, product_id INT NOT NULL, priority INT NOT NULL DEFAULT 3, UNIQUE KEY customer_product (customer_id, product_id), FOREIGN KEY (customer_id) REFERENCES customers(id), FOREIGN KEY (product_id) REFERENCES products(id))"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
sql "DESCRIBE wishlist"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
5. テーブルに行を入れる
INSERT INTO は行を追加します。まずテーブルと列を書き、次に VALUES と、行ごとに 1 組のかっこを書きます。id は書きません。MySQL が数えてくれるからです。ここでは 3 行を入れます。お客さん 1 は商品 1 と商品 5 を、お客さん 2 は商品 5 をほしがっています。そのあと SELECT * で、すべての行のすべての列を表示します。
sql "INSERT INTO wishlist (customer_id, product_id, priority) VALUES (1, 1, 3), (1, 5, 2), (2, 5, 1)"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
sql "SELECT * FROM wishlist"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
6. ユニークキーが「だめ」と言う
お客さん 1 は、すでに商品 1 をほしがっています。同じ組み合わせをもう一度入れてみましょう。ステップ 4 の UNIQUE KEY があるので、MySQL はエラーを出して断ります。このエラーはあなたの失敗ではありません。テーブルが自分のデータを守っているのです。何も追加されていません。
sql "INSERT INTO wishlist (customer_id, product_id, priority) VALUES (1, 1, 1)"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
sql "SELECT * FROM wishlist"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
外部キーも「だめ」と言う
メモ
ターミナルで sql "INSERT INTO wishlist (customer_id, product_id) VALUES (1, 999)" を試してみましょう。商品 999 はないので、FOREIGN KEY が断ります。
7. かんたんな質問をする
SELECT は質問をします。FROM はどのテーブルかを指定します。WHERE は条件に合う行だけを残し、ORDER BY は並べ替えます。この質問は、お客さん 1 のほしいものを、いちばんほしい順に表示します。
sql "SELECT * FROM wishlist WHERE customer_id = 1 ORDER BY priority"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
sql "SELECT name, price FROM products WHERE price > 50 ORDER BY price DESC"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
8. 2 つのテーブルを結合する
wishlist には数字しかありません。商品の名前は products にあります。結合(JOIN)は、2 つのテーブルを横に並べます。JOIN products ON products.id = wishlist.product_id は、「wishlist の行ごとに、product_id にある数字を id に持つ商品を探す」という意味です。これで中身が読めるようになります。
sql "SELECT wishlist.id, products.name, products.price, wishlist.priority FROM wishlist JOIN products ON products.id = wishlist.product_id"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
9. 3 つのテーブルを結合する
もう一度結合すると、お客さんの名前も加えられます。考え方は同じで、JOIN が 1 つ増えるだけです。
sql "SELECT customers.first_name, products.name, wishlist.priority FROM wishlist JOIN customers ON customers.id = wishlist.customer_id JOIN products ON products.id = wishlist.product_id ORDER BY customers.first_name"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
10. 行を変える
UPDATE は行を変えます。SET は新しい値、WHERE id = 2 はどの行かを指定します。お客さん 1 は商品 5 がいちばんほしいので、priority を 1 にします。そのあと SELECT で、本当に変わったか確かめます。
sql "UPDATE wishlist SET priority = 1 WHERE id = 2"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
sql "SELECT * FROM wishlist WHERE id = 2"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
WHERE を忘れない
注意
UPDATE や DELETE は、思った行だけを変えてくれると考えがちです。でも WHERE がないと、テーブルのすべての行が変わります。かならず先に WHERE を書き、実行の前と後に SELECT で確かめましょう。
11. 行を消す
DELETE FROM は行を消します。ここでも WHERE でどの行かを指定します。お客さん 2 が気を変えたので、行 3 を消します。そのあとテーブルを見ると、行 3 はなくなり、ほかの行は残っています。
sql "DELETE FROM wishlist WHERE id = 3"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
sql "SELECT * FROM wishlist"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
12. 残りを数える
COUNT(*) は行の数を数えます。行 3 について聞くと答えは 0 になり、行が消えたことがわかります。
sql "SELECT COUNT(*) AS rows_found FROM wishlist WHERE id = 3"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
13. phpMyAdmin で見る
ラボのバーの phpMyAdmin を押すと、新しいタブで開きます。左の shop を選びます。作った wishlist テーブルが、ほかのテーブルといっしょに並んでいます。wishlist を押し、Browse(表示)で行を、Structure(構造)で、作った主キーとユニークキーを見てみましょう。
自分でもう一度やってみよう
ヒント
最初からやり直すには、sql "DROP TABLE wishlist" でテーブルを消して、ステップ 4 に戻ります。そのあと、自分で質問も考えてみましょう。価格が 10 未満の商品は? パリに住んでいるお客さんは?
ターミナルが再起動していたら、先にステップ 1 の alias をもう一度実行してください。テーブルはデータベースに残っています。