2016-09-19 59 views
2

输入:表格数据文件:每个文件具有可变列数,并且这些列名对文件和/或其他文件(事先未知)可能是唯一的。这些数据预计不会改变,所以插入会很频繁,但更新很少。列和它们的参数值可以是文本的或数字的。Cassandra中的地图冗余

请求的能力:能够通过身份或范围查询给定列名和值来检索数据的行。

数据模型:在CQL我可以模拟使用表示一个文件的一个特定的单元格值的单个表(在这种情况下的文本,但也可构造成用于数字数据的类似的表)

create table mytable(
    colname text, 
    value text, 
    filename text, 
    rowid int, 
    data map<text,text>, 
    primary key (colname , value, filename, rowid)#partitioning on colname may not be ideal here, but will be dealt with in ways unrelated to this question 
); 

例如,一个文件的内容可能是:

A B C D E 
i1 i2 i3 i4 i5 

插入是:

insert into mytable(colname, value, data, filename, rowid) values ('A', 'i1', {'A':'i1', 'B':'i2', 'C':'i3', 'D':'i4', 'E':'i5', 'F':'i5'}, 'F1', 1); 
insert into mytable(colname, value, data, filename, rowid) values ('B', 'i2', {'A':'i1', 'B':'i2', 'C':'i3', 'D':'i4', 'E':'i5', 'F':'i5'}, 'F1', 2); 
insert into mytable(colname, value, data, filename, rowid) values ('C', 'i3', {'A':'i1', 'B':'i2', 'C':'i3', 'D':'i4', 'E':'i5', 'F':'i5'}, 'F1', 3); 
insert into mytable(colname, value, data, filename, rowid) values ('D', 'i4', {'A':'i1', 'B':'i2', 'C':'i3', 'D':'i4', 'E':'i5', 'F':'i5'}, 'F1', 4); 
insert into mytable(colname, value, data, filename, rowid) values ('E', 'i5', {'A':'i1', 'B':'i2', 'C':'i3', 'D':'i4', 'E':'i5', 'F':'i5'}, 'F1', 5); 
... 

SELECT data from mytable where colname=? and value=? 

问题:我们确实有数据存储限制 - 在此模型中的数据值是一个行的每个列的值是相同的,从而导致大量过度的数据重复的(这是一个简单的例子,但列数能超过100个 - 意味着地图可以重复数百次)。

问题:(通过指针到例如数据或以某种方式定义地图作为不同)是否有卡桑德拉任何方式,以避免这种类型的数据复制的,而无需创建/查询第二表?或者,另一种方法可以使用相同的查询功能和结果对数据进行建模?

+0

你有没有考虑过使用Solr来解决这个问题呢? – Sreekar

+0

感谢您的建议@Sreekar会研究它......尤其是Solr与文本或数字数据的性能(我们的数据可能是,我们正在寻找后者有效的范围查询) – copeg

回答

1

如果您的设计受益于C *内置压缩,我不会感到惊讶,您的存储需求可能会低于您的预期。

顺便说一句,如果你想要一个完全不同的模型,你可以尝试:

  • 一个表输入数据
  • 每个表都有一个分区键时,你的价值的每一列寻找沿着这些路线

东西:

CREATE TABLE colname_A (
    value text, 
    data map<text,text>, 
    ..., 
    PRYMARY KEY (value) 
); 

CREATE TABLE colname_B (
    value text, 
    data map<text,text>, 
    ..., 
    PRYMARY KEY (value) 
); 
.... 
CREATE TABLE colname_xxx (...); 

然后,您可以发通过发行选出你的数据:

SELECT * FROM colname_A WHERE value = 'i5'; 
SELECT * FROM colname_A WHERE value IN ('i4', 'i5') 

小心与分区键的IN clausole查询,因​​为你想避免像this问题,当你把数据加载到您的集群。

该模型以不同方式组织数据,并受益于列间数据重复而不是行间数据重复。如果你有不平衡的列(例如一些列中的大量记录),这个数据组织提供的压缩可能是一个巨大的胜利。

+0

谢谢你的想法。我已经考虑过一个类似于你描述的模型,但是我不完全清楚这将如何解决我最初的问题:a)数据重复的膨胀和b)需要从单个查询中提取行数据(除非'数据'这里指的是行值)?对于它的价值,这些文件中的行数是列数的几倍。 – copeg

+1

事实上,你有更多的行比列看起来很正常。您应该根据数据的组织方式选择模型,或者坚持使用更好的压缩比的模型。 ** a)**在担心数据重复之前,您应该尝试加载一堆数据。 ** b)**我不明白你的意思,是你提取地图字段的要求,是吗? – xmas79

+0

用** a **钉住它。替代模型之间的磁盘使用情况表明,在有或没有数据重复的情况下,磁盘使用情况非常相似(当然,我很惊讶)。如果你在答案中包含了这一点(以及关于数据组织建模的前一句话),我会将其标记为已解决。 – copeg