无法使用 Astyanax 客户端创建带有复合键的表 [英] Can't create table with composite key using Astyanax client

查看:18
本文介绍了无法使用 Astyanax 客户端创建带有复合键的表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How do I create table with composite keys using astyanax client. For now I've created it with cqlsh -3, and this is how it looks like in 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 中的样子:

This is how I would expect it to be in cqlsh:

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

我使用复合键存储为 blob,这是一个问题.

I got it working with composite key stored as a blob which is a problem.

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>描述列族 my_cf;

cqlsh:KS>describe columnfamily my_cf;

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

cqlsh:KS>select * from my_cf;

cqlsh:KS>select * from my_cf;

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

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

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;

doesnt' it look right in cassandra-cli below? why it doesn't work in cqlsh?

cassandra-cli] list 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, cassandra 1.1.2)cqlsh>[cqlsh 2.2.0 |卡桑德拉 1.1.2 |CQL 规范 3.0.0 |节俭协议 19.32.0]


What am I doing wrong? (astyanax 1.0.6, cassandra 1.1.2) cqlsh>[cqlsh 2.2.0 | Cassandra 1.1.2 | CQL spec 3.0.0 | Thrift protocol 19.32.0]

推荐答案

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

From what I've been able to figure out, composite primary keys represent a major divergence in the protocol and interface to cassandra and the protocol you use controls the features you have access to.

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

For instance, astyanax and hector are primarily thrift protocol clients, while CQL, more than just a language, is (or will be?) a binary protocol.

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

The two protocols are not equivalent and CQL3 with composite primary keys makes things very different.

关于具有复合主键的表"的理解是它们本质上转换为具有复合列名称的宽行.这主键的第一部分是行键,其余部分是用作前缀以及 TABLE 列名作为列名宽排.

The thing to understand about "TABLES" with composite primary keys is that they essentially translate into wide rows with composite column names. The first part of the primary key is the row key and the remaining parts are used as a prefix along with the TABLE-column name as the column name in the wide row.

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

In your instance, the row key is "key" and the column prefix is "timeid", so the flag field of what you are inserting is actually a column named :flag and data is :data and so on.

为了使其工作,cassandra 的 CQL 协议接口是将表格"转换为宽行并透明地处理所有那个列命名.

In order for this to work, the CQL protocol interface to cassandra is converting "TABLES" into wide rows and transparently handling all of that column naming.

节俭界面不会处理这些东西,当你做一个改变,它只是像以前那样写列,没有虚拟寻址.

The thrift interface doesn't take care of this stuff and and when you do a mutation, it just writes columns like it is used to, without the virtual addressing.

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

So, in fact, the results do not look right in your cassandra-cli. If you do an insert from cqlsh -3, here is what it should look like from the cassandra-cli point of view (with a simple text date):

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

CQL3 和表格看起来很吸引人,但需要进行一些权衡,而且似乎还没有可靠的 Java 客户端支持.

CQL3 and tables look really attractive, but there are some trade-offs to be made and there doesn't seem to be solid java client support yet.

这篇关于无法使用 Astyanax 客户端创建带有复合键的表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