创建复合列cassandra

时间:2012-07-12 19:19:09

标签: nosql cassandra hector

我需要存储每个每晚构建的基准运行。为此,我提出了以下数据模型。

BenchmarkColumnFamily= {

   build_1: {
       (Run1, TPS) : 1000K
       (Run1, Latency) : 0.5ms
       (Run2, TPS) : 1000K
       (Run2, Latency) : 0.5ms
       (Run3, TPS) : 1000K
       (Run3, Latency) : 0.5ms
    }

    build_2: {
       ...
    }
...

}

为了创建这样的模式,我在cassandra-cli上提出了以下命令:

create column family BenchmarkColumnFamily with 
    comparator = 'CompositeType(UTF8Type,UTF8Type)' AND 
    key_validation_class=UTF8Type AND
    default_validation_class=UTF8Type AND
    column_metadata = [
    {column_name: TPS, validation_class: UTF8Type}
    {column_name: Latency, validation_class: UTF8Type}
    ];

以上命令是否创建了我打算创建的模式?我混淆的原因是,当我使用以下内容将数据插入上述CF时:  set BenchmarkColumnFamily['1545']['TPS']='100'; 即使比较器类型是复合的,它也会成功插入。此外,即使以下命令也能成功执行

set BenchmarkColumnFamily['1545']['Run1:TPS']='1000';

我失踪了什么?

2 个答案:

答案 0 :(得分:2)

cassandra-cli工具在处理复合材料方面非常有限。此外,Cassandra在验证显式的,用户提供的复合材料方面可能会发生一些意想不到的事情。我不知道你的情况的确切答案,但我可以告诉你,你会发现使用CQL 3引擎更容易使用 这种模型。

例如,您的模型可以表示为:

CREATE TABLE BenchmarkColumnFamily (
    build text,
    run int,
    tps text,
    latency text,
    PRIMARY KEY (build, run)
);

INSERT INTO BenchmarkColumnFamily (build, run, tps, latency) VALUES ('1545', 1, '1000', '0.5ms');

有关如何转换为存储引擎层的详细信息,请参阅this post

答案 1 :(得分:2)

我认为你做错了什么。 CLI正在使用org.apache.cassandra.db.marshal.AbstractType<T>.fromString()根据类型解析值的字符串。对于Composite类型,它使用':'作为字段分隔符(不是我见过的文档,但我已经尝试使用Java代码来说服自己。

没有':',它似乎只设置了Composite的第一部分,并将第二部分保留为null。要设置第二个,您可以使用

set BenchmarkColumnFamily['1545'][':NOT_TPS']='999';

从CLI中,转出CF:

list BenchmarkColumnFamily;

你应该看到所有的名字(对于所有的行),例如

RowKey: 1545
=> (column=:NOT_TPS, value=999, timestamp=1342474086048000)
=> (column=Run1:TPS, value=1000, timestamp=1342474066695000)
=> (column=TPS, value=100, timestamp=1342474057824000)

没有办法(通过CLI)将复合元素约束为非空或特定值,这是您在代码中必须做的事情。

此外,创建CF的column_metadata选项是不必要的,因为您已经将默认验证列为UTF8Type。