就没有希望了吗?
在MongoDB中你可以采用另一种方法来解决这个问题,如果你有相关背景经验的话会对此更熟悉。与复制用户数据不同的是,你可以在活动流文档中保存用户的引用。
用这个方法,代替那种在需要的地方将用户数据内联进来的方法,你只需给每个user一个ID。一旦用户具有了ID,我们就只需在之前内联数据的地方保存这个用户的ID。下面的这些新的ID是用绿色标识的。
MongoDB实际用的是BSON IDs(译注:BSON是由10gen开发的一个数据格式,目前主要用于MongoDB中,是MongoDB的数据存储格式),它就像是GUID的字符串形式, 但为了让这些例子便于阅读,这里我只是用了整数。 这消除了我们之前的重复的问题。当用户数据改变时,只有一个文档需要重写。不过我们为我们自己带来了一个新的问题。因为我们将一些数据移到了活动流之外,我们再也不能从一个单独的文档构造一个活动流了。这使得效率降低,复杂性增加。现在构造一个活动流需要 1)检索数据流文档,然后 2)检索所有用户文档以便填写名字和头像。
MongoDB缺少的是SQL风格的join操作,这种操作可以通过写一条查询语句,得到活动流与活动流所引用的所有用户的混合结果。因为MongoDB不具备这种能力,取而代之的是,你必须在你的应用代码中手工做这项混合工作。 简单的非规范化数据
我们回头看一看电视节目(TV shows),电视节目的关系集合没有太多的复杂性。因为关系图中所有的盒子是不同的实体,整个查询可以整合进一个文档,没有重复没有引用。在这个文档数据库中,文档之间没有链接。它不需要join。
然而在一个社交网络中,没有什么能像这样独立存在。在任何时候,只要你看到什么东西看起来像是一个名字或者一幅图像,你就会希望能点击它,看看那个用户,他们的个人资料,以及他们的帖子。TV show应用不是这样运作的。如果你位于巴比伦5(Babylon 5)的第一季第一集,你不会希望点击综合医院(General Hospital)的第一季第一集。 不要链接文档
我们开始在Diaspora代码中手工做这项烦人的MongoDB joins操作时,我们很清楚这只是麻烦的第一个迹象。这个迹象表明我们的数据实际是相互关联的,这个数据结构具有价值,而且我们正在违背文档数据库的基本概念。
不管你是否在复制关键数据(天啊),或者使用引用并在应用代码中执行join操作(天啊天啊),只要文档之间有链接,你就已经超越了MongoDB。当MongoDB爱好者用不同的方式说“文档”的时候,他们的意思是那些你可以在一张纸上打印出来、拿在手里的东西。一个文档可能具有内部结构——标题(headings)、子标题(subheadings)、段落(paragraphs)和页脚(footers)——但这并没有链接到其它文档。它是独立的半结构化数据。 如果你的数据看起来是那样的,你只需文档。祝贺你!对Mongo而言它是一个好的用例。但是如果文档之间链接具有存在价值,那么实际上你拥有的就不是文档。对你来说MongoDB就不是正确的解决方案。当然它也不是社交型数据的解决方案,在那种数据中文档之间的链接实际上是系统中最关键的数据了。
因此社交型数据不是面向文档的。那是否这就意味着它实际上是……关系型的呢? |