RDBとスキーマレスDBの使い分けについて

はじめに

RDBとスキーマレスDBをどういう基準で使い分けるのかを、会社で聞かれた際に答えた雑な回答をメモ書きしておく。

他にも多くの基準があるだろうし、スキーマレスDBというかKVSは様々な実装があり、そのそれぞれが微妙に違うので議論として曖昧な部分はある。

特に、運用面やデータ量がペタバイトクラスになる状況については考慮していない。

僕はSI戦士なので、最終的には金を無限に突っ込んだOracle先生が最高のデータベースであると考えている。

そういうバイアスのある人間の意見だと思って以下の文章は読んで欲しい。

念頭に置いているデータベースについて

このエントリを書くにあたって念頭においているデータベースは以下の通り

最初はRedisをDBと書いていたけども、僕の認識違いが明らかになったのでDBでない方に移した。

念頭に置いていないデータベースについて

このエントリを書くにあたって念頭においていないデータベースのようなものは以下の通り

これらをデータベースだと言う人もいるだろうが、僕はこれらをデータベースとは考えていない。

意見の相違がある方はアンサーエントリを書いて頂けると勉強になるのでありがたい。

スキーマを事前定義するか?

一番大きな違いは、スキーマを事前定義するのか、事後定義つまり、格納されているデータがスキーマなのである、というアプローチをとるのかが違う。

スキーマを事前定義するためには、ストレージされるデータの構造を厳密に規定しなければアプリケーションを作り始められない。

一方で、スキーマを定義しないのであれば、手に入れたデータをJSONか何かにシリアライズすれば、とりあえずDBに格納できる。

つまり、これから作ろうとするアプリケーションをどれだけ厳密に設計したいか?というのが、最初の使い分け基準になる。

トランザクションを使いたいか?

次にトランザクションモデルが違う。

RDBでは、トランザクションを使えるので複数のデータを追加したり更新する時の整合性を取るのが非常に簡単だ。データの整合性を保障するのはデータベースの役割となる。

一方で、スキーマレスなDBの殆どはまともなトランザクションをサポートしていないので、複数のデータを追加したり更新する時の整合性を取るのはアプリケーションコード側でやらなければいけない。

トランザクションモデルの違いは、DBに格納するデータ構造の違いにも表れる。

RDBでは、ユーザや、部署、会社のようないわゆるマスタデータは、それぞれ正規化して独立したテーブルにするのが望ましいとされる。これは、ユーザと部署と、その連関テーブルを同時に更新するのが容易いからだといえる。

一方で、スキーマレスなDBでは、一つのビジネストランザクション内で必要なデータは一つの塊として保存してしまうのがよい。

データは正規化されている訳では無いので、複数のビジネストランザクション間で、同じ筈のデータが同じでなくなってしまう可能性はある。それが問題になるようなアプリケーションではスキーマレスDBを使わなければいい。

これから作るアプリケーションにおいてトランザクションは必要か?必要ない場合に、データが非正規なままでも問題が置き辛いようなアプリケーションか?が二番目の使い分け基準になる。

高度なクエリ言語を使いたいか?

3つ目の使い分け基準の話は、DBの実装によって違うのでおおまかな話になるが、クエリの複雑さの話だ。

RDBでは標準化された極めて高水準で高機能なSQLを使える。集合論に基づいて設計されたSQLはDBというデータの集合を操作するために最適化された構造をしている。

一方で、多くのスキーマレスDBには、それ程高水準なクエリ言語は搭載されていない。

ちょっと日付で範囲クエリが使えるだけで優位性があるとみなされるレベルだ。

多くの場合は、KVS等と言われるように、DBに格納されているモデルの特定のフィールド、つまりキーを基準に1:1でデータを取出せるだけだ。集合に対する操作が必要なら、アプリケーションコードの中で、mapだのreduceだのと言った関数を駆使することになる。

データの量が十分に少なければ、アプリケーションコードで集合を操作すること自体が問題になることはないだろう。

一方で、データの量が大きい場合、つまりメモリに乗り切らない程度に大きくなる場合、アプリケーションコードとして適正に動作する集合操作のコードを書くのは飛躍的に難しくなる。一度に操作しきれないので、部分的にファイルに書きだしたり、DBからデータを少しずつ取り出しながらソートしたりといったコードを書くのは、恐ろしく難しいので出来れば避けるべきだ。

更にデータ量が大きい場合、つまりデータベースを分散化せざるをえない程度に大きくなる場合には、さらに別な手段を考える必要がある。これは、ビッグデータ界隈の話になるので、そちらについては言及しない。

まとめ

以上をまとめると、RDBとスキーマレスDBの使い分けの基準は3つ

  • スキーマを事前定義するか?
  • トランザクションを使いたいか?使わない場合、それに伴うデータモデルのあり方を許容できるか?
  • 高度なクエリ言語を使いたいか?