2010-06-19 61 views
1

我目前正在设计一个数据库结构(这很奇怪,在这里避免术语方案)并遇到一些问题。我将通过一个类似的例子激发我的问题。分区CouchDB中的1:1关系

想象一下博客条目的数据库。每个博客条目有0..n条评论,0..m条标签和0..r条用户投票(上/下)。

当然,我可以把所有东西放在一个大的JSON对象中,每个条目都有一个共同的对象,包括注释,标签和投票等字段。

然而,当存在许多并发更改时(至少在我的真实应用程序中),这很容易发生冲突。所以我想把我的结构分成几个文件。每个条目一个,每个条目一个(集合)文档用于评论,一个用于标签,另一个用于投票。

我还设置了一个修复名称模式。博客条目在创建时具有UUID,评论,标签和投票的文档名为<blog-entry-uuid>:(tags|votes|comments)。 因此,我总是可以通过了解博客文章的ID来构建引用文档的ID。在使用视图时,我可以使用视图归类功能“加入”或利用include_docs=true

通过使用更新处理程序,我可以进一步最小化添加注释等的冲突更改。处理程序只是将新评论,并将其放入<blog-entry-uuid>:comments文档中。

这是一种可行的方法,还是有更好的方法来加入?以这种方式构建ID是否是不好的做法?提前

回答

1

据我了解

感谢,沙发是不是真的打算处理1:在一个单一的“东西”是独立方面的文件之间的关系1包含在不同的文档。您可以在没有特定收集文件的情况下处理所有这些。

大概每个评论都可以有自己的文档。 Christopher Lenz有a blog article描述了在这种情况下如何做类似连接的视图。

另一方面,标记和向上/向下的投票可能应该保持在其所有者内部。是的,你仍然有编辑冲突的问题,但无论如何这些冲突都可以很容易地解决。我认为这不值得将数据库结构复杂化。 (虽然如果审计上/下选票很重要,您可以为每个投票单独提供一个文档,并使用减少查询来查找文档的最终分数。)

+0

正如我的问题概括_id,引用ID和视图归类的自动包含是处理CouchDB中关系的强大工具。 – 2010-06-21 18:54:41

1

LeafStorm提供了一个很好的观点。我不会说CouchDB 绝对是不支持1:1;你只需要了解其含义。主要是,你不能同时更新两个文件。坦率地说,许多类型的应用程序都被过度使用。

查看整理是将相关文档“连接”在一起的绝佳方法。它非常强大。

其他需要考虑的是CouchDB 0.11及其后续版本的功能,可以在视图中通过id引用相关文档。在Jan的CouchDB 0.11 views博客文章中阅读它。基本上,当您发出一个键/值时,您可以“诱骗”include_docs=true功能,以返回任何文档,而不仅仅是您在调用emit()时正在处理的文档。比较:

function(doc) { 
    // The old way. include_docs would include this document (doc). 
    emit(some_key, some_value); 

    // The new way. include_docs will fetch some_other_doc_id and return that. 
    emit(some_other_key, {"_id": some_other_doc_id}); 
} 
1

,我看到的文档处理的关系,更重要的是更新的时候,他们可以由多个用户同时被写入到这些文件最常见的方式,是将文件与行动联系起来。例如,不要将博客文章的评级看作一个组件,将每个评级看作是一个不同的操作并为其创建一个文档。然后你使用Map/Reduce的功能来聚合所有这些动作。

评级行动文件:

{ 
    "docType": "rating", 
    "of": { 
    "id": "ID of the blog/video/comment document", 
    "type": "blog/video/comment" 
    }, 
    "by": "the user's document ID", 
    "rating": 3 
} 

地图功能:

function(doc) 
{ 
    if(doc.docType == "rating") 
    emit([doc.of.id, doc.of.type], doc.rating); 
} 

Reduce函数:

function(keys, values, rereduce) 
{ 
    return sum(values); 
} 

现在,您可以轻松地获得具体项目的评价,项目类型(例如,排名前10的评论)或应用程序中的每种媒体类型。这就是CouchDB 0.11.x和即将发布的1.0中没有一些较酷的功能。

当然,您可能正在寻找一个不同的答案 - 让我知道如果是这样的话。

最后,我认为,CouchDB的可处理1:1的关系就好了(至少我的定义):没有什么阻止你,包括文档A的文件B.