【问题标题】:Storing a list of values in Cassandra在 Cassandra 中存储值列表
【发布时间】:2012-04-10 02:16:09
【问题描述】:

版本相关

此问题的一些答案涉及旧版本的 Cassandra。此类问题的正确答案取决于您使用的 Cassandra 版本。


我有一个个人资料列族,想在每个个人资料中存储一个技能列表。我不确定这通常是如何在 Cassandra 中完成的。一种选择是存储序列化的Thrift 或 protobuf,但我不希望这样做,因为我相信 Cassandra 不了解这些格式,因此数据存储区中的数据不是人类可读或可查询的从命令行通过 CQL。我想到的另一个解决方案是使用超级列并将技能作为具有空值的键:

skills: {
  'java': '',
  'c++': '',
  'cobol': ''
}

这是在 Cassandra 中处理列表的好方法吗?我想有一些我不知道的成语。我正在使用Astyanax 客户端库,它只支持复合列而不是超级列 列,所以我上面提出的解决方案在这种情况下似乎很尴尬。尽管我仍然在理解复合列时遇到了一些麻烦,因为它们似乎还没有完全记录在案。此解决方案是否适用于复合列?

【问题讨论】:

    标签: cassandra


    【解决方案1】:

    这个答案可以追溯到 Cassandra 版本 1.2 发布之前,该版本为处理列表提供了截然不同的功能。如果您使用的是 Cassandra 1.2+,则答案可能不合适。


    我会在列键中对列表进行编码,使用以真实列名作为第一维的复合列,即:

    row_key -> {
         [column_name; entry1] -> "",
         [column_name; entry2] -> "",
         ... 
    }
    

    然后,要读取列表,您需要从 [column_name; ] 到 [column_name; ] - 注意空白尺寸。

    这样做的好处是它实际上很好地实现了一个集合;该列表不能包含两次相同的内容。我认为 Thins 适用于您的用例。该列表也将按排序顺序进行维护。

    【讨论】:

    • 谢谢。澄清一下,column_name 将是“skills”,entry1、entry2 等将是“java”、“c++”等。然后 row_key 将是用户 ID,而其他用户属性将在省略号所在的位置?或者您是否可以拥有一个复合超级列,其中“技能”是用户列族中的列名,值是您显示的复合列?
    • 没错。为了简单起见,我会避免混合使用复合列和超级列。
    • 经过大量阅读后,似乎我不能在同一个列族中拥有常规列和超级列,所以我不确定您的解决方案将如何工作。我将在哪里存储用户的其他属性,如“名字”、“姓氏”等?
    • 此方案不涉及超级列,只涉及复合列。
    • 这种方法不允许在该字段上使用二级索引。为了通过该字段进行搜索,必须存储另一个索引列族(或类似的东西)。
    【解决方案2】:

    这个答案可以追溯到 Cassandra 版本 1.2 发布之前,该版本为处理列表提供了截然不同的功能。如果您使用的是 Cassandra 1.2+,则答案可能不合适。


    正如邮件列表中提到的,我的偏好对我来说非常有效,它是存储单列“技能”,其值是一个序列化的 JSON 字符串。

    真正归结为“技能”的使用模式。

    • 如果“技能”仅适用于每个用户的 CRUD,这很好。
    • 如果您希望能够搜索所有具有“cobol”技能的用户,那么我仍然会推荐这种方法,并有另一个 row 即 Skill:cobol 有一个列UUID 和时间戳值或类似的值...
    • 我敢肯定,通过将 Pig/Hadoop 集成到您的 cassandra 节点,您仍然可以很高兴地查询所有具有 x、y 和 z 的用户以生成新数据以支持其他用例。

    【讨论】:

    • 谢谢。我倾向于 JSON 解决方案。我刚刚意识到有了 Pig 我可以做更高级的事情,所以我也要去看看 Elephant Bird (github.com/kevinweil/elephant-bird)
    • 在我看来,这种方法适合以后对列表的更改不是问题的地方。这种方法需要读取列,以便使用更新的数据重新创建 JSON 字符串并再次保存。
    【解决方案3】:

    在旧版本的 Cassandra 中,您必须自己序列化列表并将其存储在列中,或者可能使用超级列。

    Since version 1.2 of Cassandra,CQL3 具有列的集合类型,因此您可以将 list<text> 作为架构中的列类型。例如:

     CREATE TABLE Person (
        name text,
        skills list<text>,
        PRIMARY KEY (name)
     );
    

    如果您想自动消除重复项,也可以使用set&lt;text&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-29
      • 1970-01-01
      • 2019-06-04
      • 2018-08-03
      • 1970-01-01
      相关资源
      最近更新 更多