ドキュメント指向DBとそこからMySQLが取り入れたものを考える

 ドキュメント指向DBは任意のドキュメントの形でデータを扱うDBだ。MongoDBならそのドキュメントは基本的にJSONである。JSONの形でデータを扱ってなにがうれしいかというと、一件のデータをスキーマレスな形で扱えるということである。これはRDBでいうところの、一つのテーブルに、バラバラなカラムを持ったデータをつっこめるということだ。でもそんなのは極端な話で、もっと簡単なところでは、カラムの型としてリストが持てる上に、それが容易に検索に使えるところがイカしてると思っている。

 これまでのRDBではリストのような、長さの決まっていない型を持つのは難しかった。そういうことができるように工夫されたRDBもあるにはあったが。ないゆえに一対多や多対多をやるには中間テーブルを組んだりするのが流儀だった。
 たとえばこのブログの記事を従来の方法でRDBに保存することを考える。タイトル、日付、本文は文字列や日付のような型でカラムを作って、一つのレコードに保存できる。タグは新たにテーブルを作って、タグの数だけレコードが従来のまっとうなやり方だろう。JSONでそれらをそのまま表現してみると下のようになるだろう。タグは三つ作るとして。
{

"_id": 1,
"title": "タイトル",
"date": "2017-5-11 10:12:123.11111",
"body": "本文だよーん"
}

{

"ref": 1,
"tag": "タグ1"
}
{
"ref": 1,
"tag": "タグ2"
}
{
"ref": 1,
"tag": "タグ3"
}


 一件のブログ記事を表現するのに、二つのテーブルにまたがって、なおかつ二つ目のテーブルでは三件のレコードを必要としている。タグの一致する記事を探したければ、一致タグを探してテーブル結合して、という手順を踏む必要がある。
 ではでは。ドキュメント指向DBのMongoDBで一件の記事の保存を考えてみる。下記のようになる。
{

"_id": 1,
"title": "タイトル",
"date": "2017-5-11 10:12:123.11111",
"body": "本文だよーん",
"tags": ["タグ1", "タグ2", "タグ3"]
}

 一件のブログ記事が一件のドキュメント(RDBでいうところのレコード)にまとまる。シンプル。
 たとえば"タグ1"を持っている記事を検索したいってのはどうするのかというと下記のようになる。
db.entries.find({"tags": "タグ1"});

一件のドキュメントにタグまでまとまっているので結合はしない。シンプル。
 MognoDBは結合をもっていない(はず)なので、DB側でリレーションを組むことはできない。まあDB側でJSを動かせるのでやりようはあるが、今回のようなケースではなくても十分足りている。
 データをそれなり正規化して、各テーブルを用意して関係を組んでいくというところではRDBはベストなソリューションだろう。一方で、データをシンプルな表現で保存したり検索したい、関係を組んだりはしないよ、という要求があった場合にはMongoDBのような形式のドキュメント指向DBはかなりいいソリューションだと思う。DBとデータのやり取りをするとき、シンプルな形で扱うことができるから。

 JSONでデータを表現できるのは、場合によってはとてもクールなことだと思う。ここで書いた例では、ブログ記事一件を一件のデータとして、シンプルな構造で扱えた。
 たぶんそんな機能がイカしてるとMySQL開発の面々も感じたんだろう。MySQLでもカラムの型としてJSONがサポートされるようになって少し経っている。これによって、MongoDBで示した例と似たようなことができるようになっているのは前のブログで書いた。
MySQLのデータ型にJSON型が加わっていた

 趣味でやっているところでは関係を組むとかあまり必要ではないので、趣味で使うDBのデフォはMongoDBになっている。仕事では全部をMongoDBにしちゃうなんてことは、機能を検討するとそうもいかないことは結構ある。それでもシンプルなWebアプリケーションの構築もぼちぼち来る。そういったときはドキュメント指向DB、あるいはMySQLでJSON型のカラムを使うことも考えていきたい。MongoDBは銀の弾丸ではないが、かといって従来のRDBにもそれは言えることだと思っているがはてさて。
comment: 0