【问题标题】:Combining noSQL and ORM in an MVC framework for a real-case application在 MVC 框架中结合 noSQL 和 ORM 用于实际应用程序
【发布时间】:2012-01-11 01:13:30
【问题描述】:

一段时间以来,我一直在尝试将我在过去几年中读到的关于 noSQL(couchDB、mongoDB、Redis...)的一些“酷”的东西付诸实践。

我很习惯用 Django 编写应用程序,并开始使用 Play!当 Java 是唯一可接受的部署选项时(并且也很享受它)。两者都有模块可以工作,例如MongoDB,django 也有nonrel。但我从不觉得需要 noSQL。

直到我最终发现我认为是面向文档存储的一个很好的用例,例如 MongoDB。

用例

假设我们必须管理一些复杂项目的订购和跟进(无论如何)。这些项目可能有很多不同的属性,例如。过度简化我们可以有:

  • 可以有冰箱
    • 一两扇门,
    • 属于 A、B 或 C 类,
    • 表面颜色
    • 独立或内置
  • 烤箱可以有:
    • 燃气或电力或两者兼有
    • 自清洁与否
    • 独立或内置

SQL/ORM 解决方案

如您所见,每个对象都可以有多个可以受类型约束的属性。

在我通常通过 ORM 的 RDBMS 中,我会定义一个“产品”模型,然后继承两个模型,一个冰箱和一个烤箱。 如果一段时间后冰箱获得了更多属性,我会修改模型 - 以及相应的架构 -、运行迁移并添加一列。

noSQL 解决方案

我能想到的noSQL解决方案有:

  • 使用 RDF(使用 Virtuoso 之类的东西或构建我自己的简化三元组存储)
  • 使用面向文档的数据库,例如 MongoDB

问题

但是我无法理解实际切换到仍然使用框架 ORM 和正确适配器(尤其是 DODB)的 noSQL 解决方案会有多么不同(更容易)的开发.

假设我通过 mongodb-engine 将 Django 与 MongoDB 一起使用。

我仍然使用相同的 ORM,所以我仍然将这些对象描述为模型,列出所有属性。 因此,ORM 正在做同样的工作! 如果使用 ORM(尤其是像 South 之类的东西)模型发生更改,则生成迁移的成本非常有限,不需要自己学习新技术。

DODB 可能有 /other/ 优点,而某些特定于 MongoDB(可扩展性、数据处理、可能是性能),但是......我所描述的确切用例和问题呢?

我很可能错过了一点,所以真正的问题来了:

对于这个特定的用例:

  • 这个例子对 DODB 来说是好还是坏(你有好的例子吗)?
  • 将 ORM 用于基本内容(用户、订单)和使用 noSQL没有复杂对象的 ORM 是否有意义,是否有完全切换到 noSQL 的令人信服的理由,或者我应该继续使用现有的 ORM/SQL?

我知道回答这些问题可能是部分主观的,因此您可以假设您完全了解 noSQL 和 SQL 理论,以及常用的 ORM;存在从库存 ORM 到 noSQL DB 的良好桥梁。假设我们正在讨论这个用 MongoDB 作为 noSQL 替代方案的用例。

但还有一个更普遍的问题——这是这篇 SO 帖子的核心问题:

  • 难道不是一个好的 ORM(例如 JPA、ActiveRecord 或 Django 的 ORM)使得 noSQL 尤其是面向文档的数据库几乎没有用处吗?
  • ...是否值得将 noSQL 与“经典”ORM 一起使用?

(从编程和维护的角度来看,“很少使用”,性能和类似标准是另一回事,需要精确的产品与产品比较)

[编辑]

我还想了解的是,在切换到 noSQL 时是否最好放弃使用 ORM。拥有更多“动态”模型会很好,例如。我可以有一个表格来描述冰箱和烤箱 模型 是什么(字段),代码中的冰箱和烤箱模型将能够动态构建它们的视图(用于编辑的表单和用于显示的列表) .

