我一直认为,如果您的应用程序经常更改并且经常添加功能,那么Cassandra就会很好。
这是有道理的,因为您没有任何固定架构,您可以向行添加列以满足您的需求,而不是运行ALTER TABLE查询,这可能会冻结您的数据库数小时非常大的表。
但是我有一个我无法解决的低音问题。 假设我有:
CREATE COLUMN FAMILY Students
with comparator='CompositeType(UTF8Type,UTF8Type),
and key_validation_class=UUIDType;
每个学生都有一些通用专栏(你知道,meta:username,meta:password,meta:surname等),而且每个学生都可以参加N门课程。使用非规范化解决此N-N关系,为每个学生添加N列(课程:ID1,课程:ID2)。
另一方面,我可能有一个课程CF,其中每一行都包含以下所有学生UUID。
所以我可以问“XXX跟随哪些课程”和“哪些学生按照YYY课程”。
问题是:如果我没有创建第二列系列怎么办?也许在应用程序构建时,让学生遵循特定课程并不是必需的。
这是一个简单的例子,但我相信这很常见。 “通过Cassandra,您可以根据查询而不是关系来计划CF”。我现在需要那个查询,而一开始并不需要。
如果有一个包含数千个条目的学生表,您将如何填写课程CF?这是Hadoop,Pig还是Hive的工作(我从来没有触及任何这些,只是猜测)。
答案 0 :(得分:3)
Pig(使用Hadoop集成)实际上非常适合这种类型的工作,因为您不仅可以使用CassandraStorage读取数据,还可以将数据写回Cassandra。它为您提供并行处理能力,以最少的时间和开销完成工作。否则,替代方法是自己写一些东西进行提取,然后编写新的CF.
这是一个Pig示例,它计算一个CF中一组数据的平均值并将它们输出到另一个CF:
rows = LOAD 'cassandra://HadoopTest/TestInput' USING CassandraStorage() AS (key:bytearray,cols:bag{col:tuple(name:chararray,value)});
columns = FOREACH rows GENERATE flatten(cols) AS (name,value);
grouped = GROUP columns BY name;
vals = FOREACH grouped GENERATE group, columns.value AS values;
avgs = FOREACH vals GENERATE group, 'Pig_Average' AS name, (long)SUM(values.value)/COUNT(values.value) AS average;
cass_group = GROUP avgs BY group;
cass_out = FOREACH cass_group GENERATE group, avgs.(name, average);
STORE cass_out INTO 'cassandra://HadoopTest/TestOutput' USING CassandraStorage();
答案 1 :(得分:0)
如果您使用现有的cassandra文件,则必须展开数据。由于NOSQL文件是单向的,因此在Cassandra本身中这可能是非常耗时的操作。必须以与第一个文件相反的顺序对数据进行排序。坦率地说,我相信你必须回到用于填充第一个文件并从中填充这个新文件的原始数据。