新卒のペーペー目線で見たMongoDB

2週間の新卒研修を終え、ついに部署に配属された。事前に聞いてはいたものの、私の配属先のプロジェクトで使われている技術は私の技術スタックと全く被っていない。文字通り、一ミリも被っていない。言語からフレームワーク、DBに至るまで、だ。今日はそんな中からDBについて取り上げて色々と語ってみたいと思う。語ってみたいと言ってもまだ一週間しか触っていないので大したことは言えないのだが、少なくとも新しくプロジェクトに入った人間がそれをどのように感じたかということは残しておく価値があるかなあと思った次第だ。 さて、肝心のDBとはMongoDBだ。代表的なNoSQLの一種で、私も名前を聞いたことくらいはあった。しかし、今までRDBでやってきた私としては全く名前以外に全く馴染みはない。そんなMongoDBを一週間触った感想を少し述べたいと思う。

※あらかじめ断っておくが、MongoDBを触ってまだ一週間の人間なので知識に間違いがあるのはご容赦されたい。今後のためにもマサカリは真正面から受け止めるつもりだ。

1. 思ったより抵抗はない。

これは正直な感想として、想像していたよりも抵抗はない。NoSQLというとRDBというメインストリームから外れた異形の者たちという印象があったのだが、全然そんなことはない。データの形式はキーバリュー形式で、平たく言えば単なるJSONだ。値には配列も入るし自由度が高い。そしてクエリについてもそこまで抵抗はない。例えば以下のような感じだ。

db.test.findOne({ id: 1 })

どうだろうか?MongoDBを触ったことがなくても、なんとなく「testというテーブルからidが1のレコードを一つ引っ張ってきてるんだな」と分かる。形だけ見ればオブジェクト指向言語のコードのようだ。クエリ言語とプログラミング言語の差があまり感じられない。むしろMongoDBから入った人間がSQLを見た時の方がエキゾチシズムを感じることだろう。

2. 用語が耳慣れない

MongoDBで使われている用語は一般的なRDBのそれと異なる。対応関係は

  • テーブル → コレクション
  • カラム → フィールド
  • レコード → ドキュメント

といった具合だ。特に最後のドキュメントなんかはなかなか慣れない。ドキュメントと言えば「公式ドキュメント」等でも使うし一般的な言葉だ。MongoDBのデータ構造はRDBのようにシンプルな二次元表には収まらないので特殊な用語法を定義する必要があったのだろう。

3. システムを把握しづらい

これが本稿のメインだ(じゃあ先に言え)。例えば、RDBを採用しているシステムならER図を見てどんなテーブルがあるか、テーブルとテーブルはどのような関係かを確認して、システムの概要をざっくりと把握できる。あくまでざっくりと、だが。しかし、MongoDBではそれはできない。 理由は二つある。 まず一つに、外部キー制約などがないことだ。MongoDBのコレクションには他のコレクションとの関係を明確に示すような制約を課す機能がない。無論、コレクション同士を結合することはできるので特定のキーを外部キーとして定義することはできるのだが、それはMongoDBの機能ではない。人間が勝手にこのキーはあのコレクションとの間の関係を示す外部キーだ、と意味づけしているだけである。

第二に、フィールドがドキュメントごとに異なる。用語のせいでよく分からない?RDBで言うならば、「レコードごとにカラムが異なる」と言うことだ。これはもうパニックだ。先ほどはシステム全体の話をしたが、今度は一つのテーブルに着目するとしよう。RDBであればテーブルに定義されているカラムを見て、なるほどこのテーブルにはこんなカラムがあるのか。このカラムはNULLじゃダメ(必須)なのか。などなど、そのテーブルが何を表し、どんな役割を果たすのかを概ね把握できる。しかし、MongoDBはコレクションごとに値の内容が異なる。例えば一つのコレクションに

ドキュメント1: { "fruits": ["apple", "banana", "orange"] }
ドキュメント2: { "country": "Japan", "lang": "Japanese" }
ドキュメント3: { "hoge": true }

こんなバラバラのドキュメントが格納されていても何も言わない。何も聞かせてくれない。 フィールドの数からキーから何から何までバラバラだ。ドキュメントごとにフィールドが違うのだから、ER図のエンティティのように一つのコレクションの構造を統一的に表記することが難しい。「とりあえずテーブル定義見るか」ができない。

まとめ

まとめると、MongoDBは「ドキュメントがしっかりしていないと辛い」DBだと感じた。ここで言うドキュメントは文字通り文書のことだ。コレクションの中に好き勝手どんなJSONでもぶちこめてしまうので、このコレクションにはこうこうこういう役割があって、どんなデータを格納して、フィールドは...みたいな説明をしてくれないと収集がつかなくなりそうな気がする。コレクションの内容をページングしていって、どんどんとフィールドが変わっていく様は私にはカオスであった。それはまさしく清濁併呑のリヴァイアサンであった。この神のごとき寛容さを鎮めるには制約が必要だ。その機能がMongoDBの中に内包されているのか、それとも人間の祈りに依るものなのか。私にはまだ分からない。