4

RDBMSから取得したCassandraでデータベースをモデリングしています。同じ列名に埋め込まれた1対多の関係を作成し、次のクエリのニーズに合うようにテーブルをモデル化する方法を知りたいです。

例えば:

Boxes:{
  23442:{
    belongs_to_user: user1,
    box_title: 'the box title',
    items:{
      1: {
         name: 'itemname1',
         size: 44
      },
      2: {
        name: 'itemname2',
        size: 24
      }
    }
  },

 { ... }
}

スーパーカラムの代わりにコンポジットカラムを使用する方が望ましいと読んだので、これを実装するための最良の方法の例が必要です。私のクエリは次のようなものです。

  • IDでボックスのアイテムを取得
  • アイテムを含む上位20個のボックスを取得します(ページにアイテムを含むボックスの範囲を表示するため)
  • アイテムIDでアイテムサイズを更新(サイズを数値でインクリメント)
  • ユーザーIDですべてのボックスを取得(特定のユーザーに属するすべてのボックス)

ボックス内の各アイテムのサイズを変更するために、多くの書き込みが行われることを期待しています。スーパーカラムを使用せずに実装するための最良の方法を知りたいです。さらに、Cassandra 1.2の新機能を考慮に入れたソリューションを入手してもかまいません。これは、本番環境で使用するためです。

ありがとう

4

3 に答える 3

2

この特定のモデルは、いくつかの理由から、やや困難です。

たとえば、ボックスIDを行キーとして使用する場合、ボックスの範囲をクエリするには、(列スライスではなく)Cassandraで範囲クエリを実行する必要があります。これは、順序付きパーティショナーを使用することを意味します。注文されたパーティショナーは、ほとんどの場合、悪い考えです。

もう1つの課題は、カウンター列ファミリーの使用を必要とするため、アイテムサイズをインクリメントする必要があることです。カウンタ列ファミリは、カウンタ値のみを格納します。

ボックスIDの範囲の必要性を一時的に別にして、次のようにCQL3の複数のテーブルを使用してこれをモデル化できます。

CREATE TABLE boxes (                                                                       
   id int PRIMARY KEY,                                                                 
   belongs_to_user text,                                                               
   box_title text,                                                                     
);
CREATE INDEX useridx on boxes (belongs_to_user);

CREATE TABLE box_items (                                                                   
   id int,                                                                             
   item int,                                                                           
   size counter,                                                                       
   PRIMARY KEY(id, item)                                                               
);

CREATE TABLE box_item_names (
    id int PRIMARY KEY,
    item int,
    name text
);

BEGIN BATCH
  INSERT INTO boxes (id, belongs_to_user, box_title) VALUES (23442, 'user1', 'the box title');
  INSERT INTO box_items (id, item, name) VALUES (23442, 1, 'itemname1');
  INSERT INTO box_items (id, item, name) VALUES (23442, 1, 'itemname2');
  UPDATE box_items SET size = size + 44 WHERE id = 23442 AND item = 1;                       
  UPDATE box_items SET size = size + 24 WHERE id = 23442 AND item = 2;
APPLY BATCH

-- Get items for box by ID                                                               
SELECT size FROM box_items WHERE id = 23442 AND item = 1;

-- Boxes by user ID
SELECT * FROM boxes WHERE belongs_to_user = 'user1';

上記のBATCH変異はアトミックであり、分離されていることに注意することが重要です。

技術的に言えば、これらすべてを1つのテーブルに非正規化することもできます。例えば:

CREATE TABLE boxes (
   id int,
   belongs_to_user text,
   box_title text,
   item int,
   name text,
   size counter,
   PRIMARY KEY(id, item, belongs_to_user, box_title, name)
);

UPDATE boxes set size = item_size + 44 WHERE id = 23442 AND belongs_to_user = 'user1'
    AND box_title = 'the box title' AND name = 'itemname1' AND item = 1;

SELECT item, name, size FROM boxes WHERE id = 23442;

ただし、これは正確性を保証するものではありません。たとえば、このモデルでは、同じボックスのアイテムに異なるユーザーまたはタイトルを付けることができます。また、これによりboxesカウンター列ファミリーが作成されるため、将来スキーマを進化させる方法が制限されます。

于 2012-10-29T12:34:51.900 に答える
0

PlayOrmのオブジェクトで最初に考えてから、以下の列モデルを示します。

Box {
   @NoSqlId
   String id;
   @NoSqlEmbedded
   List<Item> items;
}

User {
   @NoSqlId
   TimeUUID uuid;
   @OneToMany
   List<Box> boxes;
}

その場合、ユーザーはそのような行になります

rowkey = uuid=<someuuid> boxes.fkToBox35 = null, boxes.fktoBox37=null, boxes.fkToBox38=null

上記の形式はcolumname=valueであり、一部の列名は複合であり、一部は複合ではないことに注意してください。

ボックスはもっと面白く、Itemにフィールドnameとidnumberがあると言うと、ボックスの行は次のようになります。

rowkey = id=myid, items.item23.name=playdo, items.item23.idnumber=5634, itesm.item56.name=pencil, items.item56.idnumber=7894

トップ20のボックスを取得する上で、あなたが何を意味したのかわかりませんか?それらの中のアイテムの数によって意味するトップボックス?

ディーン

于 2012-10-29T11:34:51.600 に答える
0

データモデリングには、クエリ駆動型の方法論を使用できます.3つの広範なアクセスパスがあります:
1)クエリごとの
パーティション2)クエリごとのパーティション+(1つ以上のパーティション)
3)クエリごとのテーブルまたはテーブル+

最も効率的なオプションは、「<strong>クエリごとのパーティション」です。この記事は、この場合、段階的に役立ちます。サンプルは正確に1対多の関係です。

これによると、いくつかの同様の列を持ついくつかのテーブルがあります。これは、マテリアライズド・ビューまたはバッチ・ログ(代替アプローチとして)によって管理できます。

于 2016-03-01T05:50:07.497 に答える