0

我需要为上传的歌曲存储这些类型的事件:

  • 意见
  • 喜欢
  • 不喜欢
  • 评论
  • 收藏夹
  • 下载

而且可能还有更多。

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

现在如果我只需要存储数字就不会有太大的问题,但我实际上需要存储有关说喜欢那首歌的用户的信息。

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

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

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

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

编辑

我正在尝试建立喜欢系统,它几乎失控了,这些是我需要执行的操作才能喜欢/不喜欢

  1. 检查用户是否已经喜欢该项目
  2. 检查用户之前是否不喜欢该项目
  3. 如果他确实不喜欢,则删除该条目
  4. 现在获取当前喜欢
  5. 现在更新项目本身,设置新的喜欢计数
  6. 更新CF包含所有喜欢该项目的用户

实际上我需要运行更多查询,所以我总共得到了将近 6 个查询,甚至更多是正常的吗?

4

3 回答 3

1

为“User、Song、Song_Likes、User_Likes、Song_Dislike、User_Dislike”创建不同的列族,使用songId(UUID)和UserId(UUID)在列族之间建立like。

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/

于 2012-11-25T14:34:49.553 回答
1

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

于 2012-11-29T15:28:54.340 回答
1

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

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

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

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

  1. 评论
  2. 喜欢/不喜欢/收藏
  3. 查看/下载

您详细说明了更新算法所需的一些功能查询:

  1. 检查用户是否已经喜欢该项目
  2. 检查用户之前是否不喜欢该项目
  3. 如果他确实不喜欢,则删除该条目
  4. 现在获取当前喜欢
  5. 现在更新项目本身,设置新的喜欢计数
    • 使用 cassandra 计数器,这两个步骤可以同时发生
  6. 更新包含所有喜欢该项目的用户的 CF

可以满足这些查询要求的模式如下。

首先,我们将为User 和 Song定义 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}];

二级索引有助于按用户名检索用户行。有关性能注意事项,请参阅此内容。


可以使用每个评论的 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 的计数器列类型在一个 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}];
于 2012-12-02T04:24:10.683 回答