見出し画像

NoSQLデータベース

この記事は私が今度受ける大学の試験に向けたアウトプットになります。勉強したことをNotionにまとめていたところ、noteでまとめておけば万が一間違えてる時に誰かが指摘してくれるかもしれないという淡い期待を込めて書いています。

NoSQLデータベースは、「Not Only SQL」の略で、リレーショナルデータベース(SQLデータベース)とは異なるアプローチを採用しているデータベースシステムになります。リレーショナルデータベースがテーブル形式でデータを整理し、SQL(Structured Query Language)を使用してデータを操作するのに対し、NoSQLデータベースはさまざまなデータ構造を用いることが特徴です。ここではキーバリュー型ドキュメント指向型のデータベースについてまとめていきます。


キーバリュー型

基本的な構造は「キー」と「値」のペアで、キーはデータの保存と検索に使われます。ここでいう「キー」とは一意の識別子であり、「値」とはそれに関連付けられたデータになります。キー・バリュー型のデータベースを想像するとき、一般的には巨大な辞書になるかなと思います。

例えば、とあるウェブアプリケーションが、ユーザーセッション情報をキー・バリュー データベースで管理しているとします。各ユーザーセッションは "キー "であり、そのキーに関連付けられた "値 "には、 ユーザーのプロファイル情報、現在のセッション状態、設定などが格納されます。

Key: user session ID (e.g. session12345)
Value: {
 User Name: "John Doe"
 Last login time: "2023-05-19T12:34:56"
 Language Preference: "Japanese"
}

キーバリュー型のメリット

スピード

キーバリュー型はキーを介した値への直接アクセスを可能にし、データの読み書きを高速に行うことができます。リレーショナル・データベースも高速なアクセスを提供できますが、そのパフォーマンスは、結合や複雑なクエリによって影響を受ける可能性が高いです。

スケーラビリティ

キーバリュー型の各データ項目はキー・バリューのペアとして独立しているため、このシンプルなデータモデルにより、複雑な関係や依存関係を気にすることなく、データをサーバー間で分散できます。これにより、データベースを複数のサーバーに分散し、負荷を均等に分散することができます。
対照的に、リレーショナル・データベースは、複数のテーブルにまたがるデータを関連付け、これらの関係(リレーション)を通じてデータの整合性を維持しています。データを横断的に管理するために、結合や複雑なクエリが頻繁に使用されるのが一般的です。これらの要素はデータを分散させる際に考慮しなければならないため、スケーラビリティがより複雑になってしまいます。

柔軟性

キーバリュー型はスキーマレスであり、どのようなデータ型でも値として保存することができます。このスキーマレス設計により、データ構造を事前に定義する必要がなくなり、アプリケーションの要件に応じて動的にデータを追加・変更することが容易になります。さらに、ユーザーごとに異なるデータ・フィールドを持つことができるため、カスタマイズされたデータ管理が可能になります。
スキーマレスデータベースでは、基本的に同じデータフィールド名で異なるデータ型を持つことができます。しかし、同じフィールド名で異なるデータ型を使用することは、アプリケーションコードに予期せぬエラーやバグを引き起こす可能性があるため、推奨はされません。

キーバリュー型のデメリット

キーバリュー型はキーを使って素早くデータを取り出すために最適化されていますが、値の内部構造を解析したり、複雑なクエリを実行したりする能力には限界があります。

例えば、とあるショッピング・アプリケーションで、各ユーザが最近見た商品のリストをキーバリュー型のデータベースに保存しているとします。

キー: ユーザーID (例: user123)
値 :最近見た商品のIDリスト (例: ["prod456", "prod789", "prod101"])

この例では、ユーザーIDがキーとして使用され、そのキーに対応する値として商品IDのリストが格納されています。データベースはキー(user123)を使用して、関連する値(商品IDのリスト)を素早く検索することができます。しかし、ユーザーが閲覧した特定の商品(例:prod789)に基づき、その商品を閲覧した他のユーザーを検索するクエリは、直接実行できません。

