MongoDBの使いどころ

Pocket

NoSQLの代表格となっている、MongoDBですがよく使われているけど、NoSQLという特徴以外に、その他は、あまりよくわかっていなかったのとMongoDBは、よく高機能と言われますが、具体的に何が高機能なのか、よくわかっていなかったので、調べてみました。

MongoDBの特徴

RDB以外のデータベース管理システムを指すNoSQLと呼ばれれるデータベースに分類されるものです。
RDBは列構造でデータを保存しますが、MongoDBは、JSONを拡張したBSON形式でデータを保存します。
配列や階層構造などのリッチなデータ構造に対応しています。 BSONはJSONでは表現できないバイナリデータを扱うBinData型や、Date型などのデータ型にも対応しており、MongoDBはこのような構造的なデータが扱えるドキュメント指向データベースに分類されています。

MongoDBの機能

スキーマレスで柔軟な構造を表現出来る

RDBでは、カラムやデータ型、長さまでのスキーマを厳格に定義するのに比べてると、MongoDBでは、スキーマを定義する必要はありません。レコードごとに異なる構造でも許容されます。
また、ドキュメント指向の嬉しいことは、配列や階層構造などリッチなデータ構造に対応しているので、KVSに比べると1対多を扱いやすいことです。

負荷分散とスケールアウト

MongoDBのシャーディング(水平分散)は、複数データベースにおいて、データの受け持ち範囲をシャードに分割することで効率よく負荷分散します。キーによってデータをノードに分散することができ、またノードを動的に追加しデータの自動バランシング機能もあります。
RDBでもシャーディングを行うことができますが、アプリケーション側での実装が必要だったり、データベース単体で行うことができない、できても手間がかかることが多いですが、 MongoDBでは非常に手軽にシャーディングの設定を行えます。また、レプリケーションと組み合わせて、負荷分散と冗長化を両立できます。

MongoDBを使う上での注意

いいことばかりのような気もするMongoDBですが、柔軟であるが上に注意しなくてはならない点があります。
一つ目は、トランザクションがない点です、複数のドキュメントを一貫性をもって更新することができません。ミッションクリティカルで複数のテーブルの更新を保証しなければならないようなシステムでは、無難にRDBを選択したほうがいいでしょう。
二つ目は、外部キー・結合が無い点です。これは、他のドキュメントへの参照はアプリケーションで実装する必要がありということです。また当然ながら、外部キー制約もないため、テーブル間の整合性が重要なシステムには向いていません。また複数のドキュメントの内容を結合して取得することはできません。
三つ目は、スキーマレスで柔軟であるが上にアプリケーション側で制御が必要になるという点です。どのようなキー名でデータが入っているかわからないく、またデータ型もわからないので、アプリケーション側でその差を吸収する必要があります。またスキーマレスなので、意図していない構造のデータでも登録できてしまいエラーが発生しません。設計を厳格に管理しないと、どのようなデータが入っているかわからなくなり、保守性の低下をまねく恐れがあります。

MongoDBと相性の良さ気な用途

MongoDBの利点をまとめると、スキーマレスとドキュメント指向やスケーラビリティ機能とレプリケーション機能などがあります。
よくあるパターンとしては、アクションログです。
データサイズの制限があるコレクションであるCapped Collectionや一定期間が経過すると削除されるTTL Collectionといった機能が活用されています。そのデータをダンプしてAWSのS3にあげて、Hadoopクラスタで集約してHiveで問い合わせをするといった解析基盤の始めのデータの落とすところに使ったらいいかも。

RailsでMongoDBを使ってみた

Railsでアクションログの保存先にMongoDBを使うためには

  • Gemを追加する
  • 設定ファイル
  • アクションログ用のModel作成
  • ログを落とすメソッド作成

こんな感じでやっていきます。

Gemを追加する

まずは、RailsでMongoDBを使うためにMongoDB用のGemを追加します。
下記の2行を追加してインストールしてください。

gem "mongoid"
gem "bson_ext"

設定ファイル

次に、設定ファイルを生成するために次のコマンドを実行します。

$ rails g mongoid:config

そうすると、config/mongoid.ymlに設定ファイルが作られます。中身はそのままでおっけーです。

アクションログ用のModel作成

そして、MongoDBへ接続するmodelをgenerateするには下記のようにします

$ rails g mongoid:model action_log

そして生成されたmodelにフィールドを追加しましょう

class ActionLog
  include Mongoid::Document

  field :datetime, type: DateTime
  field :user_id, type: String
  field :controller, type: String
  field :method, type: String
  field :body, type: String
end

ログを落とすメソッド作成

最後に、controllerの各アクションが呼ばれるときにアクションログをMongoDBに保存することメソッドをconcernsに追加します。

module Log
  extend ActiveSupport::Concern

  included do 
    before_action :save_log

    def save_log
      ActionLog.create!(
        datetime   : Time.now,
        user_id    : current_user.id,
        method     : params[:method],
        controller : params[:controller],
        body       : params
      )
    end
  end
end

あとは各コントローラでincludeしておしまいです。

Pocket

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>