我在Cassandra中建模我的数据库,来自RDBMS。我想知道如何创建一对多关系,该关系嵌入在相同的列名中并为我的表建模以满足以下查询需求。
例如:
Boxes:{
23442:{
belongs_to_user: user1,
box_title: 'the box title',
items:{
1: {
name: 'itemname1',
size: 44
},
2: {
name: 'itemname2',
size: 24
}
}
},
{ ... }
}
我读到它最好使用复合列而不是超级列,所以我需要一个实现它的最佳方法的例子。我的疑问如下:
我期待大量的写入来改变框中每个项目的大小。我想知道实现它的最佳方法,而无需使用超级列。此外,我不介意考虑将Cassandra 1.2新功能考虑在内的解决方案,因为我将在生产中使用它。
由于
答案 0 :(得分:2)
由于种种原因,这种特殊模式有些挑战。
例如,使用框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
成为一个计数器列族,因此它限制了您将来如何进化模式。
答案 1 :(得分: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具有字段名称和idnumber,然后框行将是
rowkey = id=myid, items.item23.name=playdo, items.item23.idnumber=5634, itesm.item56.name=pencil, items.item56.idnumber=7894
我不确定你的前20名盒子是什么意思?顶盒意味着它们中的项目数量?
迪安
答案 2 :(得分:0)