Cassandra 単純なデータベースの例を含むデータ モデル

⚡ スマートサマリー

Cassandra データモデルのルールは、リレーショナル設計の慣習を逆転させます。つまり、テーブルはエンティティのためではなく、クエリのために構築されます。このページでは、コアルール、パーティションキーの選択、および1対1、1対多、多対多のリレーションシップにおけるスキーマ例について説明します。

  • ✍️ 書き込みは安価です: Cassandra 書き込みスループットを最適化しているため、テーブル間でデータを複製することが、読み取り速度を向上させるための一般的な方法となっています。
  • ???? まずクエリを実行してください。 アプリケーションが応答する必要のあるクエリをリストアップし、エンティティごとにテーブルを作成するのではなく、クエリごとにテーブルを作成します。
  • 🔑 パーティションキー: 主キーの最初の要素は、どのノードにその行が格納されるかを決定し、それによってデータの分散の度合いが決まります。
  • 🧩 Cluster列の挿入: 残りの主キー要素は、パーティション内の行をソートし、範囲クエリを可能にします。
  • パーティションサイズ: パーティション数が少なすぎるとホットスポットが発生し、行サイズが大きくなりすぎます。多すぎると、読み取り時に多くのノードを経由する必要が生じます。
  • 🔗 関係: 一対一の場合は単一のテーブルが必要で、一対多の場合は複合キーが必要で、多対多の場合はクエリの方向ごとに1つのテーブルが必要です。

Cassandra データ モデルの例

しかし Cassandra クエリ言語は似ている SQL 言語、データモデリング方法がまったく異なります。

In Cassandra悪いデータモデルはパフォーマンスを低下させる可能性があり、特にユーザーがRDBMSの概念を実装しようとすると、 Cassandra。以下に詳しく説明するいくつかのルールに留意することをお勧めします。

Cassandra データモデルのルール

In Cassandra、書き込みは高価ではありません。 Cassandra 結合、グループ化、OR 句、集計などはサポートされていません。そのため、データを完全に取得できる方法でデータを保存する必要があります。したがって、データをモデル化する際には、これらのルールに留意する必要があります。 Cassandra.

書き込み回数を最大化する

In Cassandra、書き込みは非常に安価です。 Cassandra 書き込みパフォーマンスを最大化するように最適化されています。そのため、読み取りパフォーマンスとデータ可用性を向上させるには、書き込み回数を最大化してください。データ書き込みとデータ読み取りにはトレードオフの関係があります。したがって、データ書き込み回数を最大化することで、データ読み取りパフォーマンスを最適化してください。

データの重複を最大化する

データの非正規化とデータの重複は事実上、 Cassandraディスク容量は、メモリ、CPU処理、IO操作よりも高価ではありません。 Cassandra は分散データベースであるため、データの複製により即時にデータを利用できるようになり、単一障害点がなくなりました。

Cassandra データモデリングの目標

データをモデリングする際には、次の目標を設定する必要があります。 Cassandra:

データを均等に分散させます Cluster

各ノードに同じ量のデータが必要です。 Cassandra Clusterデータは、プライマリキーの最初の部分であるパー​​ティションキーに基づいて、異なるノードに分散されます。そのため、クラスタ全体にデータを均等に分散させるには、カーディナリティの高い列をパーティションキーとして選択するようにしてください。

データのクエリ中に読み取られるパーティションの数を最小限に抑える

パーティションは、同じパーティション キーを持つレコードのグループです。 読み取りクエリが発行されると、異なるパーティションの異なるノードからデータが収集されます。

多数のパーティションがある場合、クエリ データを収集するためにこれらすべてのパーティションにアクセスする必要があります。

これは、パーティションを作成すべきではないという意味ではありません。データ量が非常に大きい場合、その膨大なデータを単一のパーティションに保存することはできません。単一のパーティションでは処理速度が低下します。

したがって、バランスの取れたパーティション数を選択するようにしてください。

良好な主キー入力 Cassandra

上記の2つの目標はどちらも1つの決定に集約されるため、以下の2つの図は、不適切なキーを使用した場合と適切なキーを使用した場合の同じテーブルを示しています。

例を挙げて、どの主キーが良いか調べてみましょう。

これが MusicPlaylist のテーブルです。

CREATE TABLE MusicPlaylist (
    SongId int,
    SongName text,
    Year int,
    Singer text,
    PRIMARY KEY (SongId, SongName)
);

