【问题标题】:Can't create table with composite key using Astyanax client无法使用 Astyanax 客户端创建具有复合键的表
【发布时间】:2012-08-08 13:02:24
【问题描述】:

如何使用 astyanax 客户端创建带有复合键的表。现在我已经用 cqlsh -3 创建了它,这就是它在 cli 中的样子:

[default@KS] describe my_cf;
    ColumnFamily: my_cf
      Key Validation Class: org.apache.cassandra.db.marshal.UTF8Type
      Default column value validator: org.apache.cassandra.db.marshal.UTF8Type
      Columns sorted by: org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.TimeUUIDType,org.apache.cassandra.db.marshal.UTF8Type)
      GC grace seconds: 864000
      Compaction min/max thresholds: 4/32
      Read repair chance: 0.1
      DC Local Read repair chance: 0.0
      Replicate on write: true
      Caching: KEYS_ONLY
      Bloom Filter FP chance: default
      Built indexes: []
      Compaction Strategy: org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy
      Compression Options:
        sstable_compression: org.apache.cassandra.io.compress.SnappyCompressor

这就是我希望它在 cqlsh 中的样子:

 CREATE TABLE my_cf (
                   ... key text,
                   ... timeid timeuuid,
                   ...   flag boolean,
                   ...   data text,
                   ... PRIMARY KEY (key, timeid));

我让它使用存储为 blob 的复合键,这是一个问题。

我的代码

public class MyKey {
    @Component(ordinal=0)
    private String key;
    @Component(ordinal=1)
    private UUID timeid;
 //...
}

CF

public static ColumnFamily<MyKey, String> MY_CF = ColumnFamily
        .newColumnFamily("my_cf",
                new AnnotatedCompositeSerializer<MyKey>(MyKey.class),
                StringSerializer.get());

KS

                ksDef = cluster.makeKeyspaceDefinition();

                ksDef.setName(keyspaceName)
                        .setStrategyOptions(keyspaceOptions)
                        .setStrategyClass("SimpleStrategy")
                        .addColumnFamily(
                                cluster.makeColumnFamilyDefinition()
                                        .setName(MY_CF.getName())
                                        .setComparatorType("UTF8Type")
                                        .setDefaultValidationClass("UTF8Type")
// blob if no key validation class specified
// and something looking as a string if I use this:     .setKeyValidationClass("CompositeType(UTF8Type, TimeUUIDType)")
// anyway there's a single column per composite key

                                        .addColumnDefinition(
                                                cluster.makeColumnDefinition()
                                                        .setName("flag")
                                                        .setValidationClass(
                                                                "BooleanType"))
                                        .addColumnDefinition(
                                                cluster.makeColumnDefinition()
                                                        .setName("data")
                                                        .setValidationClass(
                                                                "UTF8Type")));
                cluster.addKeyspace(ksDef);

变异

            MutationBatch m = ks.prepareMutationBatch();

            for (char keyName = 'A'; keyName <= 'C'; keyName++) {
                MyKey myKey = new MyKey("THEKEY_" + keyName, TimeUUIDUtils.getUniqueTimeUUIDinMillis());
                ColumnListMutation<String> cfm = m.withRow(MY_CF, myKey);
                cfm.putColumn("flag", true, null);
                cfm.putColumn("data", "DATA_" + keyName, null);
            }
            m.execute();

cqlsh:KS>describe columnfamily my_cf;

CREATE TABLE my_cf (
  KEY blob PRIMARY KEY,
  flag boolean,
  data text
) WITH ...

cqlsh:KS>从 my_cf 中选择 *;

  key                                                      | flag | data
----------------------------------------------------------+--------+---------
 00064953494e5f420000109f4513d0e3ac11e19c400022191ad62b00 | True   | DATA_B

cqlsh:KS> select * from my_cf where key = 'THEKEY_B' order by timeid desc;

Bad Request: Order by on unknown column timeid

在下面的 cassandra-cli 中看起来不正确吗?为什么它在 cqlsh 中不起作用?

cassandra-cli] 列出 my_cf;

RowKey: THEKEY_B:09f29941-e3c2-11e1-a7ef-0022191ad62b
=> (column=active, value=true, timestamp=1344695832788000)
=> (column=data, value=DATA_B, timestamp=1344695832788000)

我做错了什么? (astyanax 1.0.6,卡桑德拉 1.1.2) cqlsh>[cqlsh 2.2.0 |卡桑德拉 1.1.2 | CQL 规范 3.0.0 | Thrift 协议 19.32.0]

【问题讨论】:

    标签: cassandra cql astyanax


    【解决方案1】:

    据我所知,复合主键 代表协议和接口的主要分歧 cassandra 和您使用的协议控制着您拥有的功能 访问。

    例如,astyanax 和 hector 主要是节俭协议 客户端,而 CQL 不仅仅是一种语言,它是(或将是?)一种二进制协议。

    这两个协议不等价,CQL3 与复合主协议 键使事情变得非常不同。

    关于带有复合主键的“TABLES”需要理解的是,它们 本质上转换为具有复合列名的宽行。这 主键的第一部分是行键,其余部分是 与 TABLE 列名一起用作前缀作为列名 宽行。

    在您的实例中,行键是“键”,列前缀是 “timeid”,所以你插入的标志字段实际上是一个 名为 :flag 的列和数据是 :data 等等 开。

    为了使其工作,cassandra 的 CQL 协议接口是 将“TABLES”转换为宽行并透明地处理所有 该列命名。

    thrift 界面不处理这些东西,当你 做一个突变,它只是像以前一样写列,没有 虚拟寻址。

    因此,事实上,结果在您的 cassandra-cli 中看起来并不正确。如果您从 cqlsh -3 进行插入,从 cassandra-cli 的角度来看它应该是这样的(带有简单的文本日期):

    [default@testapp] list my_cf;
    RowKey: mykey
    => (column=20120827:data, value=some data, timestamp=1346090889361000)
    => (column=20120827:flag, value=, timestamp=1346090889361001)
    

    CQL3 和表看起来确实很有吸引力,但需要做出一些权衡,而且似乎还没有可靠的 Java 客户端支持。

    【讨论】:

    猜你喜欢
    • 2015-01-15
    • 1970-01-01
    • 1970-01-01
    • 2014-12-12
    • 1970-01-01
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多