CQL3のCassandra 2.0でのデータモデリング

この記事は、Cassandraデータベースに最初の「テーブル」を作成しようとする人々を対象としています。



Cassandraのいくつかのリリースを投稿するために、開発者はこのデータベースの使いやすさを目的とした適切なベクトルを採用しました。 速度やフォールトトレランスなどの利点を考えると、管理と書き込みを行うことは困難でした。 開発を開始して開始する前に行う必要のあるタンバリンとのダンスの数が最小限に抑えられました-bashのいくつかのコマンドまたはWindowsの1つの.msi。

さらに、最近更新されたCQL(クエリ言語)により、開発者は作業が楽になり、バイナリのやや複雑な言語のThriftに取って代わりました。

個人的には、カッサンドラに関するロシア語のガイドラインがないという問題に直面しました。 私の意見では、この記事で取り上げたい最も難しいトピックです。 データベースを設計する方法は?





免責事項






教育プログラム







Cの基本的なデータモデリングルール*



Kassandraは、最大の書き込みおよび読み取り速度を重視した分散データベースとして作成されました。 アプリケーションのSELECT



クエリに応じて「テーブル」をモデル化する必要があります


SQLでは、テーブル、テーブル間の関係、およびSELECT ... JOIN ...



して、必要なものと方法をスローすることに慣れています。 結合は、RDBMSのパフォーマンスに関する主な問題です。 CQLにはありません。



最初の例。



ある会社の従業員がいます。 CQLでテーブル(実際には列ファミリと呼ばれますが、SQLからCQLへの移行を簡単にするためにwordテーブルを使用)を作成し、データを入力します。

 CREATE TABLE employees ( name text, --   age int, -- -    role text, --  -  PRIMARY KEY (name)); --     INSERT INTO employees (name, age, role) VALUES ('john', 37, 'dev'); INSERT INTO employees (name, age, role) VALUES ('eric', 38, 'ceo');
      
      





C *のテーブルには、PRIMARY KEYが必要です。 目的の文字列が保存されているノードを検索するために使用されます。



データを読み取ります。

 SELECT * FROM employees;
      
      





この写真は、手で装飾されたcqlsh出力です。





リレーショナルデータベースからの通常のテーブルのように見えます。 C *は2行を作成します。



注意! これらはテーブルではなく、2つの内部行構造です。 少しcな場合、各行は小さなテーブルのようなものであると言えます。 さらに明確。



2番目の例。



複雑です。 会社名を追加します。

 CREATE TABLE employees ( company text, name text, age int, role text, PRIMARY KEY (company,name) --    :   company    name ); INSERT INTO employees (company, name, age, role) VALUES ('OSC', 'eric', 38, 'ceo'); INSERT INTO employees (company, name, age, role) VALUES ('OSC', 'john', 37, 'dev'); INSERT INTO employees (company, name, age, role) VALUES ('RKG', 'anya', 29, 'lead'); INSERT INTO employees (company, name, age, role) VALUES ('RKG', 'ben', 27, 'dev'); INSERT INTO employees (company, name, age, role) VALUES ('RKG', 'chan', 35, 'ops');
      
      





データを読む:

 SELECT * FROM employees;
      
      







主キーに注意してください。 最初のパラメータ- company



-は配布キーであり、それ以降はノードの検索に使用されます。 2番目のname



キーはクラスタリングキーです。 彼は柱になります。 つまり データを列名に変換します。 通常の4バイトでは「エリック」で、列名の一部になりました。



これが、 内部構造の外観です。



ご覧のとおり:





3番目の例。



さらに難しい。 大文字は列の名前です。 小文字-データ。

 CREATE TABLE example ( A text, B text, C text, D text, E text, F text, PRIMARY KEY ((A,B), C, D)); --    (A,B)    (C,D) INSERT INTO example (A, B, C, D, E, F) VALUES ('a', 'b', 'c', 'd', 'e', 'f'); INSERT INTO example (A, B, C, D, E, F) VALUES ('a', 'b', 'c', 'g', 'h', 'i'); INSERT INTO example (A, B, C, D, E, F) VALUES ('a', 'b', 'j', 'k', 'l', 'm'); INSERT INTO example (A, B, C, D, E, F) VALUES ('a', 'n', 'o', 'p', 'q', 'r'); INSERT INTO example (A, B, C, D, E, F) VALUES ('s', 't', 'u', 'v', 'w', 'x');
      
      





