2012-10-12 68 views
3

我不明白关于Cassandra的一件事。说,我有类似的Facebook网站,人们可以分享,评论,上传图片等。构建cassandra数据库

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

  • USERNAME1喜欢你对此有何评论
  • 用户名2更新了他的个人资料图片

等。

所以大量的阅读后,我想我需要做的是为每一个单一的东西创造新柱族,例如:user_likesuser_commentsuser_shares。基本上,任何你可以想到的,甚至在我这样做之后,我仍然需要为大多数列创建二级索引,以便我可以搜索数据?即使如此,我怎么知道哪些用户是我的朋友呢?我需要首先获取我的所有朋友ID,然后搜索所有这些列家庭为每个用户ID?

编辑 行,所以我做了一些更多的阅读,现在我明白的事情更好一点,但我仍然无法真正弄清楚如何构建我的表,所以我将一个赏金,我想得到我的表应该看起来怎么样,如果我想存储在这样的顺序检索数据的一个明显例子:

  • 所有
  • 喜欢
  • 评论
  • 收藏
  • 下载
  • 股份
  • 消息

所以我们可以说,我想找回我所有的朋友10页最后上传的文件或我关注的人,这是它会是什么样子:

John uploaded song AC/DC - Back in Black 10 mins ago

和评价,比如和股每一件事情是类似于......

现在可能最大的挑战将是检索所有类别的10个最后的东西在一起,所以列表将是所有东西的组合...

现在我不需要一个完整的详细表的答案,我只需要一些非常清晰的例子,我将如何构建和检索数据,如我将在mysqljoins

+1

是的,您需要定义二级索引才能搜索您的数据。没有,你只能通过密钥获取数据.. –

+1

不,你不傻,顺便说一句。借助Cassandra,您需要详细了解您想要存储的内容以及访问方式。只有这样,您才能真正进入您的专栏家族的最佳模式。 –

回答

4

使用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 
    } 
} 

注意上传6被复制到两个不同的列,谁做upload6既是用户A和用户B的朋友现在

到查询好友的朋友上传显示,在userid列上做一个限制为10的getSlice。这将返回前10个项目,按键排序。

要最先放置最新的项目,请使用reverse comparator,它可以在较小的时间戳之前排序较大的时间戳。

这个代码的缺点是,当用户A上传一首歌,你所要做的ň写入更新friendUploads列,其中N是人谁是用户A.

的朋友对于数与每个timestamp-upload-id关键字相关联的值,您可以存储足够的信息以显示结果(可能在json blob中),或者您可以不存储任何内容,并使用uploadid获取上载信息。

为了避免重复写入,您可以使用如下所示的结构,

userUploads { #columm family 
    userid { #column 
     timestamp-upload-id : null #key : no value 
    } 
} 

此存储为特定用户上传的视频。现在,当想要显示用户B的朋友上传时,您必须为用户B的每个朋友执行N个查询,并将结果合并到您的应用程序中。查询速度较慢,但​​编写速度较快。如果用户可以有成千上万的朋友,那么您可以使用第一个方案,并且执行更多的写入而不是更多的查询,因为您可以在用户上传后在后台执行写入操作,但查询必须当用户在等待时发生。

作为反规范化的一个例子,看看有多少个twitter rainbird在单个click occurs上写数据。每次写入都用于支持单个查询。

1

在某些方面,您可以将noSQL视为关系存储。在其他情况下,你可以通过非规范化来加快速度。例如,PlayOrm的@OneToMany存储在许多像这样

user1 -> friend.user23, friend.user25, friend.user56, friend.user87 

这是宽行的办法,所以当你发现你的用户,你把所有的外键给他的朋友。每行可以有不同的长度。您可能还存储以及反向参考,因此用户可能不得不标志着他为好友的人引用,但他并没有将它们标记回来(我们称之为哥们),所以你可能有

user1 -> friend.user23, friend.user25, buddy.user29, buddy.user37 

公告如果设计正确,您可能不需要“搜索”数据。也就是说,使用PlayOrm,您仍然可以执行可伸缩SQL并进行连接(您只需要弄清楚如何对表进行分区,以便可以扩展到数以万亿计的行)。

一行可以有数百万列或只有10行。我们实际上正在更新PlayOrm中的许多文档和本月的noSQL模式,所以如果你留意这一点,那么你也可以在那里了解更多关于通用noSQL的知识。

院长

1

地考虑每个数据库查询的请求到另一台机器上运行的服务。您的目标是最大限度地减少这些请求的数量(因为每个请求都需要网络往返)。

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

我建议你阅读这篇文章: http://maxgrinev.com/2010/07/12/do-you-really-need-sql-to-do-it-all-in-cassandra/

,并寻找到twissandra样本项目https://github.com/twissandra/twissandra 这是优化工艺的那种你描述项目的集合不错。