ここから本文です

そもそも「リレーショナルデータベース」って何?

@IT 7月5日(火)6時10分配信

●「データベース」とは何か?

 企業には、顧客に関するデータや商品の在庫数など、企業活動で生じた「さまざまなデータ」が存在します。このようなデータを共有利用するために1つにまとめたデータの集合体が「データベース」です。

【その他の画像】SQLを使い、トランザクション単位で変更内容を管理する流れ

 どこの会社でも行っている「売上管理」でデータベースを考えてみましょう。会社の規模が小さいうちは、「表計算ソフトウェアで、簡単に管理できる」と思うかもしれません。しかし、売り上げが伸び、取引先が増え、従業員数も増えていくに従って、これだけでは問題が発生するようになります。例えば、複数の従業員が同じようなデータを、それぞれ独自のやり方で作成/保持していると、「どれが最新のデータか分からない」「どれが正しいデータなのか分からない」「ある月の特定の日の売り上げデータだけが知りたかったのに、探すのに時間がかかる」、といったように、データ管理が徐々に難しくなり、必要かつ正確なデータをすぐに取り出せなくなる状況に陥ります。

 そうならないように活用するのがデータベースです。データベースは大量のデータでも安全かつ効率的に管理できる仕組みが整えられたシステムです。そのため、複数の人が大量のデータを扱う際にとても有効なツールです。もう少し具体的な例で、データベースの必要性を解説していきましょう。

 ある企業では、「社員データ」「顧客データ」など、業務上必要なさまざまなデータを支店ごとに個別に管理しています。

 社員データは全国どの支店でも必要ですが、それを各支店で個別に管理するとなると、いくつかの問題が生じます。

 例えば新入社員が入社し、社員データベースとしてその情報を反映するとします。そのとき、各支店単位でデータを登録し、管理する方法では、ある支店だけ登録し忘れたた、変更が必要だったのにされていなかった、といったトラブルが起こり得ます。また、支店がそれぞれデータを保持するということは、データ保持のための仕組みやディスク領域がそれぞれ必要になります。全社的に考えると無駄が多く、管理もとても煩雑になってしまいます。

 このような状況は、全社で共有するデータを1つの「集合体」にすると解決できます。そうすれば、データの登録漏れや変更漏れが発生する心配がなくなります。無駄にディスク領域を使わなくても済むようになります。このデータの集合体が、データベースというわけです。

●「DBMS」とは何か

 前述したように、データベースは「共有利用」を前提として複数のデータを1つにまとめたデータの集合体です。しかし、1つのデータベースを複数の利用者(以下、ユーザーとします)で使う場合には、また別の問題が発生します。

 その1つが、「複数のユーザーが、ほぼ同時に同じデータを変更してしまった場合」の対処です。例えば、Aさんが変更作業している途中に、Bさんが“別の内容に置き換えてしまう”と、「データの矛盾」が発生してしまいます。このデータの矛盾を防ぐためには、ユーザーが順番にデータにアクセスできるように、つまり、誰かの作業中にはファイルを更新できないように制御する必要があります。

 また、全てのユーザーがあらゆるデータにアクセスできてしまうのも大きな問題です。セキュリティやコンプライアンスを考える上で、「誰がどのデータにアクセスできるのか」を制御する「アクセス制御」も必要になります。

 これを全て人力で管理するのはとても大変です。しかし、データベースを複数人で利用しても適切に管理してくれるソフトウェアがあります。このソフトウェアが、データベース管理システムです。「DBMS(Database Management System)」とも呼ばれます。

 ユーザーからのデータベースに対する要求は、必ずDBMSを介して行われます。DBMSは、データを処理する前に「順序制御」や「権限確認」などを行ってくれます。


●「リレーショナルデータベース(RDB)」とは何か

 データベースには、大きく分けて「階層型」「ネットワーク型」「リレーショナル型」があります。そのうち、2016年現在で一般的に使用されているのは、リレーショナル型です。「リレーショナルデータベース」、略して「RDB(Relational Database)」と呼ばれます。RDBを管理するDBMSを「リレーショナルデータベース管理システム」、同じく略して「RDBMS」と呼ばれます。

 RDBには2つの大きな特徴があります。

