RDBMS設計
リレーショナルデータベースを使用する新しいデータ駆動型アプリケーションを構築する場合、まずドメインを適切に正規化されたテーブルのセットとしてモデル化し、外部キーを使用して他のテーブルの関連データを参照することがあります。
下の図は、リレーショナルデータベースモデルを使用してアプリケーションのデータストレージを表す方法を示しています。リレーショナルモデルには、ホテルと観光スポット、部屋とアメニティ、部屋と空室状況、ゲストと部屋(予約経由)の多対多の関係を実現するために、いくつかの「結合」テーブルが含まれています。

RDBMSとCassandraの設計の違い
Cassandraとリレーショナルデータベースのデータモデリングにおける主な違いをいくつか強調しておきましょう。
結合なし
Cassandraでは結合を実行できません。データモデルを設計し、結合のようなものが必要だとわかった場合は、クライアント側で作業を行うか、結合結果を表す非正規化された2番目のテーブルを作成する必要があります。後者のオプションは、Cassandraデータモデリングで推奨されます。クライアント側で結合を実行することは非常にまれなケースである必要があります。実際には、データの複製(非正規化)を行いたいと考えています。
参照整合性なし
Cassandraは軽量トランザクションやバッチなどの機能をサポートしていますが、Cassandra自体にはテーブル間の参照整合性の概念がありません。リレーショナルデータベースでは、テーブルに外部キーを指定して、別のテーブルのレコードの主キーを参照できます。しかし、Cassandraはこれを強制しません。テーブルに他のエンティティに関連するIDを格納することは依然として一般的な設計要件ですが、カスケード削除などの操作は使用できません。
非正規化
リレーショナルデータベースの設計では、正規化の重要性についてよく教えられます。これは、データモデルが非正規化されている場合にCassandraが最適に動作するため、利点ではありません。企業がリレーショナルデータベースのデータも非正規化することになるのはよくあることです。これには2つの一般的な理由があります。1つはパフォーマンスです。企業は、長年のデータに対して多くの結合を行う必要がある場合、必要なパフォーマンスを得ることができないため、既知のクエリに沿って非正規化します。これは最終的には機能しますが、リレーショナルデータベースの設計方法の趣旨に反しており、最終的には、これらの状況でリレーショナルデータベースを使用するのが最良のアプローチかどうかを疑問視することになります。
リレーショナルデータベースが意図的に非正規化される2番目の理由は、保持が必要なビジネスドキュメント構造です。つまり、データが時間の経過とともに変化する可能性のある多くの外部テーブルを参照する囲みテーブルがありますが、囲みドキュメントを履歴のスナップショットとして保持する必要があります。ここでの一般的な例は請求書です。顧客テーブルと製品テーブルはすでにあり、これらのテーブルを参照する請求書を作成できると思うかもしれません。しかし、これは実際には行うべきではありません。顧客情報や価格情報が変更される可能性があり、請求書日付時点での請求書ドキュメントの整合性が失われ、監査、レポート、法律に違反したり、その他の問題が発生する可能性があります。
リレーショナルの世界では、非正規化はCoddの正規形に違反しており、それを避けようとします。しかし、Cassandraでは、非正規化は完全に正常です。データモデルが単純な場合は必須ではありません。しかし、それを恐れないでください。
従来、Cassandraでの非正規化では、このドキュメントで説明されている手法を使用して複数のテーブルを設計および管理する必要がありました。3.0リリース以降、Cassandraは `materialized views <materialized-views>` と呼ばれる機能を提供しており、これにより、基本テーブル設計に基づいてデータの複数の非正規化ビューを作成できます。Cassandraは、ビューをテーブルと同期させる作業を含め、サーバー上でマテリアライズドビューを管理します。
クエリファースト設計
簡単に言えば、リレーショナルモデリングとは、概念ドメインから始めて、ドメインの名詞をテーブルに表すことを意味します。次に、主キーと外部キーを割り当てて関係をモデル化します。多対多の関係がある場合は、それらのキーだけを表す結合テーブルを作成します。結合テーブルは現実の世界には存在せず、リレーショナルモデルの動作方法の必要な副作用です。すべてのテーブルをレイアウトしたら、キーで定義された関係を使用して異なるデータを集約するクエリを書き始めることができます。リレーショナルの世界におけるクエリは非常に二次的なものです。テーブルが適切にモデル化されていれば、常に必要なデータを取得できると想定されています。いくつかの複雑なサブクエリまたは結合ステートメントを使用する必要がある場合でも、これは通常当てはまります。
対照的に、Cassandraでは、データモデルから始めるのではなく、クエリモデルから始めます。最初にデータをモデル化してからクエリを記述する代わりに、Cassandraではクエリをモデル化し、データをそれらの周りに編成させます。アプリケーションが使用する最も一般的なクエリパスを考えてから、それらをサポートするために必要なテーブルを作成します。
批判的な人々は、最初にクエリを設計することは、アプリケーションの設計、データベースのモデリングは言うまでもなく、過度に制約的であると示唆しています。しかし、リレーショナルドメインについて真剣に考えるのと同じように、アプリケーションのクエリについて真剣に考えることを期待するのは perfectly reasonable です。間違える可能性があり、どちらの世界でも問題が発生します。または、クエリのニーズが時間の経過とともに変化する可能性があり、データセットを更新するために作業する必要があります。しかし、これは、RDBMSで間違ったテーブルを定義したり、追加のテーブルが必要になったりするのと変わりません。
最適なストレージのための設計
リレーショナルデータベースでは、テーブルがディスクにどのように格納されているかはユーザーにとって透過的であることが多く、RDBMSがテーブルをディスクに格納する方法に基づいてデータモデリングに関する推奨事項を聞くことはめったにありません。ただし、これはCassandraでは重要な考慮事項です。Cassandraテーブルはそれぞれディスク上の個別のファイルに格納されるため、関連する列を同じテーブルにまとめて定義することが重要です。
Cassandraでデータモデルの作成を開始するときにわかる重要な目標は、特定のクエリを満たすために検索する必要があるパーティションの数を最小限に抑えることです。パーティションはノード間で分割されないストレージの単位であるため、単一のパーティションを検索するクエリは通常、最高のパフォーマンスをもたらします。
ソートは設計上の決定です
RDBMSでは、クエリで `ORDER BY` を使用することで、レコードが返される順序を簡単に変更できます。デフォルトのソート順は設定できません。デフォルトでは、レコードは書き込まれた順序で返されます。順序を変更する場合は、クエリを変更するだけで、任意の列のリストでソートできます。
ただし、Cassandraでは、ソートは異なる扱いを受けます。これは設計上の決定です。クエリで使用可能なソート順は固定されており、 `CREATE TABLE` コマンドで指定するクラスタリング列の選択によって完全に決定されます。CQL `SELECT` ステートメントは `ORDER BY` セマンティクスをサポートしますが、クラスタリング列で指定された順序でのみサポートします。
『Cassandra, The Definitive Guide』から抜粋。O'Reilly Media, Inc.発行。著作権©2020 Jeff Carpenter、Eben Hewitt。All rights reserved。許可を得て使用しています。