株式会社WOWNエンジニアチームです。
前回の記事では、「Webシステムにはフロントエンドとバックエンドという2つの分野がある」という基本的な内容を話しました。
今回はバックエンド、つまりサーバーとのやり取りの話をしようと思います。
データベースの構造
Webシステムでは「データベース」という場所にデータを集めて保存しています。これを制御するのがバックエンドと呼ばれる分野で、WOWNではLaravelを使ってバックエンドのプログラムを組み上げています。
データベースは大量のデータを保管&管理する箱のようなもので、例えばユーザー情報には、「年齢は?」「メールアドレスは?」「どの部門に属しているの?」など、関連する情報が保存されます。
それに際して、もしかすればユーザーだけでなく部門の情報もデータベースに保存しないといけません。(部門の名前は?規模は?勤務地は?)
ともかくデータベースには、さまざまな種類のデータを複雑に保存する必要があります。
こういった情報を、どんな構造で保存するのか?これには以下のような種類があります。
階層型
部 門
/ | \
営業部 企画部 製造部
/ | \ / | \ / | \
菅原 冨安 板倉 遠藤 守田 久保 南野 三苫 上田
階層型データベースは樹形図のような形をしており、どんどん枝分かれして派生していく形のデータベースです。
派生前のデータを親ノード、派生後のデータを子ノードと呼び、親ノードは複数子ノードを持つことができ、子ノードは1つだけ親ノードを持つことができます。
ツリー構造でできていて、情報へ辿り着くのに一つの道しかないので早くノードを取得することができるのですが、例えば板倉さんが営業部と企画部の両方に所属する場合、板倉さんが2つの異なるノードに関連付けられることになります。
実際には同じ人物なのにデータ上では2人の板倉さんがいることになってしまい、板倉さんの情報が変更された場合、2つのノードの両方を更新する必要があるのでミスを引き起こしやすいことが欠点です。
ネットワーク型
部 門
/ | \
営業部 企 画 部 製造部
/ | \ / / | \ / | \
菅原 冨安 板倉 遠藤 守田 久保 南野 三苫 上田
上記ツリー型の欠点を克服したのがネットワーク型データベースで、1つの子ノードが複数の親ノードを持つことができるようにしたものです。親ノードと子ノードの関係が網目状になれることが特徴で、これにより板倉さんの重複登録を回避できます。
板倉さんが営業部と企画部に属している場合はこのように表示することができるのですが、たくさんの人がいろんな部署に所属すると線の数が増え、どんどん線が交差し、分かり辛くなってしまうこともあります。
リレーショナル型
社員情報テーブル 部門情報テーブル
ID,名前,部門コード ID,部門名
1 ,菅原,1 1 ,営業部
2 ,冨安,1 2 ,企画部
3 ,板倉,1 3 ,製造部
4 ,遠藤,2
5 ,守田,2
6 ,久保,2
7 ,南野,3
8 ,三苫,3
9 ,上田,3
10,板倉,2
さらにこの問題を解決したのがリレーショナル型で、急に形式が変わってExcelやGoogleスプレッドシートのような形をしています。
リレーショナルデータベースは情報ごとに「テーブル」に分けてデータを保存し、テーブルとテーブルとの関連付け(リレーション)をすることで、別のデータとの連携を行う構造です。
上の例でいうと、社員情報テーブルには部門コードという情報があり、部門情報テーブルのIDと関連付けられています。板倉さんは1番の部門コードを持っているので、部門情報テーブル1番の部門、つまり営業部に属しているという扱いになります。
これなら、例えば部門情報テーブル1番の部門名が「営業部」から「工事部」へ変更になった場合でも、所属する3人全ての所属が工事部に自動的に変更することができます。
このように種類があるといっても、ネットワーク型はツリー型の問題を解消したもので、リレーショナル型はネットワーク型の欠点を克服したものなわけです。
ツリー型やネットワーク型は構造が単純な分だけ検索時の処理速度が早いという特徴もありますが、データの加工(後からデータの内容を変更)を行ないにくい問題もあり、あまり頻繁に使われるものではありません。
WOWNのエンジニアチームで利用しているのはリレーショナル型で、MySQLというデータベース管理システムを使って運用しています。
データベースとSQL
SQL
リレーショナルデータベースとのやりとりは、通常のプログラミング言語とは違う「SQL(Structured Query Language)」という専用の言語で行い、書き上げられたコードは「クエリ(query:問い合わせ)」もしくは「SQLクエリ」と呼ばれます。
プログラムの世界では、皆さんがGoogleなどの検索エンジンで検索するときのキーワードも「クエリ」と呼ばれます。つまりSQLクエリとは、データベースに対して「データの中からこういう内容で検索してください」という命令文なわけです。
SELECT users.name, users,email, COUNT(orders.id) AS order_count
FROM users
LEFT JOIN orders ON users.id = orders.user_id
WHERE users.age > 18
GROUP BY users.id
HAVING COUNT(orders.id) > 0
ORDER BY order_count DESC;
例えばこんな感じのコードがSQLクエリです。コードの内容を簡単に説明すると「18歳以上で、なにか注文をしているユーザーを探してきて。見つけたら注文が多い順に並べて表示して」といった内容です。
name | age | order_count | |
taro_yamada | yamada@example.com | 23 | 5 |
hanako_tanaka | tanaka@example.com | 31 | 2 |
ken_suzuki | suzuki@example.com | 19 | 1 |
結果、こんな感じのデータが返ってきます。
クエリを与えたら、結果が返ってくる。これがSQLの基本的な動作になります。
SQLは難しい…
SQLクエリは独特な記述方式を取る上、Laravelプロジェクト内では「基本的にPHPでコードを書くけれど、データベース検索部分だけはSQLで書く」というややこしいコードの使い分けをしなければなりません。あまり直感的ではありませんし、書き間違えによるバグを起こしやすいです。
この問題を緩和するため、Laravelには特別な機能があり、より直感的かつ簡単で分かりやすい方法でSQLを内部的に生成し、データベースからの検索を行えます。
次回、「Laravelでは実際にどうやってデータベースと検索するのか?」に続きます。
WEB制作・ITに関するお悩みや
ご質問等お気軽にご相談ください