【问题标题】:Need to querying into a column (or collection) in Cassandra需要查询到 Cassandra 中的列(或集合)
【发布时间】:2016-06-28 04:07:16
【问题描述】:

每个人:D

我正在使用 Cassandra(Datastax 版本),但遇到了问题。

我想为一个(总是)会改变的列建模。

这很难,因为我不能只创建一个包含 1、2、3、4..10 列的列族。因为,明天可能会改变。

我认为是在集合中,但我必须查询这些。我的意思是,我需要每秒查询这些信息。

例如:有地图:

<'col1':'val1','col2':'val2'> 

我需要这样查询:

SELECT * FROM example WHERE 'col1' = 'val1' AND 'col2' = 'val2';

我不知道该怎么做,这对于我想做的事情是非常必要的。

甚至,我读到您可以创建一个列(文本)并实现一种格式:

colum1 = 'val1\x01val2\x01'

但这并不能解决我想要做的事情,因为我无法查询此字段(或不知道如何)

拜托,你能帮我做这样的模型吗?

我不能使用集合,因为(根据我读到的)速度很慢。

PD:对不起,如果我的英语不好:(但谢谢

【问题讨论】:

    标签: cassandra datastax cql modeling nosql


    【解决方案1】:

    你可以像这样创建一个表

    CREATE TABLE dynamic_columns
       partitionKey bigint,
       column_name text,
       column_value_text text,
       column_value_boolean boolean,
       column_value_bigint bigint,
       column_value_uuid uuid,
       column_value_timestamp timestamp,
       ....
       PRIMARY KEY((partitionKey), column_name)
    );
    

    partitionKey 用于指示您的数据将存储在集群中的哪台机器上

    聚类列column_name 将存储您的动态列的标签。然后我们有一个 normal 列的列表,每个数据类型(bigint、uuid、timestamp ....)都有一个列。

    让我们举个例子:

    INSERT INTO dynamic_columns(partitionKey, column_name, column_value_text)
    VALUES(1, 'firstname', 'John DOE');
    
    INSERT INTO dynamic_columns(partitionKey, column_name, column_value_boolean)
    VALUES(1, 'validity_state', true);
    
    INSERT INTO dynamic_columns(partitionKey, column_name, column_value_timestamp)
    VALUES(1, 'validity_date', '2016-03-13 12:00:00+0000');
    

    所以我们的想法是我们定义一个 column_value 列表,为 Cassandra 中的每个现有类型创建一个列表,但我们只将数据插入到适当的类型列中,就像上面的示例一样。

    对于查询,您需要在每个类型列上创建一个索引。示例:

    CREATE INDEX ON dynamic_columns(column_value_boolean);
    CREATE INDEX ON dynamic_columns(column_value_text);
    CREATE INDEX ON dynamic_columns(column_value_boolean);
    ....
    

    如果可以切换到Cassandra 3.4,还有一个更好的二级索引实现,叫做SASI,这里创建索引的语法:

    // All data types EXCEPT text
    CREATE CUSTOM INDEX ON types(column_value_boolean) 
    USING 'org.apache.cassandra.index.sasi.SASIIndex' 
    WITH OPTIONS = {'mode': 'SPARSE'};
    
    // Text data type
    CREATE CUSTOM INDEX ON types(column_value_text) 
    USING 'org.apache.cassandra.index.sasi.SASIIndex' 
    WITH OPTIONS = {
        'mode': 'PREFIX', 
        'analyzer_class' : 'org.apache.cassandra.index.sasi.analyzer.NonTokenizingAnalyzer',
        'case_sensitive': 'false'
    };
    

    然后您可以轻松查询您的列:

    //Give me col1 where value = 'val1'
    SELECT * FROM dynamic_columns 
    WHERE partitionKey=1 
    AND column_name='col1'
    AND column_value_text='val1';
    
    //Give me 'validity_state' = true
    SELECT * FROM dynamic_columns 
    WHERE partitionKey=1 
    AND column_name='validity_state'
    AND column_value_boolean=true;
    

    备注:您应该始终在 SELECT 中提供 partitionKey 值,否则 Cassandra 将在最坏的情况下执行完整的集群扫描并破坏您的性能。从 Cassandra 3.4 开始使用 SASI 索引,这个问题不太严重,但仍然强烈建议在使用二级索引时提供 partitionKey

    有关分区键重要性的更多信息,请阅读以下内容: http://www.planetcassandra.org/blog/the-most-important-thing-to-know-in-cassandra-data-modeling-the-primary-key/

    【讨论】:

      猜你喜欢
      • 2021-12-10
      • 2015-03-02
      • 2012-05-01
      • 2012-10-29
      • 2011-11-13
      • 2021-03-04
      • 2021-08-14
      • 1970-01-01
      • 2010-09-09
      相关资源
      最近更新 更多