相关问题:

[编辑]:这些是为了展示我的研究,但也为了澄清我所问的不是关于 noSQL 与 SQL 的通用问题

编辑 和链接:

  • Siena:受 Google App Engine Python Datastore 启发的 Java 持久性 API,试图在 SQL 和 NoSQL 世界之间架起一座桥梁。
  • minimongo:MongoDB 的轻量级、无模式、Pythonic 面向对象接口

【问题讨论】:

  • slacy.com/blog/2011/01/… 这似乎朝着我正在考虑的方向发展。不要使用带有 nosql 的“经典”orms = 使用自定义 orms 或不使用 nosql :)
  • 将此标记为移至程序员
  • 我发现了一个有趣的项目:Siena

标签: django model-view-controller orm nosql playframework


【解决方案1】:

这是一个相当开放的问题,没有“正确”的答案。 NoSQL 和 SQL (ORM) 之间的决定取决于太多因素。我会问一些问题:

  • 您对这两种技术的熟悉程度如何?
  • 在您的场景中,权衡的影响是什么?关系模型提供了一些 NoSQL 不提供的保证,反之亦然
  • 您的模型多久更换一次?应用程序的演进通常需要模型更改,但您期望更改多少?

正如我告诉你的,它是开放式的。我个人的建议是使用您所知道的技术开始建模。如果您真的需要,您可以随时集成新组件。

当然,如果对使用 NoSQL 的兴趣纯粹是“学术”,不要介意最佳场景,使用它,你会看到它的优缺点。

编辑评论(答案不适合评论区):

@Stefano 恐怕我不明白你的意思,因为框架中 NoSQL 的使用(或 ORM 的使用)取决于你的需求。

这不是“在这个框架中使用这个工具很好”的问题,因为支持(通常)非常好。问题应该是“我需要使用这个工具吗,为什么以及它给我带来了什么好处?”。

如果答案是“是的,我需要这个,因为 A、B 和/或 C”然后继续使用它。

如果答案是“不,因为 A 或 B”或“它没有任何区别”,那么要么不要使用它,要么从可用的选项中选择你最熟悉的选项。

也就是说,一个框架支持某些东西这一事实并不意味着它更差或更好,或者应该或不应该使用。这就是我提出问题的原因。最后,这是一个关于 NoSQL 与 SQL 的问题,因为您用来集成它的工具(ORM、SQL 等等)只是访问数据的渠道,与您为问题选择的存储系统相比,它的相关性较低(因为根据定义,该工具将受到存储系统的限制)

【讨论】:

  • 谢谢 Pere,我同意 /can/ 是一个悬而未决的问题,而且我确实有一些“学术”兴趣;但是我试图确定的是,虽然与您的(第二和第三)问题相关,但使用 noSQL 和 ORM,例如 Rails 的 ActiveRecord,或 Django 的,或 Java 的 JPA。有了这样的 ORM,我感觉 noSQL 从编程角度来看的大部分优势都消失了,包括迁移(可能还有其他标准,例如性能)。因此,我的问题不是关于 SQL 与 noSQL,而是关于 noSQL 在 Django、Play!、Rails 等典型框架中的使用。
  • 1) 仅在理论上熟悉 noSQL 2) 这是我想了解的部分内容。那些“保证”是什么? 3) 不时。通常在开始时,之后每个月左右
  • Pete,我回答了你的问题(尽管第二个问题实际上是我问题的一部分!),但我仍然不能同意我的问题是关于 noSQL 与 SQL 的。由于大多数现代框架中的 ORM 可以 noSQL 和 SQL 一起使用,因此我的问题是,将这种 ORM 与 noSQL 一起使用是否有意义。
  • 最后我意识到你的“ORM vs. noSQL”的回答是完全正确的,但那是因为我知道没有 ORM 足以将 noSQL 优势带入框架!如果您有兴趣,请参阅我对 DigitalPrecision 的 cmets,稍后我可能会添加完整的答案(尽管我不会接受它,因为它只是一个非常具体的应用程序,而不是一个好的整体解决方案)!
