この特定のモデルは、いくつかの理由から、やや困難です。
たとえば、ボックス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
カウンター列ファミリーが作成されるため、将来スキーマを進化させる方法が制限されます。