データベースとSQLのお話

こんにちは、Akros Web & Business Design Academy 札幌校の三本です。
Webの制作業務、特にフロントエンドで活躍されている方には少しハードルが高めなお話になりますが、プログラマーにとっては基礎的なお話になっていきます。
今回は、データベースとSQLのお話をしていこうと思います。

データベースとは

簡単に言ってしまうと、データの集まりで、DBMS(データベース管理システム)と呼ばれるもので管理されています。
Web制作の現場では、主にMySQL、PostgreSQLが使われることが多いですね。
他にも、Microsoft Officeに収録されているAccessやWindows Serverに実装されているSQL Server、Oracle DB、SQLiteなどがあります。

このデータは、テーブルと呼ばれる塊でまとめられ、いくつかのテーブルが集まってデータベースとなります。
テーブルというと、htmlのtableタグを思い浮かべる方もいると思いますが、データベース上のテーブルも正にその形でイメージすることができます。
このテーブルをイメージした構造を関係モデルと呼び、テーブル同士を連結しながら目的の情報を得る仕組みになっています。

【球団テーブル】
ID 所属リーグ 球団名
1 1 広島
2 1 巨人
3 2 日本ハム
4 2 ソフトバンク

リレーショナルデータベース(関係データベース)

データベースを管理するDBMSには、管理の方法(データモデル)によって大別されます。
Web制作でよく使われるMySQLは、リレーショナルデータベースの代表格で、RDBMSと呼ばれるデータモデルによって管理しています。
上で説明した、関係モデルがリレーショナルデータベースを示しています。
PostgreSQLのDBMSは、ORDBMSと呼ばれ、上記の関係モデルの他にオブジェクト指向の管理もできるシステムになっています。

SQLとは

データベース問い合わせ言語と呼ばれることもある、データベースから目的の情報を取り出す際に必要になるものです。
そのために記述したコードのことをSQL文と言います。

[sql] /* 抽出 */
SELECT * FROM t_team WHERE id=1 ORDER BY name

/* 挿入 */
INSERT INTO t_team(id,league,name) VALUES (1,1,”中日”)

/* 更新 */
UPDATE t_team SET (name=”広島”) WHERE id=1 AND league=1
[/sql]

SQL文について

前項でサンプルを書きましたが、より具体的な例を使って説明したいと思います。
まずは、いくつかのテーブルを用意します。

【球団テーブル】
ID 所属リーグ 球団名
1 1 広島
2 1 巨人
3 2 日本ハム
4 2 ソフトバンク

 

【ポジションテーブル】
ID ポジション
1 投手
2 捕手
3 内野手
4 外野手

 

【選手テーブル】
ID 背番号 ポジションID 選手名 球団ID
1 11 1 大谷 翔平 3
2 25 3 新井 貴浩 1
3 6 3 中田 翔 3
4 6 3 坂本 勇人 2

 
このようなテーブルがあった場合、以下の条件でデータが欲しい場合を考えます。

  • 日本ハム球団に所属している選手の一覧
  • ポジション順で並べる
  • 同じポジションの場合は背番号順
  • 背番号、選手の名前、ポジション名をデータとして取得する

ここでは選手の一覧が欲しいので、ベースになるテーブルは、【選手テーブル】になります。
各テーブルの関係性(リレーションシップ)を図で表すと以下のようになります。

【選手テーブル】のポジションIDと【ポジションテーブル】のIDが紐付いており、
【選手テーブル】の球団IDと【球団テーブル】のIDが紐付いています。
このテーブルの関係性により、≪大谷 翔平≫は、投手のポジションで、日本ハムに所属していることが分かります。

この関係性を使って目的の情報を取得するためにSQL文を記述することになります。

SQL文の記述

まずはじめに、ベースとなるテーブルから情報を抽出するためのSQL文を記述してみます。
とりあえず最初は全ての情報を取得してみます。

[sql] SELECT * FROM 選手テーブル ORDER BY ID ASC
[/sql]

データベースから情報を抽出するためには、SELECT文を使います。
*印は、ワイルドカードで全ての項目を表します。
FROM句は、対象となるテーブル名を指定しおり、ORDER BY句は、並び替えのキーとなる項目を指定します。
最後のASCは、昇順にソートすることを表しています。降順の場合は、DESCを指定します。

