データベースはどんな形をしているか

SQL が初めてなら、このレッスンから始めましょう。テーブルがデータをどう持つか、クエリの結果をどう読むかを例で確認します。

まず開いてみる

最初の例題の下にあるボタンを押してください。新しいタブで Planche が開き、ショップデータベースが読み込まれています。データベースはページ内で扱われるため、ここでの変更が他のマシンに届くことはありません。最初の状態に戻したいときは、ウェルカム画面からサンプルを読み込み直してください。

テーブルは表である

これを実行してみてください。categories という名前のテーブルの中身を全部くださいという意味です。

1

SELECT * FROM categories;
Planche で実行

結果 — 33 行のうち先頭 5 行

idnamedescriptionparent_idsort_orderis_active
1ElectronicsElectronics and related productsNULL01
2LaptopsLaptops in Electronics111
3PhonesPhones in Electronics121
4TabletsTablets in Electronics131
5AudioAudio in Electronics141

ブラウザの別タブで Planche が開き、サンプルデータベースを読み込んだ状態でこのクエリが入ります。このページの例はどれも同じタブを使い回します。F9 を押すまで実行はされません。

返ってくる表がテーブルです。まず3つの用語を確認します。

  • 列は上端に並ぶ見出しのひとつです。id、name、description など。テーブルのどの項目も同じ6つを持っていて、この名前がそのままクエリに打ち込む名前になります。
  • 行は表を縦に1本たどった横一列で、これがひとつのものにあたります。ここでは1行が1つのカテゴリです。33行あるので、このショップにはカテゴリが33個あります。
  • セルは行と列が交わるところ、つまり値ひとつです。たとえば、あるカテゴリの名前です。

このデータベースのテーブルはどれも同じ形です。products は1行が1商品、orders は1行が1注文、customers は1行が1顧客。違うのは、どんな列を持っているかだけです。

空のセルには名前がある

2

SELECT id, name, parent_id
FROM categories
LIMIT 8;
Planche で実行

結果 — 8 行のうち先頭 5 行

idnameparent_id
1ElectronicsNULL
2Laptops1
3Phones1
4Tablets1
5Audio1

parent_id を見てください。数字が入っている行と、NULL と表示される行があります。この列は「このカテゴリがどのカテゴリの中にあるか」を表します。ノートパソコンは家電の中にあります。そして最上位のカテゴリはどこにも属していないので、入れる値がありません。

NULL は「ここには値がない」という意味です。ゼロの一種としてではなく、それ自体ひとつの考え方として覚える価値があります。実際、ゼロではないからです。

  • NULL は 0 ではありません。ゼロは測った結果の数字で、NULL は測っていないという事実です。
  • NULL は空文字でもありません。名前が空欄で記録されている顧客と、名前を一度も記録していない顧客は別物です。

NULL は通常の値とは異なる比較規則に従います。詳しくは3つめのレッスンで扱います。ここでは、空のセルが単なる空欄ではなく、値が不明であることを示すと覚えておいてください。

行にはそれぞれ固有の番号がある

いちばん左の列は id で、ちょうど1行だけに属し、二度と使い回されない番号です。これが行の主キーです。他の何かがこの行を指すときに、あとから変わりうる名前に頼らずに済むための仕組みです。

出会うテーブルのほとんどが主キーを持っていて、たいていは id という名前です。

なぜ1つではなく23個のテーブルなのか

ショップは原理上、巨大な表1枚でも表せます。1行が1注文で、顧客の名前も住所も、商品も価格もその行に繰り返し書いておけばいい。データベースがそう作られていないのには、身も蓋もない理由があります。引っ越した顧客が1人いるだけで、その人の過去の注文すべてを直して回らなければならず、直し漏れた行がそのまま「他と食い違う事実」になるからです。

そこで、種類ごとにテーブルを分け、行どうしは主キーで指し合います。products.category_id は categories.id を持ち、orders.customer_id は customers.id を持ちます。他のテーブルの行を指す列を外部キーと呼び、これをたどる操作が4つめのレッスンで扱う結合です。

だからこそ、テーブルにどんな列があるかを調べる場所が要ります。サンプルデータベースのページに、全テーブル・全列と、どの列がどのテーブルを指しているかがまとまっています。別タブに開いたままにしておいてください。毎日SQLを書いている人でも、スキーマは手元に置いて書きます。

クエリは質問で、答えもまたテーブル

3

SELECT COUNT(*) AS how_many FROM products;
Planche で実行

結果 — 1 行

how_many
400

1行1列、数字ひとつ。これも立派なテーブルで、ただとても小さいだけです。そしてこれがSQLの考え方そのものです。質問を投げると、400行だろうと1行だろうと、返ってくるものはいつも同じ長方形の形をしています。

この答えがデータベースのどこにも保存されていないことにも注意してください。400という数はどこにも記録されていません。聞かれたときにデータベースが数えたのです。役に立つクエリのほとんどはこの型で、答えを探してくるのではなく計算して返します。

自分で実行してみる

ワークスペース上部のエディタでクエリを書き、F9 で実行します。カーソルがある文だけを実行したいときは Ctrl / ⌘ + Enter です。結果は下のグリッドに出て、行数は最下部に表示されます。

左のパネルは同じデータベースをツリーで見せています。main を開いて Tables を開き、テーブルをダブルクリックすれば、何も書かずに中身を見られます。クエリを書く前にテーブルの中身を確かめるには、たいていこれがいちばん速い方法です。

このページの例題はそれぞれ自分のタブで開くので、書き換えて実行して元に戻す、という往復をしても作業中の場所を失いません。

うまくいかないとき

必ずうまくいかないときが来ます。メッセージは短く、そのままの意味です。列名を打ち間違えるとこうなります。

no such column: naem

メッセージは末尾から読んでください。データベースが見つけられなかったものの名前が、たいていそこに書いてあります。最初のうちのエラーはほぼ3種類です。列名の打ち間違い、思っていたのと違うテーブルにある列、そして文字列を囲むクォートの抜けです(SQLで文字列は 'paid' のようにシングルクォートで囲みます。ダブルクォートは別の意味になります)。

エラーが出たということは、何も実行されなかったということです。文はまるごと拒否されるので、失敗したクエリが何かを変えてしまうことはありません。

次は

テーブル、行、列、NULL が何かを押さえ、クエリを実行して結果を読めるようになりました。次のレッスンは、ほぼすべてのクエリを組み立てている4つの句です。

自分で書いてみる

  1. このショップには顧客が何人いますか。形はページ最後の例題で見たとおりです。

    答えを見る

    答えを見る

    SELECT COUNT(*) AS how_many FROM customers;
    Planche で実行

    結果 — 1 行

    how_many
    1500

    COUNT(*) が行を数え、AS how_many は答えの列に読みやすい名前を付けているだけです。customers を別のテーブル名に変えれば、そのテーブルの行数が出ます。