・データは「二次元の表形式」で表現される
・表は結合(リレーション)して利用できる

 RDBでは、全てのデータを表形式で表現します。表は列と行で構成され、列は必ず1つの意味を持ちます。

 例えば、図5で示した社員表には「社員番号」「社員名」「給与」「部門番号」といった「列データ」が含まれます。そして、横の1行が1人の社員データを示します。例えば、行データの最初の行にある、社員番号7899の鈴木さんは、月給30万円で10番で識別される部門番号の部署に所属しているという意味になります。社員表を参照することで、社員の社員番号を調べたり、給与金額を変更するといった処理を行えます。

 RDB内にあるデータを参照したり、変更したりするには、「SQL(Structured Query Language)」というデータベース言語を使います。SQLの詳細は後述します。

 RDBのもう1つの大きな特徴は、複数の表を結合(リレーション)して利用できることです。1つの表の情報だけでは知りたい情報が得られないことがあります。例えば図5では、加藤さんの所属は「20」とありますが、これだけでは正しい部署名が分かりません。そこで、部門番号「20」が「何部の何課」なのかが登録してある「別の表=部門表」を参照します。部門表の情報と付け合わせることで、加藤さんの正しい所属部署が分かる、というわけです。

 RDBでは、共通の情報を持つ「列」を使用して、表を一時的に結合することができます。このことを「リレーション」と呼びます。複数の表のリレーションも、前述したSQLを使って操作します。

 それならば、最初から図7のような1つの表にしておけばいいのでは? と思うかもしれません。しかし、これらを1つの表にしてしまうと、幾つか問題が起こり得ます。例えば、データベースの規模が大きくなるにつれてディスク領域が多く必要となり、更新の手間も多く発生する課題が発生します。

 具体的に説明しましょう。仮に3拠点で計1万人のデータを保存する社員表に「部門表のデータ」も含めるとすると、3つしかない「所在地」の名称が社員ごとの行データそれぞれに必要となります。重複データが多いと思いませんか? 数件ならまだしも、1万件規模になりますと、その分、無駄と思えるディスク領域を消費してしまっています。

 また、「所在地の名称」が変わる場合はどうでしょう。その拠点にいる社員全員のデータを変更する処理を行わなければなりません。変更は手間が掛かり、ミスも発生しそうです。このような問題を避けるために、「データ重複を省きながら」1つの表を複数の表に細かく分けて、必要に応じてリレーションができるようにするのがポイントです。このような作業は、データベースの世界では「正規化」と呼ばれます。

●「SQL」を使ってデータを処理する

 RDBMSに対する処理は、前述したSQLという言語を使って指定します。表データの検索や、データの変更、表の作成もSQLで行います。SQLは処理の内容によって、以下の4つに分類されます。

※注:解説書籍などによって、SELECTはDMLに分類されることもありますが、本稿ではQueryで分類します

 SQLを使って、どのような処理が行えるのでしょう。ここでは、人事部の担当者が社員の情報を共有するために社員表を作成する、というシーンで解説します。

 まず、社員表そのものを作成するために、CREATE文を使って表を作成します。この作業で、「表の枠組み」が作られます。データはまだ何も入っていません。

 続いて、INSERT文を使って社員表に社員情報のデータを挿入します。これで、全社員の情報を持つ社員表を作成できました。ここまでできれば、SELECT文を使って、社員表のデータを参照することも可能になります。

 山田さんの所属部署が「営業」から「企画」に移るといったように、社員の部署異動があったならば、社員表のデータベースを修正する必要が生じます。この作業はUPDATE文によって更新します。

 無事に社員表が作成できたら、最後にCOMMIT文でデータを確定させます。もし、社員情報データを間違えて挿入してしまった場合など、変更処理を誤って実行した場合は、ROLLBACK文で事前の処理を取り消すこともできます。

●「トランザクション単位」で変更内容を管理する

 COMMITやROLLBACKは、「トランザクション制御文」と呼ばれます。トランザクションとは、データベースにおいて「作業を完了するための一連の作業」の単位のことです。ここでは「ある工場での製品の受発注処理を行う」シーンに例えて解説しましょう。

 受発注の処理では、データベース内の在庫表と注文表でデータを管理しています。「2016年6月15日に、D社から、製品Aについて、100個の注文を受けた」ら、在庫表と注文表には以下のように2つのSQLで変更処理が行われます。

