SQL Lab
第一部 DB 基礎編 · 第 0 章 · 約 15

データベースとは何か

表計算のシートと同じ見た目の表から出発し、文字列で頼むと表が返る相手としてデータベースを掴む。

この章で答える問い
  1. データベースは、表計算と何が同じで、何が違うのか
  2. 何を送ると、何が返ってくるのか
  3. 「データが入っている」とは、どこに何があることか

実物: 見慣れた表

説明の前に、下の枠の「実行する」を押してほしい。枠の中の 1 行が送られて、何かが返る。

顧客の一覧
期待: 10 行 5 列。email が空(NULL)の行が 2 つ

10 行 5 列の表が返ったはずだ。1 行が 1 人の顧客で、列は idnameemailtiercreated_at の 5 つ。 表計算のシートを開いたときと同じ見た目で、行が顧客、列が項目、空欄もある。違いは 1 つだけだ。あなたはこの表のファイルを開いていない。 短い文字列を送ったら、表が届いた。

つまり、誰かがこの表を預かっていて、頼まれたときに作って渡している。この「表を預かり、頼まれた表を作って返す相手」をデータベース(database)と呼ぶ。 預けている表の 1 枚 1 枚がテーブル(table)で、今見たのは customers というテーブルだ。

表計算では、表はあなたの手元のファイルで、自分で開いて直す。だから直す人の数だけコピーが増える。 データベースでは、表は相手の手元に 1 枚だけあり、あなたは頼んで表を受け取る。この違いを 1 枚の図にする。

表計算のファイルcustomers.xlsx手元で開いて直すコピー A佐藤 陽菜 → goldコピー B佐藤 陽菜 → silverコピー C古いまま直した人の数だけ別のコピー。どれが本物か決められないデータベースあなた(この画面)データベースidnametier1佐藤 陽菜gold2鈴木 大輔regular3高橋 美咲silver… 計 10 行customers(1 枚だけ)SELECT *FROM customers表(10 行 5 列)表は相手の手元に 1 枚だけ。頼んで受け取る
表計算は手元のファイルを開いて直すのでコピーが増える。データベースは表を 1 枚だけ預かり、頼まれた表を返す。

使い方: 頼み方は文字列

頼み方を変えると、届く表が変わる。3 つ試す。押す前に「期待」を読み、押した後に返った表の形(何行、何列)を数えてほしい。

列を選ぶ
期待: 10 行 2 列。name と email だけ
行を絞る
期待: 2 行 5 列。tier が gold の 2 人だけ
数える
期待: 1 行 1 列。値は 10

1 つ目は 10 行 2 列、2 つ目は 2 行 5 列、3 つ目は 1 行 1 列で値は 10 のはずだ。 列を選ぶと横が減り、行を絞ると縦が減り、数えると 1 マスになった。送った文字列の違いは、SELECT の後ろと、FROM customers の後ろだけだ。

この頼み方の書き方の決まりを SQL と呼ぶ。SELECT は「取り出せ」、FROM は「〜から」。SELECTFROM の間に列の名前を並べれば列を選べ、* は「全部の列」。WHERE は「〜の行だけ」、COUNT(*) は「行を数えろ」。日本語で言えることを短い英語で書いている、と見ればよい。WHERECOUNT の詳しい使い方は第 2 章と第 3 章でやる。

3 つの結果を見比べて、気づいてほしいことが 1 つある。列を減らしても、行を絞っても、数えても、返ってくるのは表だ。数を 1 つ聞いただけでも、1 行 1 列の表で届く。何を頼んでも、答えは必ず表の形で返る。文字列を送ると表が返る。この往復の形は、この本の最後まで変わらない。

