首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MongoDB (noSQL)何时拆分集合

问MongoDB (noSQL)何时拆分集合
EN

Stack Overflow用户
提问于 2015-05-06 11:30:21
回答 2查看 4.4K关注 0票数 11

因此,我正在用NodeJS & ExpressJS编写一个应用程序。这是我第一次使用像noSQL这样的MongoDB数据库,我正在努力弄清楚如何修复我的数据模型。

在我们的项目开始时,我们已经用关系数据库的术语写下了所有的东西,但是自从我们最近为我们的项目从Laravel转换到ExpressJS之后,我有点困在如何处理所有不同的表布局上。

到目前为止,我已经想出了最好的办法,去美化你的计划,但它必须在某个地方结束,对吗?最后,您可以将整个数据存储在一个集合中。好吧,不是很认真,但你明白重点。

1.那么,是否有一个 rule 或标准来定义在哪里进行多个集合?我有一个与用户(它们都是客户端或商店用户)、商店、产品、采购、类别、子类别的关系数据库。

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

3. noSQL/MongoDB是否适用于具有许多关系的大型数据库(如果它们是用MySQL创建的)?

提前感谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-06 14:27:41

正如前面所写的,没有类似于SQL的第二个普通形式的规则。

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

过度使用嵌入

BSON极限

与流行的观点相反,参考文献没有什么问题。假设你有一个藏书库,你想追踪租金。你可以从这样的模型开始

代码语言:javascript
复制
{
  // 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文档的大小限制为16 of,因此将有一个有限的租金。

文档迁移问题

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

因此,对于这个例子,我们将更改我们的单个模型,并创建第二个模型。首先,书的模型

代码语言:javascript
复制
{
  _id: "9783453031456",
  title:"Schismatrix",
  author: "Bruce Sterling"
}

租赁的第二种模式是这样的

代码语言:javascript
复制
{
  _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的主要区别在于,您根据需要得到答案的问题对数据进行建模。

话虽如此,让我们看看一个典型的n:m关系,并以作者与书籍之间的关系为例。在SQL中,您有3个表:两个用于实体(图书和作者),另一个用于关系(谁是哪本书的作者?)。当然,您可以使用这些表并创建它们的等效集合。但是,由于MongoDB中没有联接,您需要三个查询(一个查询第一个实体,一个查询其关系,一个查询相关实体)来查找实体的相关文档。这是没有意义的,因为针对n:m关系的三种表方法是专门为克服SQL数据库强制执行的严格模式而发明的。由于MongoDB有一个灵活的模式,第一个问题是在哪里存储关系,同时要记住过度使用嵌入所产生的问题。由于一个作者在未来的几年里可能会写很多书,但是一本书的作者很少(如果有的话)改变,所以答案很简单:我们将作者存储在书籍数据中,作为作者的参考。

代码语言:javascript
复制
{
  _id: "9783453526723",
  title: "The Difference Engine",
  authors: ["idOfBruceSterling","idOfWilliamGibson"]
}

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

代码语言:javascript
复制
var book = db.books.findOne({title:"The Difference Engine"})
var authors = db.authors.find({_id: {$in: book.authors})

我希望以上这些帮助您决定何时真正“拆分”您的集合,并避开最常见的陷阱。

结论

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

  1. 正如前面所写的:No,但是记住技术限制应该给您一个什么时候才有意义的想法。
  2. --它并不坏--只要它适合您的用例。如果您有一个给定的类别及其_id,则很容易找到相关产品。在加载产品时,您可以很容易地获得它所属的类别,即使是如此,因为默认情况下_id是索引的。
  3. 我还没有找到一个用MongoDB无法完成的用例,尽管有些事情可以在MongoDB中变得更加复杂。你应该做的是把你的功能需求和非功能需求之和,检查它们的优缺点。我的经验法则是:如果您的需求列表中有“可伸缩性”或“高可用性/自动故障转移”,那么MongoDB值得一看。
票数 18
EN

Stack Overflow用户

发布于 2015-05-06 11:51:44

在选择用于存储的"NoSQL“解决方案而不是”关系“解决方案时,需要考虑的”第一件事“是,事物”不以相同的方式工作“,因此通过设计响应不同。

更具体地说,像MongoDB这样的解决方案“无意”“模仿”“关系连接”结构,这种结构存在于许多SQL中,因此也存在于“关系”后端中,而且它们的目的是以一种非常不同的方式查看数据“联接”。

以下是你的“问题”:

  1. 实际上并没有设置“规则”,并且理解在这里不适用非正态化的“规则”是因为NoSQL解决方案存在的基本原因。这是为了提供一些“不同”的东西,可以很好地适应你的情况。
  2. 是不是很糟?很好吗?两者都是主观的。考虑到这里的"1“点,基本的考虑因素是,”非关系“或"NoSQL”数据库的设计目的是“与关系系统不同”。因此,通常以关系方式“模拟联接”是一种“惩罚”。对于MongoDB来说,这意味着“额外的请求”。但这并不意味着你“不能”或“不应该”这样做。相反,它是关于您的应用程序的使用模式是如何工作的。
  3. NoSQL通常是为了解决不适合传统的SQL和/或“关系”设计模式的问题而设计的,因此可以用其他方法替换它们。这里的“最终目标”是“重新思考您的数据访问模式”,并使您的应用程序使用更适合您在应用程序使用中访问它的存储模型。

简而言之,没有严格的规则,这也是脱离“n-范式”规则的一部分。NoSQL解决方案(如MongoDB )允许“嵌套结构”存储,而典型的SQL/关系解决方案不能以有效的形式提供这种存储。

另一方面,考虑到诸如“联接”之类的操作并不比“大数据”表单“扩展”得多,因此通过提供“嵌入式数据结构”(如MongoDB )这样的概念,存在着不同的“连接”方式。

您可以很好地了解关于有多少NoSQL解决方案处理存储和访问数据的主题的一些指南。这是您最终需要决定的,以确定哪一个对您和您的应用程序是最好的。

说到底,我们应该认识到/Relational模型什么时候不能满足您的需求,然后选择其他的东西。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30075448

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档