2011年6月10日金曜日

MongoDBと戯れる その2

今回は覚書、読むだけじゃ覚えないので、書きながらサマリーしてみる。

そもそも概念がちょっと違う。

普通にデータベースを持つ

Collection

CollectionというのがRDBMSでいうところのテーブルに値する。
  db.students --> studentsというcollectionが存在する。
内部表現はJSON形式であらわすことができる。実はBSONという形式ぱっと見た感じ、JSONだけどちょっと違う。
よりオブジェクト指向的な形になっている。
 db.students
  name: 'yas',
     addressHd: {
      address: XXXXX,
      city: Edogawa,
      prefecture: Tokyo
     }

参照

例えば、別のcollectionに対して参照を持つ場合はfor_【collection名】と書けばよい。
 db.students
    name: 'yas',
    for_course:  #参照をあらわしている。

 db.course
  name: 'Biology'
参照するよりも、埋め込んだほうが早いらしい。これは非正規化して速度稼ぐのと同じ理屈。
 1:Mongo的な非正規化
  db.students
    name: 'yas'
    address: 'XXXX'
    score: 
     { name: 'biology',
     grade: 4.0},
 
 2:Mongo的な正規化
  db.students
    name: 'yas'
    score: 
      { for_cource
          grade: 4.0}
    
    db.cource
      name: 'biology'
呼び出し側を考えれば簡単
1の場合: print(student.cource)
2の場合: print(student.score[0].for_course.name)
--> 内部的には、student.scores[0].for_course = db.courses.findOne({_id:_course_id_to_find_});
こういうノリのよう。
なので、場合によって使い分けたほうが良いはず。
非正規化する際、Gridとかのデータとかは出来上がったものを持てば良いだけなので問題ない。
それ以外の属性に依存する形の場合にはちょっと考えたほうが良い。2でガツガツ呼ばれる(1000)とか来ると
といくらキャッシュとはいえ1秒以上かかってしまうので。そこら辺は良く考えて!!だそうだ。

一般的なルール

  • ノード的にトップレベルのものは独自のコレクションを持つほうが良い
  • LineItemは(要するに詳細情報とかは)埋め込んどけ。
  • Object contains A の形になる場合は埋め込んどけ。
  • Many to Many なる場合はどうしようもないので、参照で持つしかない。
  • 集計とか統計とかするのであれば埋め込んどかないと時間かかって仕方ない。
→要するに基本的には埋め込んどけ。MtoMをどうしても表現しないといけなくなったときだけ参照使え。

indexはRDBMSと同じノリで張れば大丈夫。

  • _idは勝手にindexが張られている。これはputした瞬間にMongoが突っ込んでくれる。サロゲートキー
  • sortされるところはindexはっといたほうが良い→これは要検証。

tree表現とかも使える。


結構用意されていて、treeとしても使える。
tree情報のキャッシュには良いかもしれない。

デフォルトポート

27017

シェル

Mongoがそれにあたる。JavaScriptなシェル。これ面白い

制約

32bit環境においてstorageの限界は2Gbyteまで。

ちょっと試してみた結果

環境WindowsXP 32bit CPM core2 DUO Memory:4G
使用言語MongoDBのJavaドライバー経由でJava
対象件数3万件
ローカルストレージの変遷72,920byte
実行時間5891ミリ秒
使用メモリ量70Mぐらい

実験に使ったコード

ちなみにthis.excは適当に書いてみた。ラッパー
 long t1 = System.currentTimeMillis();
    System.out.println("計測開始!!" + t1);
    for (int i = 0; i < 30000; i++) {
      DBObject doc = new BasicDBObject();
      String str = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
      doc.put("name", str);
      doc.put("name_1", str);
      doc.put("name_2", str);
      doc.put("name_3", str);
      doc.put("name_4", str);
      doc.put("name_5", str);
      doc.put("name_6", str);
      doc.put("name_7", str);
      doc.put("name_8", str);
      doc.put("name_9", str);
      doc.put("name_10", str);
      doc.put("name_12", str);
      doc.put("name_13", str);
      doc.put("name_14", str);
      doc.put("name_15", str);
      this.exc.insert(doc);
    }
    long t2 = System.currentTimeMillis();
    System.out.println("結果:" + (t2 - t1) + "milSec");
    System.out.println("レコード数" + this.exc.getCount());
まだまだわからないことだらけだ。もっと検証を進めていこう。

0 件のコメント: