Firebase Cloud Firestore中的反规范化是什么?

Firebase Cloud Firestore中的反规范化是什么?,firebase,google-cloud-firestore,Firebase,Google Cloud Firestore,当谈到Firebase Cloud Firestore时,这种非规范化的真正含义是什么?我在网上读了几篇文章,这里有一些关于stackoverflow的答案,大多数答案都推荐这种方法。这种非规范化究竟有什么帮助?这总是必要的吗 数据库扁平化和非规范化是一回事吗 这是我的第一个问题,希望我能找到一个能帮助我理解这个概念的答案。我知道这是不同的,但我有两年的MySQL经验 Firebase Cloud Firestore中的反规范化是什么 非规范化不仅仅与CloudFireStore有关,它是NoS

当谈到Firebase Cloud Firestore时,这种非规范化的真正含义是什么?我在网上读了几篇文章,这里有一些关于stackoverflow的答案,大多数答案都推荐这种方法。这种非规范化究竟有什么帮助?这总是必要的吗

数据库扁平化和非规范化是一回事吗

这是我的第一个问题,希望我能找到一个能帮助我理解这个概念的答案。我知道这是不同的,但我有两年的MySQL经验

Firebase Cloud Firestore中的反规范化是什么

非规范化不仅仅与CloudFireStore有关,它是NoSQL数据库中普遍使用的一种技术

这种非规范化到底是什么

非规范化是通过在数据库的其他不同位置添加冗余数据来优化NoSQL数据库性能的过程。我所说的添加冗余数据,正如@FrankvanPuffelen在他的评论中已经提到的,这意味着我们复制了完全相同的数据,这些数据已经存在于一个地方,另一个地方,以适应其他地方甚至不可能出现的查询。因此,非规范化有助于掩盖关系数据库固有的低效性

这种非规范化究竟有什么帮助

是的。对于Firebase来说,这也是一种非常常见的做法,因为数据复制是更快读取的关键。我知道您是NoSQL数据库的新手,为了更好地理解,我建议您观看此视频。它适用于Firebase实时数据库,但同样的原则也适用于云Firestore

这总是必要的吗

我们不只是为了使用它而使用非规范化。我们只在绝对需要的时候才使用它

数据库扁平化和非规范化是一回事吗

让我们举一个例子。假设我们有一个测验应用程序的数据库模式,如下所示:

Firestore-root
    |
    --- questions (collections)
          |
          --- questionId (document)
                 |
                 --- questionId: "LongQuestionIdOne"
                 |
                 --- title: "Question Title"
                 |
                 --- tags (collections)
                      |
                      --- tagIdOne (document)
                      |     |
                      |     --- tagId: "yR8iLzdBdylFkSzg1k4K"
                      |     |
                      |     --- tagName: "History"
                      |     |
                      |     --- //Other tag properties
                      |
                      --- tagIdTwo (document)
                            |
                            --- tagId: "tUjKPoq2dylFkSzg9cFg"
                            |
                            --- tagName: "Geography"
                            |
                            --- //Other tag properties
Firestore-root
    |
    --- questions (collections)
    |     |
    |     --- questionId (document)
    |            |
    |            --- questionId: "LongQuestionIdOne"
    |            |
    |            --- title: "Question Title"
    |
    --- tags (collections)
          |
          --- tagIdOne (document)
          |     |
          |     --- tagId: "yR8iLzdBdylFkSzg1k4K"
          |     |
          |     --- tagName: "History"
          |     |
          |     --- questionId: "LongQuestionIdOne"
          |     |
          |     --- //Other tag properties
          |
          --- tagIdTwo (document)
                |
                --- tagId: "tUjKPoq2dylFkSzg9cFg"
                |
                --- tagName: "Geography"
                |
                --- questionId: "LongQuestionIdTwo"
                |
                --- //Other tag properties
我们只需将
标记
集合移动到一个单独的顶级集合中,即可将数据库展平,如下所示:

