nosql - Cassandra 中的一对多等价物和数据模型优化

标签 nosql cassandra

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

例如:

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

 { ... }
}

我读到最好使用复合列而不是 super 列,所以我需要一个实现这一点的最佳方法的例子。我的查询是这样的:
  • 通过 Id 获取盒子的元素
  • 获取带有元素的前 20 个盒子(用于在页面上显示一系列带有元素的盒子)
  • 按项目 id 更新项目大小(按数字增加大小)
  • 通过用户 ID 获取所有框(属于特定用户的所有框)

  • 我期待大量写入来更改框中每个项目的大小。我想知道无需使用 super 列即可实现它的最佳方法。此外,我不介意得到一个考虑 Cassandra 1.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一个计数器列族,它限制了你在 future 发展模式的方式。

    关于nosql - Cassandra 中的一对多等价物和数据模型优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13110363/

    相关文章:

    javascript - 使用 Mongoose 创建数据库模型

    node.js - 使用 Mongoose ORM 的 killer 锏是什么?

    indexing - 扫描 Dynamodb 中的特定行

    erlang - 从 erlang 插入 cassandra

    Cassandra 服务器抛出 java.lang.AssertionError : DecoratedKey(. ..) != DecoratedKey

    hadoop - 什么 cassandra 客户端用于 haoop 集成?

    r - 如何使用 R 连接到 Redis(rredis 和特定套接字)

    sql-server - 从 SQL Server 和 Azure DocumentDB 查询数据?

    java - Cassandra Session vs Cluster 分享什么?

    django - 如何使用cql-engine将图像存储到cassandra数据库中?