2018.10.03
MRT

RDBに慣れた私がNOSQL(MongoDB)を触ってみた

私が今までデータベースに触れてきたのは全てRDB(リレーショナルデータベース)というもので具体的にはOracle、PostgreSQL、MySQLなどを使ってきました。
簡単に言うとエクセル(表計算)でデータをまとめて、複数のシートの列と列の関係(リレーション)を紐づけて効率的にデータを管理するって感じです。
当たり前ですが表なので、行と列があります。それをSQLという言葉でデータを抽出したり、挿入したり、変更したりします。

で、NOSQLはというと、いろいろなタイプがあるらしいので、それによって特徴も違うのでしょうが、

    ・リレーションがない
    ・トランザクション管理できない
    ・SQLじゃない。(No SQL!)
    ・スキーマ(表の定義)がない

てなことがよくRDBと比較されるらしいです。

・リレーションがない
何で?正規化したりすれば、わかりやすいじゃん!と思いましたが、速度重視なんですね。

・トランザクション管理できない
これも速度重視のため、トランザクション(データの整合性を保つための一連の処理の流れ)はアプリケーションで管理して、データベースでは管理しないようです。

・SQLじゃない
ま、NoSQLっていうぐらいですから。。。

・スキーマ(表の定義)がない
これがなかなかイメージできなかった。RDBは基本的に表なので列に要素を定義して、データの単位を行で管理します。

例えば

名前 年齢 性別
太郎 18 男性
花子 43 女性

って感じです。

この「名前」「年齢」「性別」の表定義がないってどういう事?と。

ということで触ってみます。

インストール

今回はMongoDBってやつを使ってみます。(特に理由はないです)
簡単に触ってみるだけなので、Windowsに導入してみます。

ここからインストーラ(msi形式)をダウンロードしました。
今回は

mongodb-win32-x86_64-2008plus-ssl-4.0.2-signed.msi

でした。

ダウンロードしたインストーラをウィザードに沿って進めるだけです。

接続

ちなみに今回は

データベース:testdb
コレクション:test
※コレクション・・・RDBでいう表(テーブル)みないなもんですかね?

で話を進めます。

インストールした中に(私の環境では)

C:\Program Files\MongoDB\Server\4.0\bin\mongo.exe

ってのがあります。どうやらこれがデータベースにアクセスするツールのようです。
このツールを立ち上げてまずはデータベースを指定します。

> use testdb
switched to db testdb

「testdbに切り替えたぜ」って言われました。うまくいったようです。

データを入れてみる

今回は以下のデータを入れてみます。MongoDBはJSON形式で取り扱うようなのでデータもJSONで書いておきます。

{
name:”tanaka taro”,
sex:”male”,
age:”26″,
school:{
name:”test university”,
department:”Chemistry”,
address:”tokyo”
}
}

{
name:”suzuki hanako”,
sex:”female”,
age:”36″,
work:{
name:”bitstar”,
department:”development”,
address:”hokkaido”
}
}

今回はわざとデータを学生と社会人のデータとしています。RDBで管理しようとすると

name sex age school:name school:department school:address work:name work:department work:address
tanaka taro male 26 test university Chemistry tokyo
suzuki hanako female 36 bitstar development hokkaido

となります。(今回はわざと1テーブルにまとめています。そこは突っ込みなしで)

MongoDBの場合はとりあえずJSON形式で突っ込んじゃいます。

> db.test.insert({name:”tanaka taro”,sex:”male”,age:”26″,school:{name:”test university”,department:”Chemistry”,address:”tokyo”}})
WriteResult({ “nInserted” : 1 })

> db.test.insert({name:”suzuki hanako”,sex:”female”,age:”36″,work:{name:”bitstar”,department:”development”,address:”hokkaido”}})
WriteResult({ “nInserted” : 1 })

これだけ。

参照

今度は入れたデータを見てみます。