上の例では、テーブル MusicPlaylist、

  • SongIdはパーティションキーであり、
  • SongNameはクラスタリング列です
  • データはSongNameに基づいてクラスタリングされます。SongIdごとに作成されるパーティションは1つだけであり、各楽曲には固有の識別子があるため、各パーティションには1行のみが格納されます。

このデータ モデルでは主キーが間違っているため、データの取得が遅くなります。

こちらは別のテーブル MusicPlaylist です。

CREATE TABLE MusicPlaylist (
    SongId int,
    SongName text,
    Year int,
    Singer text,
    PRIMARY KEY ((SongId, Year), SongName)
);

上の例では、テーブル MusicPlaylist、

  • SongIdとYearはパーティションキーであり、
  • SongName はクラスタリング列です。
  • データは SongName に基づいてクラスター化されます。このテーブルでは、毎年新しいパーティションが作成されます。その年のすべての曲は同じノード上にあります。この主キーはデータにとって非常に役立ちます。

このデータ モデルにより、データの取得が高速になります。

データをモデル化する Cassandra

クエリをモデル化する際には次の点に留意する必要があります。

どのクエリをサポートするかを決定する

まず最初に、どのようなクエリが必要かを決定します。

たとえば、必要ですか?

  • ジョイン
  • グループ化する
  • どの列などでフィルタリングします。

クエリに従ってテーブルを作成する

クエリに従ってテーブルを作成します。 クエリを満たすテーブルを作成します。 最小限の数のパーティションを読み取る必要があるような方法でテーブルを作成するようにしてください。

続く3つのセクションでは、この原則をほぼすべてのスキーマに見られる3種類の関係性に適用する。

での 1 対 1 の関係の処理 Cassandra

XNUMX 対 XNUMX の関係は、XNUMX つのテーブルが XNUMX 対 XNUMX の対応関係を持つことを意味します。 たとえば、学生が登録できる科目は XNUMX つだけですが、その学生がどの科目に登録されているかを学生で検索したいとします。

したがって、この場合、テーブル スキーマには、コース名、学生のロール番号、学生名など、特定のコースに対応する学生の詳細がすべて含まれる必要があります。

1 対 1 の関係 Cassandra
1 対 1 の関係 Cassandra

上記の図は、クエリを処理する単一のテーブルを示しています。これは、1人の学生が必ず1つのコースに対応するためです。

CREATE TABLE Student_Course (
    Student_rollno int PRIMARY KEY,
    Student_name text,
    Course_name text
);

Student_rollnoはパーティションキーであるため、ロール番号による検索では正確に1つのパーティションが読み取られます。

での 1 対多の関係の処理 Cassandra

XNUMX 対多の関係とは、XNUMX つのテーブル間に XNUMX 対多の対応関係があることを意味します。

たとえば、XNUMX つのコースを多数の学生が受講することができます。 特定のコースを学習しているすべての学生を検索したいと考えています。

したがって、コース名をクエリすると、特定のコースを学習する多くの学生の名前が得られます。

1 対多の関係 Cassandra
1 対多の関係 Cassandra

ここでは、コース名がパーティションキーとなり、コースのすべての学生が同じパーティションに割り当てられ、学籍番号がクラスタリング列となり、各学生が個別の行として扱われるようになります。

CREATE TABLE Student_Course (
    Course_name text,
    Student_rollno int,
    Student_name text,
    PRIMARY KEY (Course_name, Student_rollno)
);

次のクエリにより、特定のコースのすべての学生を取得できます。

SELECT * FROM Student_Course WHERE Course_name = 'Course Name';

での多対多の関係の処理 Cassandra

多対多の関係とは、XNUMX つのテーブル間に多対多の対応関係があることを意味します。

たとえば、XNUMX つのコースを多数の学生が学習することができ、また、XNUMX 人の学生が多数のコースを学習することもできます。

多対多の関係 Cassandra
多対多の関係 Cassandra

特定のコースを学習しているすべての学生を検索したいと考えています。 また、特定の学生が学んでいるコースをすべて検索したいと考えています。

この場合、テーブルを2つ作成し、問題を2つのケースに分割します。これは、重複ルールを最も明確に示しています。同じ事実が2回書き込まれるため、各クエリは1つのパーティションを読み取ることになります。

まず、特定の学生のコースを検索できるテーブルを作成します。

