Nosql Cassandra和数据模型优化中的一对多等效

Nosql Cassandra和数据模型优化中的一对多等效,nosql,cassandra,Nosql,Cassandra,我正在用来自RDBMS的Cassandra对我的数据库进行建模。我想知道如何创建嵌入在同一列名中的一对多关系,并为表建模以满足以下查询需要 例如: Boxes:{ 23442:{ belongs_to_user: user1, box_title: 'the box title', items:{ 1: { name: 'itemname1', size: 44 }, 2: { n

我正在用来自RDBMS的Cassandra对我的数据库进行建模。我想知道如何创建嵌入在同一列名中的一对多关系,并为表建模以满足以下查询需要

例如:

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

 { ... }
}
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;
我读到最好使用复合列而不是超级列,所以我需要一个实现这一点的最佳方法的示例。我的问题如下:

  • 按Id获取长方体的项目
  • 获取前20个框及其项目(用于在页面上显示一系列框及其项目)
  • 按项目id更新项目大小(按数字增加大小)
  • 按用户ID获取所有框(属于特定用户的所有框)
我期待着大量的文字修改框中每个项目的大小。我想知道在不需要使用超级列的情况下实现它的最佳方法。此外,我不介意得到一个考虑到Cassandra 1.2新特性的解决方案,因为我将在生产中使用它


谢谢

我先在PlayOrm的对象中思考,然后在下面显示列模型

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

User {
   @NoSqlId
   TimeUUID uuid;
   @OneToMany
   List<Box> boxes;
}
我不知道你说的是什么意思,但是你能拿到前20个盒子吗?顶框是指顶框中的项目数


迪恩

出于多种原因,这种特殊的模式有些挑战性

例如,使用框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';
需要注意的是,上面的批量突变既是原子突变,也是孤立突变

从技术上讲,您还可以将所有这些反规范化为一个表。例如:

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

 { ... }
}
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;

但是,这并不能保证正确性。例如,此模型使同一框中的项目可能具有不同的用户或标题。而且,由于这使得
box
成为一个计数器列族,它限制了您将来如何发展模式。

您可以使用查询驱动方法来进行数据建模。您有三种广泛的访问路径:
1) 每个查询的分区
2) 分区+每个查询(一个或多个分区)
3) 表或表+每个查询

最有效的选项是“每个查询的分区”。文章可以帮助你在这种情况下,一步一步。它的样本正是一对多关系


根据,您将有几个具有类似列的表。您可以通过物化视图或批处理日志(作为替代方法)来管理此问题。

谢谢您的回答。前20个框,意味着用户将这些框插入到数据库中,我想得到最后插入的前20个框的数据时间。比如从一长串评论中获取前10条评论,这样我就可以在我的应用程序中对其进行分页,并生成第1页、第2页、第3页,并在每个框中显示根据插入的数据/时间排序的所有框。您将
大小计数器
作为
框项目
列族的列键。但在INSERT查询中,您正在添加名称(
box\u项(id、项、名称)
)。你能解释一下那个尺码插在哪里吗?