> db.test.find()
{ “_id” : ObjectId(“5b8f1f4b0b4fc5eda33b87c3”), “name” : “tanaka taro”, “sex” : “male”, “age” : “26”, “school” : { “name” : “test university”, “department” : “Chemistry”, “address” : “tokyo” } }
{ “_id” : ObjectId(“5b8f1f6b0b4fc5eda33b87c4”), “name” : “suzuki hanako”, “sex” : “female”, “age” : “36”, “work” : { “name” : “bitstar”, “department” : “development”, “address” : “hokkaido” } }

どうやらInsert時に_idって一意のIDが割り付けられているようですね。それ以外はInsert時と同じ状態で抜き取る事が出来ました。
今度は名前(name)が「tanaka taro」のデータだけを抽出してみます。

> db.test.find({name:”tanaka taro”})
{ “_id” : ObjectId(“5b8f1f4b0b4fc5eda33b87c3”), “name” : “tanaka taro”, “sex” : “male”, “age” : “26”, “school” : { “name” : “test university”, “department” : “Chemistry”, “address” : “tokyo” } }

簡単。

更新

次は更新です。
「suzuki hanako」さんは2歳サバ読んでいたって事で正しい年齢に直します。名前(name)が「suzuki hanako」の年齢を「38」歳にしてみます。

> db.test.update({name:”suzuki hanako”},{$set:{age:”38″}},false,true)
WriteResult({ “nMatched” : 1, “nUpserted” : 0, “nModified” : 1 })

ちゃんと更新されたか確認してみます。

> db.test.find({name:”suzuki hanako”})
{ “_id” : ObjectId(“5b8f1f6b0b4fc5eda33b87c4”), “name” : “suzuki hanako”, “sex” : “female”, “age” : “38”, “work” : { “name” : “bitstar”, “department” : “development”, “address” : “hokkaido” } }

ちゃんと38歳になりました。

他にも

変数が使えます。

変数dataにまずデータを代入します。

> data={name:”kato jiro”,sex:”male”,age:”52″,work:{name:”bitstar”,department:”production”,address:”hokkaido”}}
{
“name” : “kato jiro”,
“sex” : “male”,
“age” : “52”,
“work” : {
“name” : “bitstar”,
“department” : “production”,
“address” : “hokkaido”
}
}

その変数dataを挿入してみます。

> db.test.insert(data)
WriteResult({ “nInserted” : 1 })

できたかな?確認します。

> db.test.find({name:”kato jiro”})
{ “_id” : ObjectId(“5b8f23590b4fc5eda33b87c5”), “name” : “kato jiro”, “sex” : “male”, “age” : “52”, “work” : { “name” : “bitstar”, “department” : “production”, “address” : “hokkaido” } }

いいね!

ループで回したり、検索結果(複数件)のカーソルを操作して値を取得したりもできます。
プログラムではよくやる操作ですね。

検索結果を変数cに代入。

> var c = db.test.find()

検索結果の変数cを1件ずつ取得してJSON形式で出力してみます。

> while ( c.hasNext() ) printjson( c.next() )
{
“_id” : ObjectId(“5b8f1f4b0b4fc5eda33b87c3”),
“name” : “tanaka taro”,
“sex” : “male”,
“age” : “26”,
“school” : {
“name” : “test university”,
“department” : “Chemistry”,
“address” : “tokyo”
}
}
{
“_id” : ObjectId(“5b8f1f6b0b4fc5eda33b87c4”),
“name” : “suzuki hanako”,
“sex” : “female”,
“age” : “38”,
“work” : {
“name” : “bitstar”,
“department” : “development”,
“address” : “hokkaido”
}
}
{
“_id” : ObjectId(“5b8f23590b4fc5eda33b87c5”),
“name” : “kato jiro”,
“sex” : “male”,
“age” : “52”,
“work” : {
“name” : “bitstar”,
“department” : “production”,
“address” : “hokkaido”
}
}

こんな感じ。プログラムっぽい事いろいろできそうなので結構便利かも。

さいごに

今回は結局、触ってみるって事だったのであまりRDBにはないNOSQLの特性を活かしたうんたらかんたらには触れませんでしたが、NOSQLはそんなに難しい事はないってことだけはわかりました。お仕事の案件によってはNOSQLを使うのも悪くないなぁって思ったところで今回は終わりとします。

MRT

一覧に戻る