如何有效地将CouchDB与标准化数据一起使用?

时间:2014-08-19 20:31:44

标签: join couchdb

我花了很长时间(日历)时间来了解CouchDB和map / reduce以及如何将它用于各种用例。我自己理解的一个挑战是如何有效地将其用于规范化数据。互联网上的消息来源只是停止“不要将它用于标准化数据”。我不喜欢缺乏关于如何有效地使用标准化数据的分析!

我发现的一些更好的资源如下:

CouchDB: Single document vs "joining" documents together http://www.cmlenz.net/archives/2007/10/couchdb-joins

在这两种情况下,当需要在文档中存在非规范化的共性时,如果需要加入文档,作者在解释如何进行“加入”方面做得很好。但是,如果我需要加入两个以上的规范化“表”,则利用视图排序技巧来查询一行数据并不起作用。也就是说,您似乎需要某些关于联接中所有元素的数据存在于参与连接的所有文档中,因此,您的数据不会被标准化!

考虑以下简单的Q& A示例(问题/答案/答案评论):

{ id: "Q1", type: "question", question: "How do I...?" }
{ id: "A1", type: "answer", answer: "Simple... You just..." }
{ id: "C1", type: "answer-comment", comment: "Great... But what about...?" }
{ id: "C2", type: "answer-comment", comment: "Great... But what about...?" }
{ id: "QA1", type: "question-answer-relationship", q_id:"Q1", a_id:"A1" }
{ id: "AC1", type: "answer-comment-relationship", a_id:"A1", c_id:"C1" }
{ id: "AC2", type: "answer-comment-relationship", a_id:"A1", c_id:"C2" }
{ id: "Q2", type: "question", question: "What is the fastest...?" }
{ id: "A2", type: "answer", answer: "Do it this way..." }
{ id: "C3", type: "answer-comment", comment: "Works great! Thanks!" }
{ id: "QA2", type: "question-answer-relationship", q_id:"Q2", a_id:"A2" }
{ id: "AC3", type: "answer-comment-relationship", a_id:"A2", c_id:"C3" }

我想得到一个问题,答案和答案的所有评论,而且只有一个查询的数据库中没有其他记录。

使用上面的数据,在高级别,您需要为每种记录类型提供观看次数,要求特定的question考虑id,然后在另一个视图中,使用question id查找question-answer-relationship type指定的关系,然后在另一个视图中查找answer获取的idquestion-answer-relationship type之后,依此类推,在一系列请求中汇总“行”。

另一种选择可能是创建某种类型的应用程序,该应用程序在上面进行处理,以所需格式缓存非规范化文档,自动对正在更新的规范化数据做出反应。这感觉很尴尬,就像重新实现已存在/应该存在的东西一样。

在完成所有这些背景之后,最终的问题是:是否有更好的方法来执行此操作,以便数据库而不是应用程序完成工作?

提前感谢任何分享经验的人!

1 个答案:

答案 0 :(得分:2)

如果我使用的是传统的关系数据库,那么您拥有的文档模型就是我要做的事情,因为您可以使用这些ID更自然地执行连接。

但是对于文档数据库,这会引入复杂性,因为与MapReduce“加入”文档并不是一回事。

在您提供的Q& A场景中,我将其模型如下:

{
    id: "Q1",
    type: "question",
    question: "How do I...?"
    answers: [
        {
            answer: "Simple... You just...",
            comments: [
                { comment: "Great... But what about...?" },
                { comment: "Great... But what about...?" }
            ]
        },
        {
            answer: "Do it this way...",
            comments: [
                { comment "Works great! Thanks!" },
                { comment "Nope, it doen't work" }
            ]
        }
    ]
}

这可以解决数据库中read的许多问题,但它会使您的write更复杂,例如在为答案添加新评论时,您需要< / p>

  1. 从CouchDB获取文档。
  2. 循环回答并找到正确的位置,并将注释推送到数组中。
  3. 将文档保存回CouchDB。
  4. 我只考虑将answer作为单独的文件吐出,如果有很多(例如1个问题产生1000个答案),否则将它们打包在单个文档中会更容易。但即使在这种情况下,也可以尝试将关系信息放在文档中,例如

    {
        id: "Q1",
        type: "question",
        question: "How do I...?"
    }
    {
        id: "A1",
        type: "answer",
        answer: "Simple... You just..."
        question_id: "Q1"
    }
    {
        id: "C1",
        type: "comment",
        comment: "Works great! Thanks!"
        answer_id: "A1"
    }
    

    这可以使您write操作更容易,但您需要创建viewjoin文档,以便它返回所有文档,只需一个请求。

    始终记住,view的返回结果不一定像sql查询中的行那样是平面结构。