1概要

Cassandraは、パフォーマンスを犠牲にすることなく高可用性と水平方向のスケーラビリティを提供するNoSQLデータベースです。

Cassandraから最高のパフォーマンスを引き出すには、当面のビジネス上の問題に固有のクエリパターンを中心にスキーマを慎重に設計する必要があります。

この記事では、Cassandraでのデータ・モデリングへの取り組み方に関する主な概念をいくつか復習します。

先に進む前に、/cassandra-with-java[Cassandra with Java]の記事を読んで、基本とJavaを使ってCassandraに接続する方法を理解してください。

** 2パーティションキー

**

Cassandraは、データがクラスタ内の複数のノードにまたがって分割され格納されている分散データベースです。

パーティションキーは1つ以上のデータフィールドで構成され、

ハッシュを介してトークンを生成してデータをクラスタ全体に一様に分散させる

ためにパーティショナによって使用されます。

** 3クラスタリングキー

**

クラスタリングキーは1つ以上のフィールドで構成され、同じパーティションキーを持つ行をクラスタリングまたはグループ化し、それらをソート順に格納するのに役立ちます。

Cassandraに時系列データを格納しており、時系列順にデータを取得したいとしましょう。時系列データフィールドを含むクラスタリングキーは、このユースケースのデータを効率的に取得するために非常に役立ちます。

  • 注:パーティションキーとクラスタリングキーの組み合わせが主キーを構成し、Cassandraクラスター内のすべてのレコードを一意に識別します。

** 4クエリパターンに関するガイドライン

**

Cassandraでのデータモデリングを始める前に、クエリパターンを特定し、それらが以下のガイドラインに従っていることを確認する必要があります。

  1. 各クエリは単一のパーティションからデータを取得する必要があります

  2. 私たちは、どれだけのデータが保存されているのかを追跡する必要があります.

Cassandraには、可能な列数に制限があるため、パーティション
単一のパーティションに格納する
。異なるデータをサポートするためにデータを非正規化して複製しても構いません。

同じデータに対するクエリパターンの種類

上記のガイドラインに基づいて、実際のユースケースと、それらのCassandraデータモデルをどのようにモデル化するかを見てみましょう。

** 5実世界のデータモデリングの例

**


5.1. Facebookの投稿

Cassandraに異なるユーザーのFacebook投稿を保管しているとします。一般的なクエリパターンの1つは、特定のユーザーによって作成された上位の ‘

N

‘の投稿を取得することです。

したがって、上記のガイドラインに従って、特定のユーザーのすべてのデータを単一のパーティションに格納する必要があります。

また、ポストタイムスタンプをクラスタリングキーとして使用すると、上位の ‘

N

‘個の投稿をより効率的に取得するのに役立ちます。

このユースケースのためにCassandraテーブルスキーマを定義しましょう:

CREATE TABLE posts__facebook (
  user__id uuid,
  post__id timeuuid,
  content text,
  PRIMARY KEY (user__id, post__id) )
WITH CLUSTERING ORDER BY (post__id DESC);

それでは、ユーザー

Anna

の上位20の投稿を見つけるためのクエリを作成しましょう。

SELECT content FROM posts__facebook WHERE user__id = "Anna__id" LIMIT 20


5.2. 全国のジム

さまざまな都市やさまざまな国の州にまたがるさまざまなパートナージムの詳細を保存しており、特定の都市のジムを取得するとします。

また、ジムを開始日順に並べ替えた結果を返す必要があるとしましょう。

上記のガイドラインに基づいて、特定の州および国の特定の都市にあるジムを単一のパーティションに格納し、開始日とジム名をクラスタリングキーとして使用する必要があります。

この例のCassandraテーブルスキーマを定義しましょう。