ドキュメント指向型

ドキュメント指向型のデータベースは、キーバリュー型データベースの柔軟性とシンプルさを維持しつつ、その欠点のいくつかを克服するために設計されています。

リッチなデータ構造

ドキュメント指向型は、JSONやXMLのようなリッチなフォーマットでデータを格納します。これにより、単一のエンティティ内で複雑なデータ構造を扱うことができ、キーバリュー型で使用される単純な文字列やバイナリ・フォーマットでは表現が困難な階層データ、リスト、ネストされたオブジェクトに対応することができます。

XMLとは

XMLはeXtensible Markup Languageの略で汎用マークアップ言語として設計され、多様なデータ構造を記述するのに適しています。XMLは開閉タグを使って要素を定義し、カスタムタグを作成したり、属性を持たせることで特定のデータ要件に合わせることができます。しかし、XMLは開閉タグが必要なことから、データ量が増えてしまい、冗長に見えてしまう欠点もあります。

XMLドキュメントは、ルート要素と呼ばれる1つの要素から始まります。他の子要素はこのルート要素の中に入れ子になります。

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
    <book isbn="978-3-16-148410-0">
        <title>Introduction to XML</title>
        <author>Tanaka Ichiro</author>
        <price>2400</price>
    </book>
    <book isbn="978-4-16-148410-1">
        <title>Advanced XML</title>
        <author>Yamada Hanako</author>
        <price>3000</price>
    </book>
</bookstore>

上記はXMLの簡単な例です。この例では、<book>がルート要素で、いくつかの子要素と属性を含んでいます。

<?xml version="1.0" encoding="UTF-8"?>はXML宣言であり、ドキュメントがXMLであることをバージョンとエンコーディングとともに指定します。
<bookstore>はルート要素で、その下に他の要素がネストされているのがわかります。
<book>は各書籍の情報を格納する子要素。本のISBN番号を示す属性 isbn を持っています。
<title>, <author>, <price>これらの子要素は、本のタイトル、著者、価格など、より具体的な情報を格納するタグになります。

XMLのルールとして、ドキュメントはルート要素を1つだけ持たなければいけません。また、開始タグと終了タグは一致しなければならず、属性は名前と値のペアで、要素の開始タグの中に記述します。更に、タグ名と属性名は大文字と小文字を区別します。このあたりはHTMLを記述したことがある人なら分かりやすいかなと思います。

JSONとは

JSONはJavaScript Object Notationの略で、Webアプリでの使用に特化した、軽量なデータ交換フォーマットとして設計されています。構造は名前と値のペア(キーと値のペア)で構成され、データを整理するために配列とオブジェクトを使用します。可読性はXMLよりも簡潔で、データのオーバーヘッドが少なく、通信に効率的という利点があります。

{
    "name": "Taro Yamada",
    "age": 30,
    "isStudent": false,
    "address": {
        "city": "Tokyo",
        "postalCode": "100-0001"
    },
    "phoneNumbers": [
        "080-1234-5678",
        "080-8765-4321"
    ],
    "courses": null
}

上記はJSONデータの例になります。書き方として中括弧 {}で囲み、キーと文字列の値は常に二重引用符を使用します。また、オブジェクト内の各キーと値のペアをコロンで区切り、ペアや配列の要素はカンマで区切る必要があります。

強化されたクエリ機能

ドキュメント指向型は、ドキュメント内のあらゆるフィールドに対するクエリを可能にする検索機能を備えています。この機能は、キーバリュー型で一般的な単純なキー・ベースの検索にとどまらず、複雑な条件検索やフィールド値に基づくソートも可能です。
また、最近のドキュメント指向型(MongoDB等)は、限定的にはなりますが、トランザクションをサポートし始めており、複数のドキュメントの更新を単一の操作としてアトミックに実行することができ、データの整合性と一貫性を高めることができます。

この記事が気に入ったらサポートをしてみませんか?