由于多种原因,这个特定的模型有些挑战性。
例如,使用框 ID 作为行键,查询框的范围将需要在 Cassandra 中进行范围查询(而不是列切片),这意味着使用有序分区器。有序分区器几乎总是一个坏主意。
另一个挑战来自需要增加项目大小,因为这需要使用计数器列族。计数器列族仅存储计数器值。
暂时不考虑对一系列框 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 突变既是原子的,又是孤立的。
从技术上讲,您还可以将所有这些非规范化到一个表中。例如:
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
了一个计数器列族,它限制了您将来如何发展模式。