2.1 NoSQL という用語の出現

最近、「NoSQL」という用語が非常にファッショナブルで人気があり、この看板の下であらゆる種類のソフトウェア ソリューションが積極的に開発、推進されています。NoSQL は、膨大な量のデータ、線形スケーラビリティ、クラスター、フォールト トレランス、非リレーショナル性の代名詞となっています。ただし、NoSQL ストレージとは何なのか、この用語がどのように登場したのか、どのような共通の特徴があるのか​​を明確に理解している人はほとんどいません。このギャップを埋めてみましょう。

この用語の最も興味深い点は、この用語が初めて使用されたのは 90 年代後半であるにもかかわらず、現在使用されている形で本当の意味を獲得したのは 2009 年半ばになってからであるということです。 -Carlo Strozzi によって作成されたソース データベース。すべてのデータを ASCII ファイルとして保存し、データへのアクセスに SQL の代わりにシェル スクリプトを使用しました。現在の形式の「NoSQL」とは何の関係もありませんでした。

2009 年 6 月、Johan Oskarsson は、IT ストレージおよび処理市場の新しいトレンドについて話し合う会議をサンフランシスコで開催しました。この会議の主な推進力となったのは、BigTable や Dynamo などの新しいオープンソース製品でした。会議の明るい兆しを得るには、Twitter のハッシュタグにぴったり収まる、容量が大きく簡潔な用語を見つける必要がありました。これらの用語の 1 つは、RackSpace の Eric Evans によって提案された「NoSQL」です。この用語は 1 つの会議用に計画されたものであり、深い意味的負荷はありませんでしたが、たまたまバイラル広告のようにグローバル ネットワーク全体に広がり、IT 業界全体のトレンドの事実上の名前になりました。ちなみに、Voldemort (Amazon Dynamo クローン)、Cassandra、Hbase (Google BigTable の類似品)、Hypertable、CouchDB、MongoDB がカンファレンスで講演しました。

「NoSQL」という用語は完全に自然発生的に生まれたものであり、一般に受け入れられている定義や背後にある科学的機関がないことをもう一度強調する価値があります。この名前はむしろ、リレーショナル データベースから離れた IT 開発のベクトルを特徴づけています。これは Not Only SQL の略ですが、No SQL を直接定義する支持者もいます。Pramod Sadalaj と Martin Fowler は、近著『NoSQL Distilled』で NoSQL の世界に関する知識をグループ化して体系化しようとしました。

2.2 NoSQL データベースの基本特性