CREATE TABLE Student_Course (
    Student_rollno int,
    Course_name text,
    Student_name text,
    PRIMARY KEY (Student_rollno, Course_name)
);

次のクエリを実行すると、特定の学生のすべてのコースを見つけることができます。

SELECT * FROM Student_Course WHERE Student_rollno = 101;

次に、特定のコースを勉強している学生の数を確認できる表を作成します。

CREATE TABLE Course_Student (
    Course_name text,
    Student_rollno int,
    Student_name text,
    PRIMARY KEY (Course_name, Student_rollno)
);

次のクエリで特定のコースの学生を見つけることができます。

SELECT * FROM Course_Student WHERE Course_name = 'Cassandra';

学生がコースに参加するたびに、両方のテーブルに書き込みを行う必要があります。通常は、2つのコピーが同期するように、単一のログバッチ内で書き込みが行われます。

コマンドと Cassandra データモデリングの誤り

ほとんどの質の低いスキーマは同じ少数のエラーを繰り返しており、 trac関係設計から引き継がれた習慣に戻る。

  • 境界のないパーティション: 国名などのパーティションキーを選択すると、数百万行が1つのパーティションに格納されてしまいます。パーティションのサイズを適切な範囲に抑えるには、例えば(国、月)といった時間バケットを追加してください。
  • 非常に低いカーディナリティのキー: ステータスフラグなど、取り得る値がごく少数しかないパーティションキーを使用すると、すべてのトラフィックが少数のノードに集中し、残りのノードはアイドル状態になります。
  • ALLOW FILTERING を使用してクエリを機能させる方法: これはすべてのパーティションをスキャンし、モデリング上の問題を隠蔽します。クエリが必要とする場合、スキーマには別のテーブルが必要になります。
  • クエリではなくエンティティをモデル化する: 学生一覧表とコース一覧表を作成し、それらをアプリケーション内で結合しようとすると、設計の目的が損なわれてしまう。
  • 頻繁な削除と上書き: 削除処理が行われるたびに、削除痕跡(トゥームストーン)が書き込まれ、圧縮処理によって削除されるまで、その痕跡を読み取ってスキップする必要があるため、ホットパーティションでの読み取り速度が低下します。

これらを避けることで、スキーマは本ページ上部に記載されているルール、および以下に要約されている関係性の違いに沿ったものになります。

RDBMSとの違い Cassandra データモデリング

RDBMS Cassandra
データを正規化された形式で保存します データを非正規化形式で保存します
レガシー DBMS。 構造化データ 広範囲な行ストア、動的、構造化データおよび非構造化データ
スキーマはエンティティとその関係を中心に設計されています スキーマは、アプリケーションが実行するクエリに基づいて設計されます。
結合、GROUP BY、および任意のWHERE句がサポートされています。 結合や任意のフィルタリングは禁止。クエリは主キーと一致する必要がある。
通常、1つのテーブルが多くの異なるクエリに対応します。 通常、1つのテーブルは1つのクエリに対応するため、データはテーブル間で重複する。
外部キーによって強制される参照整合性 外部キーは使用せず、重複するテーブル間の整合性はアプリケーションの責任となります。

これらのスキーマ決定は、実際には Cassandra テーブル (NAIST) と キースペース チュートリアル

よくあるご質問

パーティションサイズは100MB未満、行数は約100,000万行を目安にしてください。パーティションサイズが大きすぎると、読み取り速度が低下し、修復時間が長くなり、圧縮時のメモリ負荷が高まります。

パーティションキーによって、行を格納するノードが決まります。 Cluster列は、そのパーティション内の行のソート順を決定し、日付範囲などの範囲クエリを可能にします。

マテリアライズドビューはデータの重複を自動化しますが、依然として実験的な機能であり、一貫性に関する既知の例外的なケースが存在します。ほとんどの運用スキーマでは、アプリケーションから取得した2つ目のテーブルが引き続き使用されます。

AI はエンティティを候補テーブルに変換できますが、 Cassandra スキーマはエンティティではなくクエリに従います。まずクエリリストを指定し、生成されたテーブルを下書きとして扱い、パーティションサイズとの照合を行います。

列のカーディナリティと予想される行数に基づいて、AIはホットスポットや境界のないパーティションを生成する可能性のあるキーを特定できます。実際のデータがロードされたら、nodetool tablehistogramsを使用して警告を確認してください。