【解决方案2】:

我还想了解的是,如果不是更好 切换到 noSQL 时放弃使用 ORM

完全放弃 ORM 并没有什么好处。但是您可能需要对其进行相当多的重写。有很多小事情,例如事务、事件顺序写入、错误处理和数据完整性检查,ORM 可以以 noSQL 方式为您处理。

ORM 并不意味着处理所有可能的特性,即使在 SQL 中也是如此。他们只是做“大部分”繁重的工作。这就是为什么 django ORM 在您需要时提供对 SQL 类的直接访问。

【讨论】:

  • 谢谢,这对我仍然不准确的印象。现在,我更务实地试图理解的是如果玩!和 Django (RoR ...) 保留现有的 ORM 是有意义的,或者如果应该从头开始设计一个(完全)新的,更适合 noSQL 的无模式特性(键值或 d-o)。例如,我的印象是 Play! Morphia 或 django-mongodb 引擎方法是有限的,因为如果 ORM 编程(几乎)完全相同,切换到 MongoDB 几乎没有什么好处。最大的优势似乎仅限于避免外键!
【解决方案3】:

这就是我从堆栈溢出中得到的。偶尔会有一个悬而未决的问题被问到,我不得不提供我的 2 美分(冒着我自己的项目时间表的风险)。

我刚刚完成了一个项目,我必须将 ORM 从模型中分离出来,以便我可以实施 NoSQL 解决方案,并且发现这并不困难,尽管有时很难找出最佳方法。因此,对于我的实现,我不会太具体,我将谈谈我必须做些什么才能让它发挥作用,因为当你走上同样的道路时,它可能会提供一些启示。

我的设置:

  • 框架 - Symfony 1.4
  • ORM - 学说 1.4
  • NoSQL - 我自己的专有解决方案

目标:

  • 在 xml 文件与数据库中存储图像路径
  • 在 xml 文件与数据库中存储 html 描述路径

我不想将图像作为 blob 存储在持久存储(数据库)中,也不想将图像路径存储在数据库中,因为我不想支付创建数据库连接的开销并查询路径。所以我决定将路径信息存储在 NoSQL 持久存储(文件系统)中。

对于 html 描述也是如此,我不想在我的表上创建一个文本列并在数据库中存储可能有数百行 html 的内容,原因与上述相同。

我所有的 NoSQL 文件都与一个对象(例如冰箱)相关。这些文件包含指向其相关资产(html 描述和图像)的路径,我称之为指针,它指向文件系统上的资产。我选择使用 XML 格式来存储数据,所以它看起来像这样:

// Path to pointer file
/home/files/app/needle/myApp/refrigerator/1/1.xml

// Example pointer
<pointer>/home/files/app/file/myApp/refrigerator/1.png</pointer>

现在,我必须在框架内重写 save() 方法,以便可以使用 NoSQL API 保存上述资产。这很简单,我只是检查了父调用并维护了进入方法的值,因此它们不会破坏任何我不知道的链逻辑(方法调用具有相同参数的其他方法)。我还让我的自定义 NoSQL API 调用引发异常,因为主 save() 调用被包装在 try/catch 块中。您在这里唯一需要注意的是确定您的 NoSQL 资产是否值得停止整个事务。在我的示例中,我必须弄清楚上传图像是否会破坏将其余表单字段保存在数据库中(我选择破坏事务)。

我还必须更改 load() 方法以使用 NoSQL API 与标准模型逻辑检索资产。与保存方法一样,这也不难做到。我只需要看看父类在做什么,而不是搞砸任何参数值。

说完之后,我可以在文件系统上存储图像和 html 描述,并使用一个由指向其位置的指针组成的 xml 文件。所以现在我不会在每次需要资产时都调用数据库。