データを読み取ります。

 SELECT * FROM example;
      
      









これで、 配布キーはcomposite- (A,B)



です。 クラスターキーもコンポジット-C、Dです。



内部構造はより複雑になりました。 c, d, g, k, o, p, u, v



などのデータは、EおよびFとともに列名に含まれます。









なぜそんなに複雑なのですか?



これは、分散データベースに無限量のデータを記録および保存するための最速の方法です。 C *は、書き込み/読み取り速度に重点を置いて設計されました。 ここでは、たとえば、 MongoDB、HBase、およびC *速度を比較します



実生活の例



1秒間に1000回発生するイベントがいくつかあります。 たとえば、インジケータはノイズレベルセンサーから取得されます。 10個のセンサー。 それぞれが1秒間に100回データを送信します。 3つのタスクがあります。

  1. データベースサーバー(ノード)が作業を停止した場合は、書き込みを続けます。
  2. 何であれ、1000の新しいレコードを数秒で記録する時間。
  3. 数ミリ秒で任意の日のセンサーのグラフを提供します。
  4. 可能な限り迅速に、任意の期間の任意のセンサーのグラフを提供します。




最初と2番目のポイントは簡単です。


複数のノードをインストールし、それぞれを自律的にする必要があります。 それらの1つをクラウドに取り込むこともできます。



3番目のポイントは主要なトリックです。


1日のデータを1行で保存します。

 CREATE TABLE temperature_events_by_day ( day text, -- Text of the following format: 'YYYY-MM-DD' sensor_id uuid, event_time timestamp, temperature double, PRIMARY KEY ((day,sensor_id), event_time) --  .  (day,sensor_id)    (event_time) ) WITH CLUSTERING ORDER BY event_time DESC; --    
      
      





配布キーは日+センサーの一意の組み合わせであるため、1日のデータはセンサーごとに個別の行に保存されます。 文字列内の逆ソートのおかげで、「指先で」最も重要な(最後の)データを取得できます。

配布キー(日)の検索はC *では非常に高速な操作であるため、3番目のポイントは完了したと見なすことができます。



第四ポイント


もちろん、日/日検索を行うことができますが、日中はタイムスタンプを比較できます。 しかし、多くの日があります。

結局のところ、センサーは10個しかありません。 これは使用できますか? 1つのセンサーが1行であると想像するなら可能です。 この場合、C *はディスク上の10行すべての場所をメモリにキャッシュします。



2番目のテーブルを作成して、同じデータを保存しますが、日は除外します。

 CREATE TABLE temperature_events ( sensor_id uuid, event_time timestamp, temperature double, PRIMARY KEY (sensor_id, event_time) --   (sensor_id)    (event_time) ) WITH CLUSTERING ORDER BY event_time DESC; --    
      
      







そして、データを挿入するとき、20億列に慣れないように各セルの寿命を制限します。 弊社では、各センサーが毎秒100個以下の読み取り値を提供します。 ここから:

2**31 / (24 * 60 * 60 * 100 /) = 2147483648 / (24 * 60 * 60 * 100) = 248.55





248日後、最も古いデータを静かに削除する必要があります。

 INSERT INTO temperature_events (sensor_id, event_time, temperature) VALUES ('12341234-1234-1234-123412', 2535726623061, 36.6) TTL 21427200; -- 248 days in seconds
      
      







アプリケーションコードでは、要求されたデータが過去248日間を超えた場合にtemperature_events_by_day



テーブルを使用し、そうでない場合はtemperature_events_by_day



を使用するという条件を設定する必要があります。 後者の検索は数ミリ秒高速になります。



「なんてナンセンスだ! なぜ2番目のテーブルですか?」と思うでしょう。 私は繰り返します:C *データベースでは、同じ値を数回保存するのが標準であり、正しいモデルです。 賞金は次のとおりです。





ソース



この順序で表示することをお勧めします。

  1. ウェビナー-CQL3がCassandraの内部データ構造にどのようにマッピングされるかを理解します。
  2. ウェビナー- データモデルは死んでいます、データモデルは長く生きています
  3. ウェビナー- スーパーモデラーになる
  4. ウェビナー- 世界の次なるトップデータモデル
  5. 完全なCQL3ドキュメント-Cassandra Query Language(CQL)v3




シリーズの次の記事




UPD:用語の修正。 適切な場所で「マスターキー」という単語を「配布キー」に置き換えました。 いくつかの場所に「クラスターキー」の概念を追加しました。



All Articles