データベースに関する世界観です。
そもそも、データベースとは何か。
それは、「必要な時にさっと出せるように、データをきちんと整理して備えておく仕組み」のこと。
データベースをプログラムから使う際には、データベース管理システム(DBMS)と呼ばれるソフトウェアを使う。
データベースの勉強がしたい人は、無料のSQLiteなどを使って、自分の持っているデータを整理し、簡単に取り出せるような構造で格納する、という練習をするとよい。
データベースのついて本質を捉えるためには、「データを守る」という視点を持つことです。
データベースとは、データを一元的に格納し、どこからでも参照できるようにするための「在り処」を提供することです。
まず、テーブル単位のことで言うならば、制約を使うことで、主キーや外部キーなどの一意性などを保ち、間違ったデータが格納されないようにします。データテーブルがきちんとした規則に基づいて整理されるように、テーブルを正規化し、リレーションを用いて複数のテーブルからひとつのテーブルを自動作成します。
このようにすることで、テーブルは常に正しい状態であり、CRUD操作を行っても必ずテーブルがその設計のもとで存在し続けるようにします。
また、トランザクションによってデータの更新時に矛盾が起きないようにし、アトミックな変更がもし失敗してもロールバックして元の状態に戻すことで、「データ更新時に絶対にデータの破損が起きないようにする」という操作を行います。
また、複数のユーザーが同時に参照する並列処理において、排他制御によってロックをかけることで、別々のユーザーの同時参照や同時変更によってデータの矛盾が発生しないようにします。
この上で、全体バックアップと差分バックアップを行うことで、もしデータが破損しても、データが破損する以前の状態から復旧できるようにします。
そして、データベースの可用性を高めるために、データをコピー(レプリケーション)したり、ジャーナルファイルにログを記録したり(ジャーナリング)することで冗長性を構築します。もち、一部のデータベースが破壊されても、それを複製からバックアップできるようにします。また、一部のサーバが働かなくなっても、別のサーバが代わりに働く(フェイルオーバ)するようにします。
このように、データベースの多くの機能は、「データを守ること」のためにあります。
データベースを用いるもうひとつの理由は、高速化のためです。
データベースを用いず、テキストファイルなどを用いてPerlなどで検索を書ける場合と、SQLによるデータベースサーバを使う場合の違いは、パフォーマンスにあります。
一般的に、SQLを用いた方が、パフォーマンスの意味で高速化します。また、複雑な処理を行う場合、単にテキストファイルを解析するよりも、データベースを使った方がプログラミングも容易になることがあります。
また、データベースは、SQLのクエリを用いて、選択、射影、結合などの関係演算ができます。この関係演算は、主キー、外部キー、候補キーなどを用いて、リレーションに基づいてテーブルを結合したりできます。また主キーや候補キーなどの従属といった考え方により、正しいテーブルの分割状態に正規化することができます。
また、インデックスを用いることで、テーブルの参照が高速化します。状況によって、インデックスをつけた方が高速化する場合と、インデックスをわざわざ更新しなければならないために逆に低速化する場合があるので、注意する必要があります。
データベースを使うことで、たとえば何百万単位になったデータであっても、高速に参照することができます。
Webなどの分野では、データベースは、たくさんのユーザーが頻繁かつ同時にデータを書き換える時に使います。
データベース管理システムの持つ、排他制御やトランザクション処理といった機能により、たくさんのユーザーが頻繁かつ同時にデータを書き換え、参照しても、安全にデータを取り出したり格納したりすることができます。
Webサーバーが、HTMLという「画面デザイン」を担当するものだとしたら、DBサーバーはテーブルという「定型的データの集積」を担当するものです。これにAPサーバがプログラミングという「ロジック」を担当して、多くのシステムは構築されています。
データベースの重要なポイントは、「データベースやテーブルの設計」「高速な処理」「並列処理における保護」「トランザクションの管理」が大きく言えると思います。
データベースやテーブルを上手く設計することで、クリーンにデータ管理ができます。
また、何万件・何億件とデータがあったとしても、その件数に関係なく、高速な処理ができます。
そして、並列で、誰かがデータを操作した場合、ほかの誰かが同時に操作していたとしても、ロックをすることでデータを保護します。
最後に、データベースにおけるトランザクションを管理することで、もしデータの更新に失敗しても、データベースすべてが破損するリスクを軽減できます。
この4つのポイントに加えて、冗長化構成を取ることで、データが破壊されても別の場所から復旧できるようにします。
データベース管理システムを使う主な理由は、実際のデータベースの物理的構造を変えてもソフトウェアは変わらない、ということです。
データベースを格納するデータセンターの物理的な仕様を変えても、ソフトウェアの方は変わらずにすみます。つまり、「どんなデータベースであっても、また変更があっても、その差異や変更を吸収できる」ということです。
いくらデータセンターの物理システムを独自に構築しても、また社外データセンターを社内データセンターにしても、ソフトウェアはSQLなどの言語インターフェースを用いて、同じようにシステムのデータにアクセスできます。
また、データをひとつのシステムに一元管理でき、ソフトウェアの開発が容易かつ堅固になります。そして、データベース管理システムの持つさまざまな高信頼性機能を使うことができます。
RDBMSを参照のこと。
また、データベースを使うことによって、ものすごく大量のデータから、ひとつのSQLクエリで、いっぺんに全てのデータを検索することができる。
リレーショナル(関係)データベースモデルでは、データは表によって管理される。単純な表のテーブルで管理されるため、大量のデータがあった時に目的の表を検索しやすく、また新しいテーブルを生成しやすい。だが、データベースを構築する際に前もって表の構造(カラムやレコードの要素)を決めておかなければならないという欠点もある。
このように、データベース管理システムを使ってデータを一元管理することで、全てのデータからひとつのSQL文で膨大な検索をかけて、高速かつ安全に目的のデータ構造を取り出すことができる。
データベース管理システムを使うメリットのひとつは、パフォーマンスが良い、ということ。
億単位の膨大なデータがあったとしても、SQLクエリを発行することで、瞬時にデータを検索できます。
性能と速度はデータベース管理システムの大きな課題であり、多くのデータベース管理システムが、とても高いパフォーマンスを誇ります。
データベースインデックスを参照のこと。
データベース管理システムを使うもうひとつのメリットは、頻繁に更新しても壊れないということ。
データベース管理システムには、トランザクションや排他制御の機能があり、とても多くのタスクから頻繁に更新されても、データは壊れず、整合性を保ちます。
このため、不特定多数が常に更新するようなWebアプリケーションでは、データベースを使うメリットがあります。特に、巨大掲示板やSNSのようなサービスでは、不特定多数が毎秒のようにとても多くのタスクでデータを更新するため、データベース管理システムを使わなければいけません。
並列処理を参照のこと。
また、3つ目のメリットとして、複雑なSQL文を組み立てることで、柔軟にデータベースの表を抽出できる、ということが言えます。
SQL文は一見難しくて分かりづらいですが、慣れると柔軟性がありさまざまな機能があります。
SQLクエリを工夫することで、柔軟にデータを取り出したり、あるいは挿入・削除・更新したり、テーブルそのものを定義したりすることができます。
SQLを参照のこと。
また、RDBMSの大きな特徴として、リレーショナルモデルをデータモデルに採用していることが言えます。
リレーショナルモデルでは、「表」と「属性」を用いてデータを表現します。
リレーショナルモデルでは、ひとつのリレーションが全てのデータを表現するのではなく、ひとつのリレーションはひとつの事項に関するデータを格納し、場合場合によってそのリレーション同士を結合することでデータを操作します。
たとえば、岡田さんと山田さんが数学部、斉藤さんと松田さんが医学部に入っていたとして(名前と学部のテーブル1)、数学部の学部長が島村さん、医学部の学部長が松本さんだったとして(学部と学部長のテーブル2)、このデータを結合して新しい列が3つ(名前、学部、学部長)の表を作る(学部という共通する同じ要素によって二つのテーブルを結合した新しいテーブル3)、といったことができます。
この時、内部結合では、テーブル1の学部の要素にテーブル2の学部の要素が、共通する同じ要素を元にして対応する場所に適切に挿入されます(複数重複する場合でも自動に結合される)。そのため、岡田さんと山田さんの行の学部長には島村さん、斉藤さんと松田さんの行の学部長には松本さんが新しい列「学部長」として挿入されます。
このように、テーブルの同じ要素などから複数のテーブルを結合することができます。また、どちらのテーブルにも主キー(IDなど)が設定されていれば、主キーを用いて結合することもできます。
リレーションを参照のこと。データベースには、「冗長化」という言葉が良く使われます。これは「データを何重にもコピーすることで、破損しても回復できるように保つ」ということです。
また、定期的なバックアップとジャーナルファイル(ログファイル)を上手く使うことで、データベースが万一壊れても復旧できるようになっています。こうした機能があることが、データベースを使う主な理由です。
クラスタ・分散・高信頼システムを参照のこと。
データベース管理システムには、他にも、データの整合性や妥当性をチェックし、壊れることなくデータを保ち続けるための機能があります。
こうした機能を提供するために、データベースは常にデータの整合性を確保しなければなりません。そのため、トランザクションという機能を用いて、不可分の処理を整合性を保ったままでデータを更新した場合にのみコミットを行い、コミットできなかったときは必ずロールバックを行って整合性を保つようになっています。
また、排他制御を行うことで、ユーザーがデータを読みだしている時は、ロックをかけて別のユーザーがデータを更新できないようになっています。
データベース入門を参照のこと。また、他にも、ユーザーによってアクセス権限を与えて、安全にデータにアクセスする機能などがあります。ユーザーごとにデータを蓄積し、他のユーザーからはそのデータにアクセスできないようにした上で、それぞれのデータベースをユーザーごとに管理し、適切にアクセス許可を与えることができます。
また、それぞれのユーザーに異なるレベルでの「権限」を与えることができます。たとえば「全権限を与える」「テーブルの作成」「レコードの削除」「テーブルの削除」「レコードの検索」「レコードの追加」「レコードの更新」などの権限をそれぞれのユーザーで個別に与えることができます。これはWebサービスにおいて、管理者権限と一般ユーザーの権限を分ける上で役立ちます。
階層型データベースは、UNIXのディレクトリのように、データベース全体がひとつのツリーとなって、ひとつのデータについてひとつの親が対応するデータベースです。
アクセスするのが簡単であるという特徴があり、過去には汎用機などにおいてよく使われました。
ネットワーク型データベースは、階層型データベースの亜種のようなもので、ひとつのデータが複数の親を持つことができます。
XMLネイティブデータベースは、XMLの記述要素をそのままデータとして格納することのできるデータベースです。
オブジェクト指向データベースは、オブジェクト指向言語においてのデータ構造である「オブジェクト」をそのまま格納することのできるデータベースです。
自分の書いたブログ「神々とともに生きる詩人」2021/01/27より。
Webにおいては、「データベース管理システム」を用いてデータの管理を行う。
たとえば、掲示板を作るのであれば、投稿された投稿内容をデータベースサーバに登録し、表示する際にはそれを参照する。
リレーショナルデータベース管理システム(RDBMS)では、二次元の表によってデータを管理する。
PythonやR言語でいうデータフレームも、これに準ずるものである。(Pandasなどでは、二次元のラベル付きデータ構造であるデータフレームを用いる)。
RDBMSでは、「リレーション」と呼ばれる仕組みを用いて、小さく細分化(正規化)されたデータを、結合したり、選択したり、射影したりして、さまざまなデータテーブルを自動的に作成して処理を行う。
データベース管理システムでは、まず、巨大なデータを検索する時に高速で、同時にSQLクエリを用いて処理を行うという、パフォーマンスと柔軟性のメリットがあり、同時に、複数のプログラムから操作しても、排他制御などにより矛盾が発生しないという、矛盾のないデータの整合性を保つといったメリットもある。
また、データが破壊されることをできるだけ防ぎ、破壊されることがないように復旧したり、データを複製する冗長化や、ひとつのサーバが落ちても別のサーバが代わりを務めるという、フェイルオーバと呼ばれる仕組みもある。
このような信頼性を「可用性」と呼び、信頼性ではなく効率を重視したクラスタのことを「HPC」と呼ぶ。
HPCにおいては、どれだけのマシンで並列処理ができるかが重要になる。
自分の書いたブログ「神々とともに生きる詩人」2021/02/02より。
トランザクションとは、不可分の処理のことで、データベースではトランザクションによってデータ処理を行い、失敗すればロールバックする。
このようにすることで、データの矛盾のない状態を保つ。
データが破損すれば、定期的なバックアップと、詳細な記録であるジャーナルファイルから、ロールフォワードすることで復旧させる。
複数のユーザーから同時に処理がされる場合、排他制御を行うことで、データの破損を防ぐ。
データベースの定義は、スキーマで行われる。
データベースにおけるテーブルの、列をカラム、行をレコードと呼ぶ。
リレーショナルデータベースでは、テーブルを選択、射影、結合により、もとのテーブルから自動的にテーブルを作成する。
これをリレーションと呼ぶ。
また、テーブルとは別にユーザーに見せるために、ビューを作成できる。
ビューの実体はSQL文。
テーブルには、その行を一意に特定できる主キーや、結合のために使う別のテーブルの主キーを指定する外部キーなどがある。
制約は、たとえば必ず一意に特定できるように、重複した値を許さない一意性制約、ヌル値を排除する非ヌル制約、一意性制約と非ヌル制約を組み合わせた主キー制約、外部キーとして矛盾しないようにする外部キー制約がある。
また、その行を一意に特定できるキーの列あるいは列の組のことを候補キーと呼ぶ。
たとえば、市町村のテーブルがあり、都道府県名と市町村名の組み合わせで、行を一意に特定できるなら、この2つの組が候補キーとなる。
後日注記:この場合、{市町村名, 都道府県名}が候補キーとなります。
テーブルの正規化は、データの重複や矛盾を排除するために、候補キーなどの考え方を用いて、テーブルを正しい規則に分割すること。
非正規形、第一正規形、第二正規形、第三正規形がある。
E-R図は、実体と関連を表した図で、対応関係(カーディナリティ)の記述には、一対一、一対多、多対一、多対多の4種類のリレーションシップがある。
たとえば、掲示板に対してたくさんのコメントがつくような場合、一対多のリレーションシップがあると言う。
Railsなどでは、has_many(たくさんの子がある)やbelongs_to(ひとつに所属する)などとも呼ばれる。
データベース入門も参照してください。
僕は、できることならデータベースを勉強してデータサイエンティストになりたいです。
現在のIT社会は、データであふれています。特に、データベースはWebでも基幹システムでも大きく使われており、データベースに精通することは、IT技術全体に精通することを意味します。
また、最近では、人工知能・AIの技術が向上したことにより、ビッグデータなどの巨大なデータを、Pythonのような人工知能で学習させることで、「人間の代わりに機械が考える」ということができるようになっています。
これからのITは、長い間「データの時代」が続くと思います。できれば、データサイエンティストにでもなれれば良いなと思っています。
データベースとは関係がないかもしれませんが、プログラミングを行う上でも、データがどのような構造を持っているかは重要になります。「劣ったエンジニアはコードに悩むが、優れたエンジニアはデータ構造に悩む」と言います。
AI・データマイニングを参照のこと。
Webでデータベースを使う際に、HTMLファイルを使うのか、それともSQLデータベースサーバーを使うのかは、使い分けが必要です。
まず、管理者によって更新されない限り更新されないような、ひとりだけが更新するサイトにおいて、PHPなどを使った動的な処理を行わない(HTMLを直書きする)のであれば、SQLサーバーは必要ありません。
確かに、PHPなどでHTMLファイルになんらかの動的なコンテンツ処理を加えたいのであれば、SQLサーバーのほうがプログラミングはしやすいかもしれません。
ですが、逆にSQLサーバーを使った場合のほうが、たとえばテキストエディタですべてのファイルに正規表現の検索・置換処理などを行うのは簡単ではなくなります。
なので、静的なWebサイトであれば、SQLサーバーを一切使わなくてもいいでしょう。
SQLサーバーを使うべきなのは、頻繁に不特定多数から更新されるような処理を、PHPなどの動的なプログラミング言語を使って実現する場合です。
このような場合にも、テキストファイルを使った掲示板のように、SQLサーバーを使わなくてもテキストでデータを管理することは可能です。
ですが、不特定多数から頻繁にアクセスされる場合には、素直にPHPとMySQLを使ったりしたほうが、高度なプログラミングができますし、テキストファイルで行うよりもさまざまな機能が使えます。
大規模になってもパフォーマンスを維持したくて、どんなに閲覧者が増えてもいいようにしたくて、同時にサーバーにアクセスしてさまざまなアカウントで投稿を行うような状況に対応したい場合は、SQLサーバーを使ったほうが断然便利です。
SQLサーバーを使うかどうか検討するなら、そのように「HTMLファイルだけを使う」か「簡単なテキストファイルにデータを保存して読み書きする」か「大規模なSNSなどのWebサービスを構築するためにRDBMSを使う」かを使い分けるといいでしょう。
また、作りたいWebサービスがどのようなものであるかをよく考えてみましょう。簡単なツールを作りたいのであれば、データをファイルに保存して読み書きしたほうが簡単ですが、逆に高度で複雑なサービスを開発したいのであれば、SQLサーバーやRuby on RailsのようなWebフレームワークを使ったほうがよいでしょう。
データベース入門やデータベースインデックスやリレーションやSQLやRDBMSを参照のこと。
クラスタ・分散・高信頼システムを参照のこと。
並列処理を参照のこと。
Linuxカーネル(ファイルシステム)やLinuxカーネル(IPC)やLinuxアーカイブ・同期・デバイス処理を参照のこと。
複数の小さなリレーションをその都度結合してデータを表現する。
テーブルとテーブルの対応関係(共通する同じ要素)により新しいテーブルを作成する。
内部結合は、両方のテーブルに存在する(一致する行がある)データを結合する。
外部結合は、どちらかのテーブルにしかないデータも結合し、存在しないカラムについてはNULLを格納する。
「実体」と「実体」の間での「関連」を考えて図にする。
データベースの設計をする上で用いられるダイアグラム。
インデックスを作ると検索が速くなるが、更新のたびに常にインデックスを作る処理が必要になる。
トランザクションは不可分の処理のことで、成功しなかった場合はロールバックすることでデータの整合性を保つ。
データベースが壊れても構わないように別のサーバに複製を作る。
どれかのサーバが停止しても別のサーバが代わりを務める。
ジャーナリングはログや変更履歴、レプリケーションはコピー。