# MongoDB ## MongoDBとは MongoDBはクロスプラットフォーム対応のオープンソースドキュメントDBである。 NoSQLでは最有力のDBである。 ### MongoDBの特徴 * データ形式:JSONドキュメントのコレクション * データ容量:RDBMSよりも大容量 * データの整合性:満たさない。(結果整合性=トランザクション処理不可) * データの可用性:満たす。 * データの分断耐性:満たす。 * データの結合(JOIN):不可。 * 得意とする処理:JSON形式ドキュメントの保存 以上から、MongoDBは高速・大容量なJSONドキュメント保存に適する。 ### MongoDBを利用した方が良い場面 * データの整合性よりも速度を求める場合。 * データの耐障害性を高めたい場合。 * スキーマを事前に定義できない場合。(JSONの保存等) ## MongoDBとRDBMSのスキーマの違い ### RDBMS 基本的な考え方は、第3正規形を満たしながら2つのテーブルに分ける。 (例)パスポート **人物マスタ**    人物id(PK) 氏名 **パスポートマスタ** パスポートid(PK) 人物id(FK) 国名 有効期限 ☆実行結果 mysql> select * from people; +----+------------+ | id | name | +----+------------+ | 1 | Stephane | | 2 | John | | 3 | Michael | | 4 | Cinderella | +----+------------+ mysql> select * from passports; +----+-----------+---------+-------------+ | id | people_id | country | valid_until | +----+-----------+---------+-------------+ | 4 | 1 | FR | 2020-01-01 | | 5 | 2 | US | 2020-01-01 | | 6 | 3 | RU | 2020-01-01 | +----+-----------+---------+-------------+ ### MongoDB MongoDBはスキーマレスのため、形式は自由である。 第3正規形を使うと、必ずJOIN処理が発生してしまうため、非効率。 そこで以下の方法が考えられる。 #### 全てのデータを一括保存 > db.people_all.find().pretty() ```json= //Staphaneさん { "_id" : ObjectId("51f7be1cd6189a56c399d3bf"), "name" : "Stephane", "country" : "FR", "valid_until" : ISODate("2019-12-31T23:00:00Z") } //Johnさん { "_id" : ObjectId("51f7be3fd6189a56c399d3c0"), "name" : "John", "country" : "US", "valid_until" : ISODate("2019-12-31T23:00:00Z") } //Michaelさん { "_id" : ObjectId("51f7be4dd6189a56c399d3c1"), "name" : "Michael", "country" : "RU", "valid_until" : ISODate("2019-12-31T23:00:00Z") } //Cinderellaさん(架空→パスポート無し) { "_id" : ObjectId("51f7be5cd6189a56c399d3c2"), "name" : "Cinderella", } ``` 特徴 * 同一構造でないドキュメントも一括保存可能である。 * どの要素がパスポートについてで、どの要素が人物についてなのかが分かりにくくなる。 #### 人物情報の中にパスポート情報を埋め込む あらかじめパスポート情報のドキュメントを埋め込んでおき、どの要素がどちらの要素であるかをはっきりさせる。 ```json= //Staphaneさん { "_id" : ObjectId("51f7be1cd6189a56c399d3bf"), "name" : "Stephane", "passport" : { "country" : "FR", "valid_until" : ISODate("2019-12-31T23:00:00Z") } } //Johnさん { "_id" : ObjectId("51f7be3fd6189a56c399d3c0"), "name" : "John", "passport" : { "country" : "US", "valid_until" : ISODate("2019-12-31T23:00:00Z") } //Michaelさん { "_id" : ObjectId("51f7be4dd6189a56c399d3c1"), "name" : "Michael", "passport" : { "country" : "RU", "valid_until" :ISODate("2019-12-31T23:00:00Z") } } //Cinderellaさん(架空→パスポート無し) { "_id" : ObjectId("51f7be5cd6189a56c399d3c2"), "name" : "Cinderella", } ``` ### スキーマまとめ MongoDBは、保存形式を問わないため、アプリケーションが最もよくアクセスするパターンを念頭にデザインする。 RDBMSでは、アクセスするパターンよりも、正規化されているかどうかを念頭にデザインする。 ## 参照ページ [世界第4位!最有力NoSQLデータベースMongoDBはRDBとどう違うのか?特徴と使い分け](https://tracpath.com/works/development/nosql_mongodb/) ###### tags: `NoSQL`, `MongoDB`