CREATE TABLE gyms__by__city (
 country__code text,
 state text,
 city text,
 gym__name text,
 opening__date timestamp,
 PRIMARY KEY (
   (country__code, state__province, city),
   (opening__date, gym__name))
 WITH CLUSTERING ORDER BY (opening__date ASC, gym__name ASC);

それでは、米国アリゾナ州のフェニックス市の開業日までの最初の10体操を取得するクエリを見てみましょう。

SELECT **  FROM gyms__by__city
  WHERE country__code = "us" AND state = "Arizona" AND city = "Phoenix"
  LIMIT 10

次に、米国アリゾナ州のフェニックス市で最近開かれた10のジムを取得するクエリを見てみましょう。

SELECT **  FROM gyms__by__city
  WHERE country__code = "us" and state = "Arizona" and city = "Phoenix"
  ORDER BY opening__date DESC
  LIMIT 10

注:最後のクエリのソート順はテーブル作成時に定義されたソート順とは逆になるため、Cassandraが最初にデータを取得してからメモリ内でソートするため、クエリの実行速度が遅くなります。


5.3. Eコマースの顧客と製品

eコマースストアを運営しており、

Customer

および

Product

情報をCassandra内に格納しているとしましょう。このユースケースに関する一般的なクエリパターンをいくつか見てみましょう。

  1. 顧客情報を取得

  2. 製品情報を取得する

  3. 特定の

    Product

    が好きなすべての

    Customers

    を入手

  4. 指定された

    Customer

    のすべての

    Products

    を取得する


Customer



Product

の情報を格納するために別々のテーブルを使うことから始めましょう。ただし、上記の3番目と4番目のクエリをサポートするには、かなりの量の非正規化を導入する必要があります。

これを実現するために、さらに2つのテーブル「

Customer

by

Product

」と「

Product

by

Customer

」を作成します。

この例のCassandraテーブルスキーマを見てみましょう。

CREATE TABLE Customer (
  cust__id text,
  first__name text,
  last__name text,
  registered__on timestamp,
  PRIMARY KEY (cust__id));

CREATE TABLE Product (
  prdt__id text,
  title text,
  PRIMARY KEY (prdt__id));

CREATE TABLE Customer__By__Liked__Product (
  liked__prdt__id text,
  liked__on timestamp,
  title text,
  cust__id text,
  first__name text,
  last__name text,
  PRIMARY KEY (prdt__id, liked__on));

CREATE TABLE Product__Liked__By__Customer (
  cust__id text,
  first__name text,
  last__name text,
  liked__prdt__id text,
  liked__on timestamp,
  title text,
  PRIMARY KEY (cust__id, liked__on));

注:特定の顧客による最近お気に入りの商品と、特定の商品を最近気に入った顧客の両方のクエリをサポートするために、「

liked

on__」列をクラスタリングキーとして使用しました。

クエリを見て、最近商品“

Pepsi

”を気に入った10の顧客を見つけましょう。

SELECT **  FROM Customer__By__Liked__Product WHERE title = "Pepsi" LIMIT 10



Anna

」という名前の顧客が最近気に入った商品(最大10個)を検索するクエリを見てみましょう。

SELECT **  FROM Product__Liked__By__Customer
  WHERE first__name = "Anna" LIMIT 10


6. 非効率的なクエリパターン

Cassandraがデータを保存する方法が原因で、以下を含むいくつかのクエリパターンはまったく効率的ではありません。

  • ** 複数のパーティションからデータを取得する – これには

複数のノードからデータを取得し、一時的に保存するためのコーディネータ
ヒープに入れてから結果を返す前にデータを集計します。
ユーザー


結合ベースのクエリ** – その分散された性質のために、Cassandraは行います

リレーショナルデータベースと同じようにクエリでのテーブル結合はサポートされていません。その結果、


結合を使った

クエリは遅くなり、矛盾や可用性の問題を引き起こす可能性があります


7. 結論

このチュートリアルでは、Cassandraでデータモデリングにアプローチする方法に関するベストプラクティスをいくつか取り上げました。

Cassandraクラスターから最高のパフォーマンスを引き出す正しいデータモデルを設計するには、コアとなる概念を理解し、事前にクエリパターンを識別する必要があります。