Firestore-root
    |
    --- questions (collections)
          |
          --- questionId (document)
                 |
                 --- questionId: "LongQuestionIdOne"
                 |
                 --- title: "Question Title"
                 |
                 --- tags (collections)
                      |
                      --- tagIdOne (document)
                      |     |
                      |     --- tagId: "yR8iLzdBdylFkSzg1k4K"
                      |     |
                      |     --- tagName: "History"
                      |     |
                      |     --- //Other tag properties
                      |
                      --- tagIdTwo (document)
                            |
                            --- tagId: "tUjKPoq2dylFkSzg9cFg"
                            |
                            --- tagName: "Geography"
                            |
                            --- //Other tag properties
Firestore-root
    |
    --- questions (collections)
    |     |
    |     --- questionId (document)
    |            |
    |            --- questionId: "LongQuestionIdOne"
    |            |
    |            --- title: "Question Title"
    |
    --- tags (collections)
          |
          --- tagIdOne (document)
          |     |
          |     --- tagId: "yR8iLzdBdylFkSzg1k4K"
          |     |
          |     --- tagName: "History"
          |     |
          |     --- questionId: "LongQuestionIdOne"
          |     |
          |     --- //Other tag properties
          |
          --- tagIdTwo (document)
                |
                --- tagId: "tUjKPoq2dylFkSzg9cFg"
                |
                --- tagName: "Geography"
                |
                --- questionId: "LongQuestionIdTwo"
                |
                --- //Other tag properties
现在,要获取与特定问题对应的所有标记,只需查询
标记
集合,其中
questionId
属性包含所需的问题id

或者,您可以同时展平和反规范化数据库,如以下模式所示:

Firestore-root
    |
    --- questions (collections)
    |     |
    |     --- questionId (document)
    |            |
    |            --- questionId: "LongQuestionIdOne"
    |            |
    |            --- title: "Question Title"
    |            |
    |            --- tags (collections)
    |                 |
    |                 --- tagIdOne (document) //<----------- Same tag id
    |                 |     |
    |                 |     --- tagId: "yR8iLzdBdylFkSzg1k4K"
    |                 |     |
    |                 |     --- tagName: "History"
    |                 |     |
    |                 |     --- //Other tag properties
    |                 |
    |                 --- tagIdTwo (document) //<----------- Same tag id
    |                       |
    |                       --- tagId: "tUjKPoq2dylFkSzg9cFg"
    |                       |
    |                       --- tagName: "Geography"
    |                       |
    |                       --- //Other tag properties
    |
    --- tags (collections)
          |
          --- tagIdOne (document) //<----------- Same tag id
          |     |
          |     --- tagId: "yR8iLzdBdylFkSzg1k4K"
          |     |
          |     --- tagName: "History"
          |     |
          |     --- questionId: "LongQuestionIdOne"
          |     |
          |     --- //Other tag properties
          |
          --- tagIdTwo (document) //<----------- Same tag id
                |
                --- tagId: "tUjKPoq2dylFkSzg9cFg"
                |
                --- tagName: "Geography"
                |
                --- questionId: "LongQuestionIdTwo"
                |
                --- //Other tag properties
Firestore根目录
|
---问题(集合)
|     |
|---问题ID(文档)
|            |
|---问题ID:“LongQuestionIdOne”
|            |
|---标题:“问题标题”
|            |
|---标签(集合)
|                 |
|---tagIdOne(文档)//tagId
。因此,我们将数据展平,以某种方式对现有数据进行分组

有关更多信息,您还可以查看:

因为你说你有SQL背景,所以试着考虑一个规范化的设计,它通常将不同但相关的数据块存储在不同的数据库中
逻辑表,称为关系。如果这些关系作为单独的磁盘文件物理存储,则完成从多个关系(联接操作)中提取信息的查询可能会很慢。如果将许多关系连接起来,速度可能会慢得令人望而却步。因为在NoSQL数据库中,我们没有“JOIN”子句,所以我们必须创建不同的变通方法来获得相同的行为。

非规范化通常意味着在数据库中复制数据。在大多数NoSQL数据库中,这使得读取数据更快、更简单,但代价是写入操作更慢、更复杂。对于一个读量很大的数据库来说,这是一个值得权衡的问题,但它始终取决于您的确切用例和需求。对于堆栈溢出问题来说,涵盖所有这些内容的范围太广了,但我建议您阅读、观看和更新。@FrankvanPuffelen感谢FrankvanPuffelen,我当然会看一看。