Cassandra,存储关于项目的各种事件

时间:2012-11-24 23:14:18

标签: cassandra data-modeling

我需要存储这些类型的事件,让我们说上传的歌曲:

  • 浏览
  • 喜欢
  • 不喜欢
  • 评论
  • 收藏夹
  • 下载

可能会有更多。

要存储有关歌曲本身的信息,我使用的是宽行,其中列名称为时间戳,值为JSON字符串,其中包含有关该歌曲的所有信息。

现在如果我只需要存储号码就没有太多问题,但我实际上需要存储有关喜欢该歌曲的用户的信息。

因此,如果有1000个用户喜欢某首歌,那么将所有这些信息放在一列中可能是一个坏主意。

所以我可能做到的唯一方法就是将这些信息存储在不同的CF中。

但是我不确定如何将歌曲本身与分散在不同列中的所有信息“连接”?

所以我的问题是,我是否朝着正确的方向前进,如果是这样,我将如何存储所有这些行动并将它们连接在一起。

修改

我正在尝试建立喜欢系统,并且它几乎失控,这些是我需要执行的动作以便喜欢/不喜欢

  1. 检查用户是否已经喜欢该项目
  2. 之前检查用户是否不喜欢该项目
  3. 如果他不喜欢,请删除该条目
  4. 现在得到当前的喜欢
  5. 现在更新项目本身,设置新的喜欢计数
  6. 更新CF,其中包含所有喜欢该项目的用户
  7. 实际上我需要运行更多的查询,所以总共得到近6个查询甚至更多是正常的吗?

3 个答案:

答案 0 :(得分:1)

为" User,Song,Song_Likes,User_Likes,Song_ Dislike,User_Dislike"创建不同的列系列。使用songId(UUID)和UserId(UUID)在列族之间建立类似。

CF
 User: KS {userId} -> {{user}, {JSON user Info}}
 Song: KS {songId} -> {{song}, {JSON song Info}}

 Song_Comments: {songId -> {(Reversed)timestamp, userUUID:UserName:comment}}
  Reveresed Time stamp can help you to get latest N comments quickly.

 Song_Likes: {songId -> {timeStamp, userUUID}}
   (or if time of event is not important.)
 Song_Likes: {songId -> {userUUID, column Data {....} }

 similarly for other Column Families.

以下内容可能对您有所帮助。 http://www.rackspace.com/blog/cassandra-by-example/

答案 1 :(得分:1)

在casandra中,您无法执行连接,因此您必须对数据进行非规范化。因此,我们的想法是将实体和关系保持在单独的列族中。另外请记住,cassandra确实有超级列,当你想要深入一级时非常有帮助,所以你们都在一起。另外不要错过cassandra限制 - 取决于您使用的版本。

答案 2 :(得分:1)

在规划Cassandra架构时,了解您需要查询的内容是(如果不是最重要的)重要考虑因素之一。 Cassandra旨在处理大量写入。

根据您要实现的其他功能,您可能需要创建其他列系列或完全替换这些系列以便以最优化的cassandra查询方式存储数据。

此外,我建议尽可能多地将原始数据存储在cassandra中。我不会将JSON对象加载到胖字符串列中。至少,直接在cassandra中存储相关数据,例如喜欢的值等等。

您有两个域模型:用户和歌曲,以及您要存储的三类数据:

  1. 评论
  2. 顶/踩/收藏夹
  3. 查看/下载
  4. 您详细介绍了更新算法所需的一些功能查询:

    1. 检查用户是否已经喜欢该项目
    2. 之前检查用户是否不喜欢该项目
    3. 如果他不喜欢,请删除该条目
    4. 现在得到当前的喜欢
    5. 现在更新项目本身,设置新的喜欢计数
      • 使用cassandra计数器,这两个步骤可以立即发生
    6. 更新包含所有喜欢该项目的用户的CF
    7. 以下是满足这些查询要求的模式。

      首先,我们将为用户和歌曲定义CF,两者都使用UUID作为键。

      create column family users with comparator=UTF8Type
         and column_metadata=[{column_name: user_name, validation_class: UTF8Type, index_type: KEYS},
         {column_name: json_data, validation_class: UTF8Type}];
      
      create column family songs with comparator=UTF8Type
         and column_metadata=[{column_name: user_name, validation_class: UTF8Type, index_type: KEYS},
            {column_name: json_data, validation_class: UTF8Type}];
      

      辅助索引有助于按用户名检索用户行。有关性能考虑,请参阅this


      评论可以使用UUID为每个评论建模,如下所示:

      create column family comments with comparator = 'UTF8Type' 
         and column_metadata=[{column_name: user, validation_class: UUIDType, index_type: KEYS},
            {column_name: song, validation_class: UUIDType, index_type: KEYS},
            {column_name: timestamp, validation_class: DateType},
            {column_name: comment, validation_class: UTF8Type}];
      

      由于用户的喜欢是互斥的,我们可以使用一个列族来存储所有用户的喜欢/不喜欢的歌曲。如果你限制喜欢暗示喜欢,我们可以用这一个来做所有这三个。使用用户的UUID作为行键,并使用歌曲的UUID作为列键,列值0 =>没有价值,1 =>不喜欢,2 =>喜欢,3 =>喜爱。

      create column family user_likes with comparator = 'UUIDType'
         and default_validation_class = IntegerType;
      

      现在剩下的就是跟踪每首歌的喜欢,不喜欢,收藏,观看和下载。我们可以使用Cassandra's counter column类型在一个CF中完成此操作。使用歌曲的UUID作为CF键。

      create column family song_data with default_validation_class=CounterColumnType
         and column_metadata=[{column_name: likes},
            {column_name: dislikes},
            {column_name: favorites},
            {column_name: views},
            {column_name: downloads}];