所以我正在用NodeJS和ExpressJS编写一个应用程序。这是我第一次使用像MongoDB这样的noSQL数据库,并且试图弄清楚如何修复我的数据模型。
在我们的项目开始时,我们已经记录了关系数据库中的所有内容,但是由于我们最近从该项目的Laravel切换到ExpressJS,所以我对处理所有不同的表格布局有些困惑。
到目前为止,我已经知道最好对您的方案进行非规范化,但是它必须在某个地方结束,对吗?最后,您可以将整个数据存储在一个集合中。好吧,不是很有趣,但是你明白了。
1.因此,是否有规则或标准定义了在哪里进行切割以进行多个收藏? 我有一个与用户(都是客户或商店用户),商店,产品,购买,类别,子类别的关系数据库。
2.在noSQL数据库中定义关系是否不好? 就像每个产品都有一个类别,但是我想通过一个ID关联该类别(MongoDB中的父工作),但这是一件坏事吗?还是在这里选择性能还是结构?
3. noSQL / MongoDB可以用于具有很大关系(如果它们是在MySQL中创建)的大型数据库吗?
提前致谢
如前所述,没有像SQL的第二范式那样的规则。
但是,我将在此处列出一些与MongoDB优化相关的最佳实践和常见陷阱。
与普遍的看法相反,参考文献没有错。假设您有一个图书馆,并且想跟踪租金。您可以从这样的模型开始
{
// 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"
}
]
}
Run Code Online (Sandbox Code Playgroud)
尽管此模型存在多个问题,但最重要的问题并不明显- 由于BSON文档的大小限制为16MB ,因此租金数量有限。
将租金存储在阵列中的另一个问题是,这将导致相对频繁的文档迁移,这是相当昂贵的操作。BSON文档永远不会被分区和创建,它们在增长时会事先分配一些额外的空间。这个额外的空间称为padding。当超出填充范围时,文档将移动到数据文件中的另一个位置,并分配新的填充空间。因此,频繁添加数据会导致频繁的文档迁移。因此,最佳实践是防止频繁的更新增加文档的大小,而改用引用。
因此,对于该示例,我们将更改单个模型并创建第二个模型。一,本书的模型
{
_id: "9783453031456",
title:"Schismatrix",
author: "Bruce Sterling"
}
Run Code Online (Sandbox Code Playgroud)
出租的第二个模型看起来像这样
{
_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")
}
Run Code Online (Sandbox Code Playgroud)
当然,作者或承租人也可以使用相同的方法。
让我们回头看看。开发人员将识别涉及业务案例的实体,定义它们的属性和关系,编写相应的实体类,将头撞墙几个小时,以达到所需的三层内外以上的工作对于用例,此后所有人都过着幸福的生活。那么,为什么一般都使用NoSQL,尤其是MongoDB?因为从此以后没有人过着幸福的生活。这种方法可怕地缩放,几乎唯一的缩放方法是垂直缩放。
但是NoSQL的主要区别在于,您可以根据需要回答的问题对数据进行建模。
话虽如此,让我们看一个典型的n:m关系,并以作者与书籍之间的关系为例。在SQL中,您有3个表:两个表用于您的实体(书籍和作者),一个表用于关系(哪本书的作者是谁?)。当然,您可以使用这些表并创建它们的等效集合。但是,由于MongoDB中没有JOIN,因此需要三个查询(一个查询用于第一个实体,一个查询用于其关系,一个查询用于相关实体)以查找实体的相关文档。这是没有道理的,因为n:m关系的三表方法是专门为克服SQL数据库强制执行的严格模式而发明的。由于MongoDB具有灵活的架构,因此第一个问题将是存储关系的位置,同时牢记由于过度使用嵌入而引起的问题。由于作者可能会在未来几年写很多书,但由于一本书的作者身份很少甚至根本没有变化,答案很简单:我们将作者存储为书籍数据中的作者参考
{
_id: "9783453526723",
title: "The Difference Engine",
authors: ["idOfBruceSterling","idOfWilliamGibson"]
}
Run Code Online (Sandbox Code Playgroud)
现在,通过执行以下两个查询,可以找到该书的作者:
var book = db.books.findOne({title:"The Difference Engine"})
var authors = db.authors.find({_id: {$in: book.authors})
Run Code Online (Sandbox Code Playgroud)
我希望以上内容可以帮助您决定何时真正“拆分”您的收藏并避开最常见的陷阱。
关于你的问题,这是我的答案
_id,则很容易找到相关产品。加载产品时,您可以轻松获得它所属的类别,甚至可以高效地获得它的类别_id(默认情况下已索引)。| 归档时间: |
|
| 查看次数: |
1359 次 |
| 最近记录: |