Try T.M Engineer Blog

多摩市で生息するエンジニアが「アウトプットする事は大事だ」と思って始めたブログ

NoSQLについて誤解していたことと学びについて

以前から気になっていたNoSQLについて調べてみた。
SQLは良く目にする言語なので、使用経験もあるのだが、NoSQLは使った事もないし、よくわからなかったで調べてみることにした。

ちなみに、NoSQLに対する私の知識は、AmazonDynamo DBやGoogleBigTableなどで使われる最近出てきた言語という事くらいしか知らない。

以降、調べてみた結果。

NoSQL( "Not only SQL" と言われている)

関係データベース管理システム (RDBMS) 以外のデータベース管理システムを指すおおまかな分類語である。 関係データベースを杓子定規に適用してきた長い歴史を打破し、それ以外の構造のデータベースの利用・発展を促進させようとする運動の標語としての意味合いを持つ。

NoSQLという用語は1998年、SQLインタフェースを持たない軽量な関係データベースのオープンソースソフトウェアの名前として最初に用いられた。

(一部抜粋)ウィキペディアより:NoSQL - Wikipedia

まず、これを読んで思ったことは「用語の定義がかなり幅広い」ということ。しかも、1998年から存在していたとは・・・てっきり最近出てきた言語だと思っていた。
また、てっきりSQLのような新しいQuery言語を指すのかなと思いきや、全然違くて「RDBMS以外のデータベース管理システムを指す分類語」らしい。これは大きな勘違いをしていた。

少し自分の過去を振り返る

むかーし、XMLを扱うデータベースを使って仕事をした事があったのだが、もしかしすると、それもNoSQLになるのだろうか・・・・調べてみた。

ドキュメント指向(Document-oriented、Document store) - XMLJSONといった、 スキーマレスでデータ構造が柔軟なもの。MongoDB、Apache CouchDBAmazon DynamoDBなど。XMLデータベースなどのシステムでは、XQueryを利用できるものもある。

(一部抜粋)ウィキペディアより:NoSQL - Wikipedia

なるほど。XMLを扱うデータベースもNoSQLの1つらしい。ということは、私は昔、NoSQLを使って仕事をしていたという事になる。(NoSQLを使ったことがないというのは嘘だという事が発覚した |||orz)

こんな事を言うと偉い人に怒られるかもしれませんが、XMLを扱うデータベースは、XMLタグを含めるすべてのデータをDBに格納するので、データ量が1000件程度でQueryからのレスポンスが非常に遅くなり、大変扱いにくかった思い出があります。(ええっ、炎上案件でしたとも・・・)
また、データもXMLで非常に見辛く、とても辛いオシゴトでした。

気を取り直してNoSQLの話

NoSQLはRDBMS以外のデータベース管理システムを指すという幅広い定義であるため、多くのNoSQLのデータベースが存在する。これをデータモデルとアーキテクチャでデータベースの種類を分けることができる。
以下記事がとても参考になった。

qiita.com

www.atmarkit.co.jp

NoSQLといっても色々な種類のデータベースがあるのがわかる。
NoSQLで有名なのはAWSのDynamoDBやGoogleBigTable、あとはMongoDBだと思うのだが、上記分類分けを見るとまったくの別物であることがわかる。NoSQLのデータベースを選定する時は、よく調べる必要がありそうです。

NoSQLを使ってみよう

私の場合、AWSを仕事で使っているので、DynamoDBについて学ぶのが良さそうです。AWS DynamoDBはAWSとDockerのアカウント、AWS-CLIさえあれば、簡単にローカル環境を構築できるので、ちょっと使ってみる分にはオススメです。

https://hub.docker.com/r/amazon/dynamodb-local

というわけで、さっそく使ってみる。
(事前にAWSとDockerアカウントの登録、AWS-CLIのインストールは必須です)以下コマンドを入力すれば、aws dynamodb-localが起動します。

docker run -d -p 8000:8000 amazon/dynamodb-local

"-d"オプションをつけることで、デーモン化してdaynamoDBが立ち上がるのでオススメです。

$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
amazon/dynamodb-local   latest              26ea09a4a680        5 months ago        446MB
$ docker ps -a
CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS              PORTS                    NAMES
7e92210ebb4a        amazon/dynamodb-local   "java -jar DynamoDBL…"   32 seconds ago      Up 30 seconds       0.0.0.0:8000->8000/tcp   tender_newton

テーブルの作り方、データ挿入方法はamazonのマニュアルを参考にしました。

CLI の使用 - Amazon DynamoDB

試しに、上記作り方に記載しているMusicテーブルを作成してみます。 なお、dynamodb-localを操作するには"--endpoint-url http://localhost:8000"オプションが必須です。
このオプションをつけていないと、自分のAWSアカウントのDynamoDBにテーブルを作るので注意が必要です。(ちゃんとAWSの設定をしている場合に限る)

$ aws dynamodb create-table \
>     --endpoint-url http://localhost:8000 \
>     --table-name Music \
>     --attribute-definitions \
>         AttributeName=Artist,AttributeType=S \
>         AttributeName=SongTitle,AttributeType=S \
>     --key-schema \
>         AttributeName=Artist,KeyType=HASH \
>         AttributeName=SongTitle,KeyType=RANGE \
>     --provisioned-throughput \
>         ReadCapacityUnits=1,WriteCapacityUnits=1
{
    "TableDescription": {
        "TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/Music",
        "AttributeDefinitions": [
            {
                "AttributeName": "Artist",
                "AttributeType": "S"
            },
            {
                "AttributeName": "SongTitle",
                "AttributeType": "S"
            }
        ],
        "ProvisionedThroughput": {
            "NumberOfDecreasesToday": 0,
            "WriteCapacityUnits": 1,
            "LastIncreaseDateTime": 0.0,
            "ReadCapacityUnits": 1,
            "LastDecreaseDateTime": 0.0
        },
        "TableSizeBytes": 0,
        "TableName": "Music",
        "TableStatus": "ACTIVE",
        "KeySchema": [
            {
                "KeyType": "HASH",
                "AttributeName": "Artist"
            },
            {
                "KeyType": "RANGE",
                "AttributeName": "SongTitle"
            }
        ],
        "ItemCount": 0,
        "CreationDateTime": 1548505321.099
    }
}

データを挿入してみます。

$ aws dynamodb put-item \
> --endpoint-url http://localhost:8000 \
> --table-name Music  \
> --item \
>     '{
>         "Artist": {"S": "No One You Know"},
>         "SongTitle": {"S": "Call Me Today"},
>         "AlbumTitle": {"S": "Somewhat Famous"}
>     }' \
> --return-consumed-capacity TOTAL

scanコマンドを使って、挿入したデータの確認。
ちゃんと追加されていますね。

$ aws dynamodb scan \
> --endpoint-url http://localhost:8000 \
> --table-name Music
{
    "Count": 1,
    "Items": [
        {
            "Artist": {
                "S": "No One You Know"
            },
            "SongTitle": {
                "S": "Call Me Today"
            },
            "AlbumTitle": {
                "S": "Somewhat Famous"
            }
        }
    ],
    "ScannedCount": 1,
    "ConsumedCapacity": null

まとめ

  • NoSQLとは、関係データベース管理システム (RDBMS) 以外のデータベース管理システムを指す。
  • SQLのようなQuery言語を指すわけではなく、データベースの分類用語。
  • NoSQLのデータベースは多くあり、データモデルとアーキテクチャで分類分けできる。また、XMLJSONを扱うもの等、個性もある。
  • AWS使っている人は、まずはDockerのdaynamodb-localがオススメ。