現在、多くの異種システムが NoSQL ラベルの下に隠されているため、すべての NoSQL に共通する特徴はほとんどありません (おそらく、最も完全なリストは http://nosql-database.org/ にあります)。多くの特徴は特定の NoSQL データベースにのみ特有のものです。これについてはリストするときに必ず言及します。

1. SQL は使用されません

ANSI SQL DML のことです。多くのデータベースがよく知られているお気に入りの構文に似たクエリ言語を使用しようとしていますが、誰もそれを完全に実装できておらず、成功する可能性は低いからです。ただし、hadup ( http://www.drawntoscalehq.com/およびhttp://www.hadapt.com/ ) など、SQL の実装を試みているスタートアップがあると噂されています。

2. 非構造化 (スキーマレス)

つまり、NoSQL データベースでは、リレーショナル データベースとは異なり、データ構造が規制されていない (プログラミング言語に喩えると、型指定が弱い) ということです。最初に宣言的に構造を変更しなくても、別の行またはドキュメントに任意のフィールドを追加できます。テーブル全体の。したがって、データ モデルを変更する必要がある場合、十分なアクションはアプリケーション コードに変更を反映することだけです。

たとえば、MongoDB のフィールドの名前を変更する場合:

BasicDBObject order = new BasicDBObject();
order.put("date", orderDate); // this field was a long time ago
order.put("totalSum", total); // before we just used "sum"

アプリケーション ロジックを変更すると、読み取り時にも新しいフィールドが必要になります。ただし、データ スキーマがないため、totalSum フィールドが他の既存の Order オブジェクトから欠落しています。この状況では、さらなるアクションには 2 つのオプションがあります。

1 つ目は、すべてのドキュメントをクロールし、すべての既存ドキュメントのこのフィールドを更新することです。データ量が多いため、このプロセスはロックなしで実行されるため (alter table rename column コマンドと同様)、更新中に既存のデータが他のプロセスによって読み取られる可能性があります。したがって、2 番目のオプションであるアプリケーション コードのチェックインは避けられません。

BasicDBObject order = new BasicDBObject();
Double totalSum = order.getDouble("sum"); // This is the old model
if (totalSum  == null)
totalSum = order.getDouble("totalSum"); // This is the updated model

そして、再記録するときに、このフィールドを新しい形式でデータベースに書き込みます。

スキーマがないことによる嬉しい結果は、スパース データの処理が効率化されることです。1 つのドキュメントに date_published フィールドがあり、2 番目のドキュメントにはそれがない場合、2 番目のドキュメントには空の date_published フィールドは作成されません。これは原則として論理的ですが、あまり明白ではない例として、テーブル/列というよく知られた概念を使用する列ファミリー NoSQL データベースがあります。ただし、スキーマがないため、列は宣言的に宣言されず、ユーザーのデータベース セッション中に変更/追加できます。これにより、特にリストの実装に動的列を使用できるようになります。

非構造化スキーマには欠点があります。データ モデルを変更するときのアプリケーション コードのオーバーヘッドに加えて、ベースからのあらゆる種類の制限 (null ではない、一意、チェック制約など) が存在しないことです。異なるプロジェクトのデータベースを並行して操作する場合、構造データの理解と制御がさらに困難になります (データベース側に辞書がありません)。しかし、急速に変化する現代世界では、このような柔軟性は依然として利点です。その一例は Twitter です。5 年前は、ツイートとともにほんの少しの追加情報 (時刻、Twitter ハンドル、さらに数バイトのメタ情報) のみが保存されていましたが、現在では、メッセージ自体に加えて、さらにいくつかの情報が保存されています。キロバイトのメタデータがデータベースに保存されます。

(以下では、主にキーと値、ドキュメントと列ファミリーのデータベースについて説明します。グラフ データベースにはこれらのプロパティがない場合があります)

2.3. 集計形式でのデータの表現 (集計)

正規化の目的でアプリケーションの論理ビジネス エンティティをさまざまな物理テーブルに格納するリレーショナル モデルとは異なり、NoSQL ストアはこれらのエンティティを総合的なオブジェクトとして操作します。

この例では、標準的な電子商取引概念リレーショナル モデル「注文 - 注文商品 - 支払い - 製品」の集計を示します。どちらの場合も、注文は位置と結合されて 1 つの論理オブジェクトになり、各位置には製品へのリンクとその属性の一部 (名前など) が格納されます (このような非正規化は、取得時に製品オブジェクトを要求しないようにするために必要です)順序 - 分散システムの主なルールはオブジェクト間の「結合」です)。1 つの集約では、支払いは注文と結合され、オブジェクトの不可欠な部分となりますが、もう 1 つの集約では、支払いは別個のオブジェクトに配置されます。これは、NoSQL データベースのデータ構造を設計するための主なルールを示しています。つまり、データ構造はアプリケーションの要件に従い、最も頻繁に発生するリクエストに対して可能な限り最適化する必要があります。

クエリが集計構造に適合しない場合に、データに対して任意のクエリを試行すると、大規模で非正規化されることが多いオブジェクトを操作すると、多くの問題が発生することに多くの人が反対するでしょう。注文を注文品目と支払いとともに使用する場合 (これがアプリの仕組みです)、企業が特定の製品が先月販売された個数を数えるように要求した場合はどうなるでしょうか? この場合、OrderItem テーブル (リレーショナル モデルの場合) をスキャンする代わりに、NoSQL ストレージ内の注文全体を取得する必要がありますが、この情報はあまり必要ありません。残念ながら、これは分散システムでは妥協しなければならない点です。従来の単一サーバー システムのようにデータを正規化することはできません。

両方のアプローチの長所と短所を表にまとめてみました。