一些注意事项(这些可能包含在其他 NoSQL 解决方案中,我必须自己编写):

  • 您将无法查询具有永久存储图像的冰箱。您必须在应用程序中编写一些逻辑才能从 NoSQL 存储中提取资产。
  • 备份:在备份持久存储数据时,您还需要备份 NoSQL 数据。
  • 孤儿:现在您的架构不知道您可能拥有的任何资产,从持久性存储中删除一行将使文件系统上的资产成为孤儿。因此,请确保您的应用程序具有在删除行时清理 NoSQL 存储的逻辑。

我认为我在使用 ORM 实施 NoSQL 解决方案时遇到了所有主要障碍,如果您有任何其他问题,请随时联系我。

-- 编辑--

对 cme​​ts 的回应:

  1. 正如我所提到的,我不想创建数据库连接和查询只是为了获取资产的路径。我觉得对此类信息使用 NoSQL 解决方案会更好,因为确实没有理由对此类信息(图像或 html 描述)运行查询。

  2. 开发我自己的 NoSQL 解决方案更像是一个自我挑战。在工作中,有一个实施自定义 NoSQL 解决方案的项目(对 MogileFS 有过不好的体验),坦率地说,设计和实施都很差。但是,我不只是指出不好的地方,而是挑战自己提供一个更好的解决方案,但只是为了一个附带项目。而且由于挑战方面,我没有研究任何已经可用的 NoSQL 解决方案,但事后看来我可能应该研究。

我仍然认为您可以通过使用 ORM 的模型层覆盖 crud 函数来实现 MongoDB 或任何 NoSQL 解决方案,相对容易。事实上,我不仅实现了我的 NoSQL 解决方案,还在 crud 函数中添加了将数据索引到 SOLR(用于全文搜索)的功能,所以一切皆有可能。

【讨论】:

  • 感谢@Digital-Precision 的分享!我简单地浏览了一下,虽然我必须花更多时间来了解细节,但我必须说这仍然是一个非常“简单”的 noSQL(文件系统)。对于这些情况,我通常(在 Django 中)以与您类似的方式扩展模型,听起来以特定方式扩展/修改 orm 绝对有意义。当涉及复杂的 noSQL 时,选择变得更加复杂,例如面向文档的存储。 ORM 的优点是引入了一些在您的用例中不需要的抽象(我清楚吗?!)
  • 花时间慢慢地重新审视它。事实上,即使对于“更简单”的用例,您仍然必须面对我能想到的大多数异常问题!我现在有两个主要问题,我将在单独的 cmets 中提出......
  • Q1) 为什么不简单地将资源路径信息添加到数据库中,然后使用DQL 将其与主模型一起检索?这样可以避免进行多个查询,同时允许您维护 ORM 方法(尽管我不知道教义如何帮助文件存储)。对于数据库或文件系统中的数据块,这是一个困难的调用 - 我不确定文件系统是否真的比一个好的数据库更好。但是你在编码上松了。
  • Q2) 在您的特定用例中,这可能不太有用,但是您是否考虑过具有真实数据库和它们自己(或集成的)ORM 的现有 noSQL 解决方案?对于我的需要,文件存储肯定是不够的,面向文档的 noSQL 听起来不错。如果我采取你的方式,我会避免使用任何 ORM,而只是破解现有的 ORM 以进行保存、删除和数据检索。这肯定是一次性代码。这比任何现有的 noSql / 或 / Sql ORM 更好吗?我知道这部分问题实际上太宽泛了:)
  • @Stefano:你最后做了什么?
猜你喜欢
  • 2015-04-27
  • 1970-01-01
  • 2011-11-28
  • 2017-11-10
  • 2010-10-06
  • 2019-06-13
  • 1970-01-01
  • 2010-10-29
  • 1970-01-01
相关资源
最近更新 更多