如何在 Cassandra(Datastax 版本)中对列进行建模?

问题描述 投票:0回答:1

我正在使用 Cassandra(Datastax 版本),但遇到了问题。我想对一个(总是)会改变的列进行建模。我不能只创建一个包含 1,2,3,4..10 列的列族,因为明天可能会发生变化。

我认为在收藏中,但我必须查询这些。我每秒都需要查询这些信息。

例如:带有地图:

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

我需要这样查询:

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

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

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

colum1 = 'val1\x01val2\x01'

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

我怎样才能模拟这样的东西?

我无法使用集合,因为(根据我读到的)它很慢。

cassandra datastax cql modeling nosql
1个回答
0
投票

您可以创建这样的表格

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/

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.