・(1)注文番号「5」で、注文表へ新しい注文内容を追加(INSERT)
・(2)在庫表の製品「A」の在庫数を、「100」個減らした値に変更(UPDATE)

 この例では、1つの「注文受付」作業を完了するために、(1)INSERT文、そして(2)UPDATE文という2つのSQLを実行します。この単位が「トランザクション」になります。

 またトランザクションは、ユーザーが明示的にSQLのCOMMITか、ROLLBACKを実行することで終了します。COMMITを実行してトランザクションを終了すると、そのトランザクション内で行った変更内容が完全に確定された状態でデータベースに反映されます。逆に、COMMIT前ならば、トランザクションの変更内容が未確定のため、ROLLBACKで取り消すことができます。

 では、なぜトランザクション単位で変更を確定しなければならないのでしょうか。

 例えば、(1)のSQL(INSERT)を実行後にCOMMITを実行したとします。

 次に(2)のSQL(UPDATE)を実行するのですが、その瞬間に停電や故障が発生してデータベースシステムが停止してしまったらどうなるでしょう。

 データベースシステムを再起動したとしても、(1)だけが確定された状態のままではいけません。処理を行っていたユーザーは、データベースの停止時点で切り離されてしまったために、(2)の処理を続けて行えず、トランザクションは不完全な状態になっています。この例では、100個の注文が確定したのに、在庫数は減っていないわけです。これでは、後で大きな問題になってしまうでしょう。

 このような事態を防ぐために、RDBMSはデータベースが異常終了すると、COMMIT前の未確定な変更内容を全て自動的にROLLBACKするように作られています。処理を取り消すことによって、トランザクションが不完全な状態で終わらないようにしているのです。

●「同時実行制御」により、データの信頼性を確保する

 データベースは共有利用されることが前提です。しかし、ユーザーが多ければ多いほど、複数のユーザーから同一のデータに対し、同じタイミングで利用要求が発生するケースが予想されます。

 この時、無秩序に同時処理を許してしまうと、データの矛盾が発生してしまいます。このような事態を防ぐため、RDBMSには「ロック」という機能が備わっています。

 もしAさんが、在庫表にある製品Aの在庫数を「300」から「200」に変更している途中に、Bさんが「300」から「100」に変更してしまうと、本来の在庫データに矛盾が発生してしまいます。

 そのためにRDBMSは、Aさんが製品Aの行を変更した時点で、「製品Aの行を自動的にロック」します。その直後にBさんが製品Aの行を変更しようとしても、Aさんがトランザクションを終了するまで、Bさんの処理は待機状態になります。このようなロックの仕組みにより、データベース内のデータに矛盾が発生しないようになっています。

更新履歴
【2016/07/05】2016年時点の状況に合わせて、内容を追記更新しました
【2008/07/16】初版公開

●筆者紹介 杉田奏子:株式会社アシスト サービス事業部教育部所属。普段はOracle研修の講師として、主にSQLなどの初心者向けコースを担当。Oracleが初めてという方でも理解して頂けるように、丁寧で分かりやすい解説を心掛けている。趣味は音楽を聴くこと。休日、休暇はライブや音楽フェスに足しげく通っている。

最終更新:7月5日(火)6時10分

@IT

TEDカンファレンスのプレゼンテーション動画

暗闇で光るサメと驚くほど美しい海洋生物たち
波のほんの数メートル下で、海洋生物学者であり、ナショナルジオグラフィックのエクスプローラーかつ写真家のデビッド・グルーバーは、素晴らしいものを発見しました。海の薄暗い青い光の中で様々な色の蛍光を発する驚くべき新しい海洋生物たちです。彼と一緒に生体蛍光のサメ、タツノオトシゴ、ウミガメ、その他の海洋生物を探し求める旅に出て、この光る生物たちがどのように私たちの脳への新たな理解を明らかにしたのかを探りましょう。[new]