【问题标题】:Cassandra -How to create composite column name (not key) using cqlshCassandra - 如何使用 cqlsh 创建复合列名(非键)
【发布时间】:2012-08-26 18:40:25
【问题描述】:

我正在尝试在 Cassandra 1.1 中对列族进行建模,逻辑上看起来像这样:

Entp: //CF
 //rowkey->  entp_name_xyz: 
                   {entp_full_name: "full_name_xyz",
                    some_value: 1,
                    policy: {policy_name: "default policy",
                             type: "type 1",
                             prop_1: "prop 1",
                             ...
                             },
                    rules: {rule_1:, rule_2:,rule_3:}
                   }

我要建模的查询是: 获取给定 entp 名称的所有策略,获取给定 entp 的所有规则,获取给定 entp_name 的所有列 我计划将此列族建模为具有“宽行”,其中一行看起来像这样:

RowKey:- entp_name_xyz,
column_name:- policy:p1
Value:-{JSON object - {policy_name: "default policy", type: "type 1",                 prop_1: "prop 1", ...}}
column_name:- policy:p2
Value:-{JSON object - {policy_name: "default policy2", type: "type 1",                 prop_1: "prop 1", ...}}
column_name: rule:r1 where r1 is a rowkey of a Rules column family
Value: Null

现在我的问题是在 cqlsh 或 cassandra-cli 中,

  1. 如何插入复合列名称,例如 policy:p1?
  2. 使用此方案,是否可以进行如下查询: select * from entp where column_name like "policy:*" and entp_name= xyz 为了只读取所有策略列?
  3. 如何为列设置空值。我在一些论坛上读到,您不需要设置 null,因为它相当于没有值。但是考虑一下这种情况 你有一个带有 col1、col2 和 col3 的静态模式,我想插入一行 col3 =null,但 col1 和 col2 有一些值。插入此类数据的 cqlsh 语法是什么(我在文档中找不到),因为以下给出了错误:

    插入 entp (col1,col2,col3) 值("abc","xyz", null)

谢谢!

【问题讨论】:

    标签: cassandra


    【解决方案1】:
    1. 在 CQL3 中使用复合材料要容易得多,您可以在 cassandra 1.1 中使用它,所以我将在我的回答中使用它。 CQL3 中具有多组件主键的表相当于存储引擎(Cassandra)层中的宽行。

      如果我已经解释了您的政策和规则数据是什么样的,那么这是一个可能的答案:

      CREATE TABLE entp_policies (
          entp_name text,
          policy_name text,
          policy_value text,
          PRIMARY KEY (entp_name, policy_name)
      );
      CREATE TABLE entp_rules (
          entp_name text,
          rule_name text,
          rule_value text,
          PRIMARY KEY (entp_name, rule_name)
      );
      

      你会这样使用它:

      INSERT INTO entp_policies (entp_name, policy_name, policy_value)
           VALUES ('entp_name_xyz', 'p1',
                   '{policy_name: "default policy", type: "type 1", ...}');
      
      INSERT INTO entp_policies (entp_name, policy_name, policy_value)
           VALUES ('entp_name_xyz', 'p2',
                   '{policy_name: "default policy2", type: "type 1", ...}');
      
      INSERT INTO entp_rules (entp_name, rule_name) VALUES ('entp_name_xyz', 'r1');
      
      -- Get all policies given an entp name
      SELECT * FROM entp_policies WHERE entp_name = 'entp_name_xyz';
      
      -- Get all rules given an entp
      SELECT * FROM entp_rules WHERE entp_name = 'entp_name_xyz';
      
      -- Get all columns given an entp_name (both of the above)
      
    2. 使用您的方案,是的,可以进行这样的查询,但它会比我的版本更挑剔,而且 CQL2 已被弃用。

    3. 没错,您只是避免插入值。 cql (yet) 中没有明确的NULL,但你可以这样做:

      insert into entp (col1,col2) values ('abc','xyz');
      

    希望有帮助!

    【讨论】:

    • 感谢“保罗”!只有一个关于 3 的问题,如果我按照您在上面显示的方式发出第 3 列没有值的插入,那么使用 cqlsh 时,“从表中选择 *”不会返回该行。它返回所有其他包含所有列中的值的行。这是一个错误还是背后有某种原因?
    • @user931518 这取决于你的entp CF 的样子。您需要插入至少一个不属于主键的列,否则该行将被视为不存在(Cassandra 语义,这使得在分布式世界中生活变得更加容易)。
    • 另外,有没有办法以这样一种方式对数据进行建模,以便通过单个查询获取给定 entp 的 policy_value 和 rules_values?
    【解决方案2】:

    如果您在组合中定义另一列,则可以在一个表中同时使用规则和策略

    create table entp_details(
        entp_name text,
        type text,
        name text,
        value text,
        primary key (entp_name, type, name));
    

    这里的类型是(策略或规则)。

    INSERT INTO entp_details (entp_name, type, name, value)
         VALUES ('entp_name_xyz', 'Policy', 'p1',
                 '{policy_name: "default policy", type: "type 1", ...}');
    
    INSERT INTO entp_details (entp_name,  type, name, value)
         VALUES ('entp_name_xyz', 'Policy', 'p2',
                 '{policy_name: "default policy2", type: "type 1", ...}');
    
    INSERT INTO entp_details (entp_name, type, name, value) VALUES ('entp_name_xyz', 'Rule', 'r1', null);
    

    查询就像

    select * from entp_details WHERE entp_name = 'entp_name_xyz' and type = 'Policy';
    select * from entp_details WHERE entp_name = 'entp_name_xyz' and type = 'Rule';
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-12
      • 2012-06-29
      • 2013-10-06
      • 2017-01-09
      • 2013-11-01
      • 2017-10-15
      • 2013-07-08
      相关资源
      最近更新 更多