Nosql 构建cassandra数据库

Nosql 构建cassandra数据库,nosql,cassandra,Nosql,Cassandra,我对卡桑德拉一点也不了解。比如说,我有一个类似于Facebook的网站,人们可以在那里分享、评论、上传图片等等 现在,让我们说,我想得到我的朋友们做的所有事情: Username1喜欢你的评论 用户名2更新了他的个人资料图片 等等 所以经过大量阅读,我想我需要做的是为每一件事创建新的列族,例如:user\u likesuser\u comments,user\u shares。基本上,你能想到的任何东西,即使在我这么做之后,我仍然需要为大多数列创建二级索引,这样我就可以搜索数据了?即便如此,

我对卡桑德拉一点也不了解。比如说,我有一个类似于Facebook的网站,人们可以在那里分享、评论、上传图片等等

现在,让我们说,我想得到我的朋友们做的所有事情:

  • Username1喜欢你的评论
  • 用户名2更新了他的个人资料图片
等等

所以经过大量阅读,我想我需要做的是为每一件事创建新的列族,例如:
user\u likes
user\u comments
user\u shares
。基本上,你能想到的任何东西,即使在我这么做之后,我仍然需要为大多数列创建二级索引,这样我就可以搜索数据了?即便如此,我如何知道哪些用户是我的朋友?我是否需要先获取所有好友id,然后在所有这些列族中搜索每个用户id

编辑 好的,我读了更多的书,现在我对事情有了更好的理解,但我仍然不知道如何构造我的表,所以我将设置一个悬赏,我想得到一个清晰的示例,说明如果我想按这种顺序存储和检索数据,我的表应该是什么样子:

  • 全部
  • 喜欢
  • 评论
  • 宠儿
  • 下载
  • 分享
  • 信息
假设我想检索我所有朋友或我跟踪的人最后上传的十个文件,它是这样的:

John 10分钟前上传了歌曲AC/DC-Back(黑色)

每一件事,比如评论和分享,都会与之相似

现在最大的挑战可能是检索所有类别中最后10件物品,因此列表将是所有物品的混合体

现在我不需要一个完整详细的表的答案,我只需要一些非常清晰的示例,说明如何像在
mysql
中那样使用
joins

构造和检索数据在某些方面,您“可以”将noSQL视为关系存储。在其他情况下,可以进行非规范化以加快速度。例如,PlayOrm的@OneToMany存储了许多这样的数据

user1 -> friend.user23, friend.user25, friend.user56, friend.user87
这是一种宽行方法,因此当您找到您的用户时,您就拥有他朋友的所有外键。每行可以有不同的长度。您还可能存储了一个反向引用,这样用户可能会引用那些将他标记为朋友的人,但他没有将他们标记回来(我们称之为buddy),因此您可能会

user1 -> friend.user23, friend.user25, buddy.user29, buddy.user37
请注意,如果设计正确,您可能不需要“搜索”数据。这就是说,使用PlayOrm,您仍然可以执行可伸缩SQL和连接(您只需要知道如何对表进行分区,以便它可以扩展到数万亿行)

一行可以有数百万列,也可以只有10列。本月我们实际上正在更新PlayOrm和noSQL模式中的许多文档,因此如果您关注这一点,您还可以在那里了解更多关于普通noSQL的信息


Dean

将每个DB查询看作是对另一台机器上运行的服务的请求。您的目标是最小化这些请求的数量(因为每个请求都需要网络往返)

这是与RDBMS范例的主要区别:在SQL中,您通常会使用连接和辅助索引。在cassandra中,连接是不可能的,因为相关数据将驻留在不同的服务器上。像物化视图这样的东西在cassandra中用于相同的目的(通过单个查询获取所有相关数据)

我建议您阅读这篇文章:

并研究twissandra示例项目
这是针对您描述的项目类型的优化技术的很好的集合。

使用sql,您可以构造表以规范化数据,并使用索引和联接进行查询。使用cassandra,您无法做到这一点,因此您需要构造表以服务于您的查询,这需要非规范化

如果您想查询朋友上传的项目,一种方法是每个用户没有一个表,并且每当该用户的朋友上传内容时,都会写入该表

friendUploads { #columm family
    userid { #column 
        timestamp-upload-id : null #key : no value
    }
 }
例如,

friendUploads {
    userA {
         12313-upload5 : null
         12512-upload6 : null
         13512-upload8 : null
    }
}

friendUploads {
    userB {
         11313-upload3 : null
         12512-upload6 : null
    }
}
注意,upload 6复制到两个不同的列,因为上传6的人是用户a和用户B的朋友

现在要查询好友的好友上传显示,请在userid列上执行限制为10的getSlice。这将返回按键排序的前10项

要将最新的项目放在第一位,请使用将较大的时间戳排序在较小的时间戳之前的方法

此代码的缺点是,当用户A上载歌曲时,您必须执行N次写入以更新friendUploads列,其中N是用户A的朋友人数

对于与每个timestamp upload id键相关联的值,可以存储足够的信息来显示结果(可能是json blob),也可以不存储任何内容,然后使用uploadid获取上传信息

为了避免重复写入,可以使用以下结构:

userUploads { #columm family
    userid { #column 
        timestamp-upload-id : null #key : no value
    }
 }
这将存储特定用户的上载。现在,当您想要显示用户B的朋友的上传时,您必须执行N个查询,用户B的每个朋友一个查询,然后将结果合并到应用程序中。查询速度较慢,但编写速度较快

最有可能的情况是,如果用户可以有数千个朋友,那么您将使用第一种方案,并执行更多的写入而不是更多的查询,就像您可以在用户上传后在后台执行写入一样,但查询必须在用户等待时进行


作为一个非规范化的例子,看看twitter rainbird在一个事件发生时写了多少次。每次写入都用于支持单个查询。

是的,您需要定义辅助索引才能搜索数据。没有卡桑德拉,你只能通过键来获取数据。不,你并不愚蠢,顺便说一句。有了卡桑德拉,你确实需要进入下一个细节层次,了解你的想法