如何使用 NoSQL 进行数据模型

Posted

技术标签:

【中文标题】如何使用 NoSQL 进行数据模型【英文标题】:How to Data model with NoSQL 【发布时间】:2012-09-23 11:05:05 【问题描述】:

我和我的团队都是 NoSQL 的初学者,还在项目中使用带有 SQL Server 2008 的实体框架,但随着时间的推移,项目变得越来越大,越来越复杂,EF 无法为我们解决更多问题,我们决定采用 MongoDB,但是由于范式转换很大,我们仍然有很多疑问,我将它们发布在这里,看看你们的想法和意见。

我有实体“Person Fisica”、“Patient”和“professional”,并且患者和专业人员都是 Person,但不久之后,患者和专业人员将是同一个人前(一个专业的健康单位,也是耐心的)在 SQL Server 中,我们有一个病人有一个物理人的引用和一个专业的人,他也有一个人的引用当病人和专业是同一个人时,两个人引用了同一个人,现在在 mongo 出现了怀疑,这里的一些团队成员几乎想要做同样的事情,患者和专业组织有这个人的 ID。现在我想让病人和专业人士都拥有完整的对象Person,但是哦,这个完整性如何?因为从技术上讲,患者的自然人与专业人员的自然人不同......这个问题和其他问题在这里让我们头疼,在几个共享的实体中,不知道我们是否将实体放在拥有它的对象中或者对象仅采用实体的 ID,与关系数据库中的方式相同。另一个例子:Health Unit 和 UnidadeDeSaude 的类型,一个类型的 Health Unit 有几个 Health Unit,一个 Health Unit 有一个类型,正确的做法是把 Unit Type 对象放在 Health Unit 中或者只是通过 Id 引用它?

在 Google 上搜索了几篇文章,但我们仍然对这些情况存有疑问 http://highlyscalable.wordpress.com/2012/03/01/nosql-data-modeling-techniques/ http://blog.fiesta.cc/post/11319522700/walkthrough-mongodb-data-modeling

【问题讨论】:

【参考方案1】:

由于无法准确查看您拥有的内容,所以一般来说,在 MongoDB 中,您不会像使用 RDBMS 那样加入表。通常,如果您有一个 Person 实体,您会将整个 Person 存储为一个 Person。这是您的代码类的一个很好的映射。

如果您有对其他实体的引用,例如在 Patient 和 Professional 之间共享单个 Person 的位置,您可以使用 RDBMS 中的外键引用来执行此操作。您可以使用 Mongo 执行此操作,但 Mongo 不会为您执行 JOIN。这将由调用者完成。推荐的方法是将 Person 实体的副本放在 Patient 和 Professional 中。这意味着如果您更新 Person 实体,您现在必须在两个地方更新数据,但这并不一定像听起来那么糟糕。更新通常是“快速”的,您可以“原子地”更新两者,因此在实践中,这与更新单个实体几乎没有区别,只是您不必执行 JOIN,因此您的读取更简单且通常更快。

获取数据的最强大工具是文档(实体)上的集合(表)索引,您可以利用的任何方式都将是返回数据的最快方式。因此,与直觉相反,如果您需要更频繁地过滤和处理文档的部分而不是整个文档,则最好将其分解为共享索引键的实体。这意味着将 Person、Patient 和 Professional 存储在同一个集合中并使用两个键。一个键由 Person 和它的派生类(Patient)共享,另一个是选择一个或另一个部分的类型鉴别器。换句话说,使用索引来查找整个实体或整个实体的集合。

除此之外,如果您使用索引来定位实体、Person、Patient 或 Professional,请阅读整个实体并让它包含您在不使用 JOIN 的情况下完成请求所需的一切。因此,无论您请求 Patient 还是 Person(均指同一 Person),无论您读取哪个对象,您都会获得相同的 Person 数据。

简而言之,您将在 Mongo 中复制数据,几乎可以在您使用 SQL 中的 Join 的任何地方进行。

你能画出你的类层次结构吗?

【讨论】:

好的,所以 Professional 和 Patient 不是从 PhysicalPerson 派生的,而是包含一个。与您使用 ORM 所做的不同,在 Mongo 中,您只需按原样序列化 Patient,包括直接嵌入的 Person 对象,假设您想在一个操作中读取整个 Patient。记得做一个 JOIN ,这将是两个操作。但是,如果您想单独操作 Person 对象,那么最好将它们作为集合中的单独***实体。事实上,您可以两者都做,具体取决于最适合您的查询。 感谢@cirrus,这为我和我的团队澄清了很多事情!

以上是关于如何使用 NoSQL 进行数据模型的主要内容,如果未能解决你的问题,请参考以下文章

NoSQL如何构建数据存储模型

如何正确选择NoSQL数据库?选型要点有哪些?

我需要关于 NoSQL/MongoDb 和数据/模型结构的建议

如何使用 NoSQL 大规模运行地理空间查询?

使用通用域模型的 DAL 架构

初学者该如何选择NoSQL数据库?