次に、最初の条件である、日本ハム球団に所属している選手を絞り込みます。

[sql] SELECT * FROM 選手テーブル WHERE 球団ID = 3 ORDER BY ID ASC
[/sql]

WHERE句を指定し、条件式を記述します。
複数の条件がある場合には、ANDもしくはORで、つないでいきます。

さらに条件で指定されている並び順でソートします。

[sql] SELECT * FROM 選手テーブル WHERE 球団ID = 3
ORDER BY ポジションID, 背番号 ASC
[/sql]

ORDER BY句の内容を変更します。
ポジション順で並べ、同じポジションだったら背番号順という指示ですので、ポジションIDを先に記述し、カンマで区切り、背番号を続けて記述します。

テーブルの結合

ここからが、今回のメインとなるところです。
先ほどテーブル同士の関連性を表した図を元にSQL文で、テーブルを結合していきます。
結合の仕方は、大きく分けて3つあります。

INNER JOIN / LEFT OUTER JOIN / RIGHT OUTER JOIN

今回は、詳しい説明を省きますが、INNER JOINを使います。
(機会がありましたら、あらためて説明します。)

[sql] SELECT * FROM 選手テーブル INNER JOIN ポジションテーブル
ON 選手テーブル.ポジションID = ポジションテーブル.ID
WHERE 球団ID = 3
ORDER BY ポジションID, 背番号 ASC
[/sql]

まずは、【選手テーブル】と【ポジションテーブル】を結合します。
INNER JOIN句の後に、結合するテーブル名を指定します。
ONの後ろに、結合する条件を指定します。
ここでは、選手テーブルのポジションID、ポジションテーブルのIDがペアとなります。
どのテーブルの項目かを区別するために、ドットでつないで記述します。

同様にして、球団テーブルも結合します。

[sql] SELECT * FROM 選手テーブル INNER JOIN ポジションテーブル
ON 選手テーブル.ポジションID = ポジションテーブル.ID
INNER JOIN 球団テーブル ON 選手テーブル.球団ID = 球団テーブル.ID
WHERE 球団ID = 3 ORDER BY ポジションID, 背番号 ASC
[/sql]

必要なデータの抽出

それでは、最後に必要な項目を拾い出す作業になります。
先ほど説明したように、*印はワイルドカードのため、全ての項目を抽出します。
したがって、結合した3つのテーブル全ての項目を出力することになります。
今回必要となるのは、「背番号」「選手の名前」「ポジション名」の3項目です。

[sql] SELECT 選手テーブル.背番号, 選手テーブル.選手名, ポジションテーブル.ポジション名
FROM 選手テーブル INNER JOIN ポジションテーブル
ON 選手テーブル.ポジションID = ポジションテーブル.ID
INNER JOIN 球団テーブル ON 選手テーブル.球団ID = 球団テーブル.ID
WHERE 球団ID = 3 ORDER BY ポジションID, 背番号 ASC
[/sql]

*印の部分を書き換えていきます。
どのテーブルの何?
っていうのを明記していきます。
例えば、ただIDとだけ記述してしまうと、選手テーブルのIDなのか、ポジションテーブルのIDなのか、分からなくなってしまいます。
したがって、選手テーブルの背番号、ポジションテーブルのポジション名というふうに、このテーブルのこの項目という形で表現してあげます。
また、対象となる項目が複数の場合は、カンマでつなげて記述します。

この結果、出力されるデータは以下のようになります。

【日本ハムの選手一覧】
背番号 選手名 ポジション名
11 大谷 翔平 投手
6 中田 翔 内野手

最後に

今回は、データベースとSQLの基本的なところのお話でしたが、細かい説明は抜きにして、ひとまず目的のデータを取得するという目標を達成するための最短でお話しました。
もしデータベースのテストができる環境がありましたら、SELECT文は参照系のSQL文ですので、データを壊すことは無いと思いますので、色々試してみて下さい。
(厳密に言うと、壊してしまう可能性もあるのですが・・・)
また機会があれば、更新系のSQLやより複雑な抽出についても触れたいと思います。

さらに詳しく知りたい方は、Akrosへ。。。
まずは、無料体験レッスンから初めてみませんか?
お申し込み、ご相談はこちら
体験お申し込み