送る(文字列)返る(表)SELECT name, emailFROM customersSELECT * FROM customersWHERE tier = 'gold'SELECT COUNT(*)FROM customersデータベース表を作って返すnameemail佐藤 陽菜hina@example.com鈴木 大輔daisuke@example.com… 10 行 2 列idnameemailtier1佐藤 陽菜hina@example.comgold7山本 さくらsakura@example.comgold2 行 5 列(created_at は略)COUNT(*)101 行 1 列。数 1 つでも表
送るのはいつも文字列、返るのはいつも表。列を選んでも、行を絞っても、数 1 つでも、表の形で届く。

何枚の表を預けているか

ここまで顧客の表しか見ていない。この店は他に何枚の表を預けているのか。一覧を頼む。

預けている表の一覧
期待: 7 行 1 列。テーブルの名前

categoriescustomersorder_itemsordersproduct_categoriesproductsstocks の 7 行が縦に並んだはずだ(第 1 章で表を 1 枚作った後に戻ってくると 8 行になる)。これも 1 列の表だ。 この店が預けている表は顧客だけではない。商品、注文、注文の明細、在庫、商品のカテゴリ。それぞれが 1 枚のテーブルで、ここに名前が出ている。

列の見出しに Tables_in_lab_basics とある。lab_basics は、この 7 枚をまとめて入れてある入れ物の名前だ。 表計算で言えば、1 つのファイルに 7 枚のシートがある状態に近い。 この入れ物のこともデータベースと呼ぶ。つまり「データベース」は 2 つの意味で使われる。頼むと表を返してくれる相手と、その相手が持っている表の束(lab_basics)。文脈で見分ける。

先輩の言った MySQL は、この束の番をして、頼みに答えているプログラムの名前だ。 この教材では、第一部は lab_basics、第二部は lab という束を使う。

データベース lab_basics = 表の束(7 枚)categories6 行customers10 行← さっき見た表order_items200 行orders50 行product_categories40 行products30 行stocks30 行SHOW TABLES で返る7 行がこの 7 枚この束の番をしているプログラムが MySQL
lab_basics は 7 枚の表の束で、これもデータベースと呼ぶ。MySQL はその番をしているプログラムの名前。

仕組み: 相手はどこにいるのか

ここまで「相手」と呼んできたものの居場所を、浅く覗く。次の 2 つは、押して返ったものを眺めるだけでよい。中身を読み解く必要はない。

相手の名前と番号
期待: 1 行 1 列。8.0.xx のような番号
いま誰が頼んでいるか(覗くだけでよい)
期待: 数行 8 列。Info の列に SHOW PROCESSLIST と書かれた行が 1 つ

1 つ目は 8.0.46 のような番号が返ったはずだ。表を指定していないのに答えが返る。相手は預かった表を渡すだけでなく、答えを作る側でもある。 この番号は、相手のプログラム、MySQL の版の番号だ。

2 つ目は数行の表で、Info の列に SHOW PROCESSLIST と書いてある行が 1 つある。それが、今まさに頼んだあなただ。 他の行は、同じ相手に今つながっている別の誰か(この教材の別の画面や、相手自身の作業)で、Time の列を見ると、あなたが押すずっと前からいる行もある。 相手はあなたが押す前から動いていて、押していない間も動き続けている。他の列の意味は今は読まなくていい。 「相手は 1 つで、頼む側は同時に何人もいる」ことだけ見えればいい。行数は環境で変わる。

この、常に動いていて頼まれるのを待っているプログラムをサーバー(server)と呼ぶ。頼む側、つまりこの画面がクライアント(client)、 画面とサーバーの間に通っている 1 本の線が接続(connection)で、さっきの表の 1 行が接続 1 本だ。

「MySQL に入っている」の中身もここで言える。7 枚の表は、サーバーが動いている機械のディスクに、ファイルとして置いてある。ここだけはこの画面から見えないので、言葉で補う。 そのファイルを開いて読み書きするのはサーバーだけだ。あなたも、Web の画面も、社内ツールも、ファイルには触らない。サーバーに文字列で頼み、表を受け取る。 ファイルの大きさは第 8 章で、接続の中で何が起きているかは第 9 章で見る。

