Cassandra - 如何使用cqlsh创建复合列名称(而不是键)

时间:2012-09-01 00:23:04

标签: cassandra

我正在尝试在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其中column_name如“policy:*”和entp_name = xyz,以便只读取所有策略列?
  3. 如何为列设置空值。我在一些论坛中读到你不应该设置null,因为它等同于没有值。但考虑一下这种情况 你有一个静态模式col1,col2和col3,我想插入一行col3 = null,但col1和col2有一些值。什么是插入此类数据的cqlsh语法(我在文档中找不到它),因为以下内容给出了错误:

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

  4. 谢谢!

2 个答案:

答案 0 :(得分:4)

  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');
    
  4. 希望有所帮助!

答案 1 :(得分:0)

如果在复合

中定义另一列,则可以在一个表中使用规则和策略
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';