MongoDB(noSQL)什么时候分割集合

所以我在NodeJS&ExpressJS中编写了一个应用程序。 这是我第一次使用像MongoDB这样的noSQL数据库,而且我正试图弄清楚如何修复我的数据模型。

在开始我们的项目时,我们已经写下了关系数据库术语中的所有内容,但是自从我们最近从Laravel切换到ExpressJS用于我们的项目之后,我有点卡在用我所有不同的表格布局来做什么。

到目前为止,我已经想出了将你的scheme进行非规范化更好,但它不得不在某个地方结束,对吧? 最后,您可以将您的整个数据存储在一个集合中。 那么,不要input,但你明白了。

那么是否有一个规则标准来定义在哪里进行多重收集? 我有一个关系数据库与用户(这是一个客户端或商店用户),商店,产品,购买,类别,子类别..

2.在noSQL数据库中定义关系不好吗? 就像每个产品都有一个类别,但我想通过一个id(父母在MongoDB中完成这个工作)来关联这个类别,但这是一件坏事吗? 或者你select性能还是结构?

3.是否将noSQL / MongoDB用于具有很多关系的大型数据库(如果它们是在MySQL中创build的)?

提前致谢

正如已经写过的,没有像SQL的第二范式那样的规则。

但是,我将在这里列出一些与MongoDB优化相关的最佳实践和常见陷阱。

过度使用embedded

BSON限制

相反,人们相信,引用没有任何错误。 假设你有一个图书馆,你想跟踪租金。 你可以从这样一个模型开始

{ // We use ISBN for its uniqueness _id: "9783453031456" title: "Schismatrix", author: "Bruce Sterling", rentals: [ { name:"Markus Mahlberg, start:"2015-05-05T03:22:00Z", due:"2015-05-12T12:00:00Z" } ] } 

虽然这个模型有几个问题,但最重要的不是很明显 – 由于BSON文件的大小限制为16MB ,所以租金将会有限

文档迁移问题

将租赁存储在数组中的另一个问题是,这会导致相对频繁的文档迁移,这是相当昂贵的操作。 BSON文件从不分区,并且在增长时预先分配了一些额外的空间。 这个额外的空间被称为填充。 当超过填充时,文档将移动到数据文件中的另一个位置,并分配新的填充空间。 如此频繁的数据添加会导致频繁的文档迁移。 因此,最好的做法是防止频繁更新增加文档的大小,并使用引用。

因此,举例来说,我们将改变我们的单一模型,并创build第二个模型。 首先,这本书的模型

 { _id: "9783453031456", title:"Schismatrix", author: "Bruce Sterling" } 

第二种租金模式看起来像这样

 { _id: new ObjectId(), book: "9783453031456", rentee: "Markus Mahlberg", start: ISODate("2015-05-05T03:22:00Z"), due: ISODate("2015-05-05T12:00:00Z"), returned: ISODate("2015-05-05T11:59:59.999Z") } 

当然,同样的方法可以用于作者或者受赠者。

过度规范化的问题

让我们回顾一下。 开发人员可以确定涉及商业案例的实体,定义它们的属性和关系,编写相应的实体类,将他的头靠在墙上几个小时,以获得需要进行的三重内外部联接工作对于用例而言,所有人都过着幸福的生活。 那么为什么要使用NoSQL和MongoDB呢? 因为没有人过着幸福的生活。 这种方法规模可怕,几乎完全是唯一的规模是垂直的。

但是NoSQL的主要区别在于,根据需要得到解答的问题对数据进行build模。

这就是说,让我们看看一个典型的n:m关系,并把作者和书籍的关系作为我们的例子。 在SQL中,你会有3个表格:两个用于你的实体( 书籍作者 )和一个关系( 谁是哪本书的作者? )。 当然,你可以把这些表格,并创build相应的集合。 但是,由于MongoDB中没有JOIN,所以需要三个查询(一个用于第一个实体,一个用于关系,一个用于相关实体)来查找实体的相关文档。 这是没有意义的,因为n关系的三表方法是专门为了克服SQL数据库强制执行的严格模式而发明的。 由于MongoDB有一个灵活的模式,第一个问题就是在哪里存储关系,从而避免由于过度使用embedded而产生的问题。 由于作者可能会在未来几年写出不less书籍,但是一本书的作者很less(如果有的话)发生变化,答案很简单:我们将作者存储为书籍数据中作者的参考

 { _id: "9783453526723", title: "The Difference Engine", authors: ["idOfBruceSterling","idOfWilliamGibson"] } 

现在我们可以通过两个查询find这本书的作者:

 var book = db.books.findOne({title:"The Difference Engine"}) var authors = db.authors.find({_id: {$in: book.authors}) 

我希望上面的内容能帮助你决定何时“拆分”你的collections,并解决最常见的陷阱。

结论

至于你的问题,这是我的答案

  1. 正如之前所写: 没有 ,但是记住技术限制应该让你知道什么时候才有意义。
  2. 这并不坏 – 只要它符合你的用例 。 如果你有一个给定的类别和_id ,很容易find相关的产品。 在加载产品时,您可以很容易地获得它所属的类别,因为它是默认索引的。
  3. 我还没有find一个MongoDB无法实现的用例,尽pipeMongoDB有些东西可能会变得更加复杂。 你应该做的事情是把你的function和非function的要求总和,检查其优点是否超过缺点。 我的经验法则是:如果需求列表中包含“可扩展性”或“高可用性/自动故障转移”之一,则MongoDB值得一看。

在“关系型”解决scheme上select“NoSQL”解决scheme时,要考虑的第一件事情是“不能以相同的方式工作”,因此在devise上会有不同的反应。

更具体地说,像MongoDB这样的解决scheme并不是要“模仿”出现在许多SQL中的“关系连接”结构,因此也就是“关系”后端,而且他们还打算查看数据“连接”非常不同的方式。

这到达你的“问题”如下:

  1. 实际上没有一套“规则”,并且明白非规范化的“规则”在这里不适用于为什么NoSQL解决scheme存在的基本原因。 那就是提供一些“不同”的东西,可能适合你的情况。

  2. 这不好吗? 好吗? 两者都是主观的。 考虑到这里的“1”,基本的考虑是“非关系”或“NoSQL”数据库被devise为与关系系统“不同”地做事情。 因此,通常以关系方式来“模仿连接”是一种“惩罚”。 特别是对于MongoDB来说,这意味着“额外的请求”。 但这并不意味着你“不能”或“不应该”这样做。 而是关于您的使用模式如何适用于您的应用程序。

  3. 重新设定上述基本观点,NoSQL一般被devise为解决不适合传统的SQL和/或“关系”devise模式的问题,因此用其他方式替代它们。 这里的“终极目标”是让您“重新考虑您的数据访问模式”,并将您的应用程序发展为使用更适合您在应用程序使用中访问它的存储模型。

总之,没有严格的规定,这也是摆脱“正常forms”规则的一部分。 像MongoDB这样的NoSQL解决scheme允许典型的SQL /关系解决scheme无法以有效的forms提供的“嵌套结构”存储。

另一方面,考虑到“连接”这样的操作并没有比“大数据”forms“缩放”,因此存在通过提供诸如“embedded式数据结构”之类的概念“连接”的不同方式,如MongoDB确实。

你可以做一些关于NoSQL解决scheme存储和访问数据的指南。 这最终是您需要决定哪一个最适合您和您的应用程序。

在一天结束时,应该是关于何时SQL /关系模型不能满足您的需求,然后select其他的。