この画面(クライアント)SELECT VERSION()VERSION()8.0.xx文字列を送り表を受け取るMySQL(サーバー)IdTimeInfo54151NULL19694NULL240SHOW PROCESSLIST濃い行があなた。1 行 = 接続 1 本Time はつながってからの秒数Id と行数は環境で変わるディスク(lab_basics)categoriescustomersorder_itemsordersproduct_categoriesproductsstocks7 枚の表がファイルとして文字列接続 1 本表(行と列)読み書きサーバーだけ
この画面が触れるのはサーバーだけで、ディスク上のファイルを読み書きするのはサーバーだけだ。

罠: なぜ表計算のファイルではだめなのか

表を読む、絞る、数える。ここまでの 7 回でやったことは、表計算でもできる。顧客が 10 人なら、そのほうが楽なくらいだ。 着任初日に聞いた「壊れた」話に戻ると、それは 4 つの場面に分けられる。データベースは、この 4 つを引き受けるためにある。 この本は、道具が揃った順に、それぞれを実物で確かめていく。

  1. 2 人が同時に同じ行を直す。片方の直しが、もう片方に上書きされて消える。→ 第 7 章「途中を見せない」
  2. 直している途中で落ちる。注文は書けたが在庫は減っていない、という中途半端が残る。→ 同じく第 7 章
  3. 行が 100 万を超えて、「この顧客の注文だけ」を探すのに毎回全部読む。→ 第 8 章「索引という実物」、そして第二部
  4. 注文の表と在庫の表がずれる。同じ商品が 2 通りの名前で書かれ、消した商品を指す注文が残る。→ 第 4 章「テーブルをつなぐ」、第 5 章「データを変える」

今は「こういう場面がある」とだけ覚えておけばいい。それぞれの章で、表計算では起きるがデータベースでは起きない、を実際に起こして確かめる。

第 7 章第 7 章第 8 章 → 第二部第 4 章・第 5 章2 人が同時に直すnametier佐藤 陽菜goldnametier佐藤 陽菜silvercustomers.xlsx後から保存した方が勝つ直している途中で落ちる注文を 1 行書く在庫を 1 減らす落ちた注文はあるのに在庫は減っていない行が増えて探せないcustomer_id = 7 ?… 1,000,000 行毎回、全部の行を読む注文と在庫が食い違うproductqty歯ブラシ 3本セット2歯ブラシ3本セット1同じ商品なのに別の商品として数える消した商品を指す注文も残る
表計算のファイルが壊れる 4 つの場面。それぞれを確かめる章が、この本の地図になる。

この画面の約束

3 つだけ。1 回の実行で送れる文は 1 つ(文末の ; は要らない)。返る行は先頭 500 行まで表示する。 Mac は ⌘+Enter、Windows は Ctrl+Enter で実行できる。

データベースとは、表を預かり、文字列で頼まれた表を作って返し続ける相手である。

確認

FROM を書かない SELECT が成り立つのはなぜか。
サーバーは預かった表を渡すだけでなく、頼まれた答えを作る側でもあるから。表を指定せずに式だけを頼んでも、計算した結果が返る。
行を数えるだけの頼みごとでも、答えが表の形で返るのはなぜか。
何を頼んでも答えは表で返る、というのがこの往復の約束だから。数を 1 つ聞いただけでも、1 行 1 列の表として届く。
同じ表を別の人が見ても食い違わないのはなぜか。
表はサーバーの手元に 1 枚だけあり、クライアントはコピーを持たずに、頼んで受け取っているから。表計算のように直す人の数だけコピーが増えることがない。

次の章へ

最初に届いた customers の表には、行と列のほかに、左端の番号と、NULL と書かれた空欄が 2 つあった。 次の章では、その表の中を指さしながら、行・列・主キー・型・NULL に名前を付ける。名前が付くと、自分でテーブルを作れるようになる。