在 MVC 框架中将 noSQL 和 ORM 结合起来用于实际案例应用程序

2024-04-20

一段时间以来,我一直在尝试将过去几年中读到的一些有关 noSQL(couchDB、mongoDB、Redis...)的“酷”东西投入实际使用。

我非常习惯使用 Django 编写应用程序,并开始使用 Play!当 Java 是唯一可接受的部署选项(并且也喜欢它)时。两者都有可以工作的模块,例如MongoDB http://www.mongodb.org/,Django也有nonrel http://www.allbuttonspressed.com/projects/django-nonrel。但我从来没有觉得需要 noSQL。

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

Use Case

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

  • a Fridge that can have
    • 一扇或两扇门,
    • 属于 A、B 或 C 类,
    • 表面颜色
    • 独立或内置
  • an Oven that can have:
    • 天然气或电力或两者兼而有之
    • 自洁与否
    • 独立或内置

SQL/ORM 解决方案

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

在我通常通过 ORM 的 RDBMS 中,我会定义一个“产品”模型,然后继承两个模型,一个冰箱和一个烤箱。 如果冰箱在一段时间后又获得一个属性,我会修改模型(因此,架构),运行迁移,并添加一列。

noSQL 解决方案

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

  • 使用 RDF(类似于Virtuoso http://virtuoso.openlinksw.com/或构建我自己的简化三元组存储)
  • 使用面向文档的数据库,例如 MongoDB

问题

But 我无法理解如何不同(更容易)的开发务实地 be切换到 noSQL 解决方案,仍然使用框架 ORM 和正确的适配器(尤其是 DODB)。

假设我通过 mongodb-engine 将 Django 与 MongoDB 结合使用。

我仍然使用相同的 ORM,因此我仍然将这些对象描述为模型,并列出所有属性。 因此,ORM 正在做完全相同的工作! 如果模型发生变化,使用 ORM(特别是像 South 这样的东西)进行迁移的成本非常有限,不需要自己学习新技术。

DODB 可能有/其他/优势,以及一些特定于 MongoDB 的优势(可扩展性、数据处理,也许是性能),但是……我所描述的确切用例和问题又如何呢?

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

对于这个特定的用例:

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

我知道回答这些问题可能部分是主观的,所以你可以假设你对 noSQL 和 SQL 理论以及普通的 ORM 有完美的了解;存在从普通 ORM 到 noSQL DB 的良好桥梁。假设我们正在讨论使用 MongoDB 作为 noSQL 替代方案的用例。

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

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

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

[edit]

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

相关问题:

[edit]:这些是为了展示我的研究,同时也是为了澄清我所问的并不是 noSQL 与 SQL 的通用问题

  • ORM 对于 NoSQL API 来说是多余的吗? https://stackoverflow.com/questions/2694044/is-an-orm-redundant-with-a-nosql-api: 相似的!但我试图了解为什么大多数框架(见上文)都通过其 ORM 提供 noSQL 访问。这是个好主意吗?
  • 为什么将 ORM 与 NoSql 结合使用(如 MongoDB) https://stackoverflow.com/questions/8051614/why-the-use-of-an-orm-with-nosql-like-mongodb:比前一个更具体,但仍然是相反的。我认为ORM 使 noSQL 变得无用,而不是相反!
  • 何时用 NoSQL 取代 RDBMS/ORM https://stackoverflow.com/questions/3522069/when-to-replace-rdbms-orm-with-nosql
  • 何时使用 MongoDB 或其他面向文档的数据库系统? https://stackoverflow.com/questions/1476295/when-to-use-mongodb-or-other-document-oriented-database-systems
  • https://softwareengineering.stackexchange.com/questions/54373/when-would-someone-use-mongodb-or-similar-over-traditional-rdms https://softwareengineering.stackexchange.com/questions/54373/when-would-someone-use-mongodb-or-similar-over-traditional-rdms

EDIT以及链接:

  • Siena http://www.sienaproject.com/index.html:受 Google App Engine Python 数据存储启发的 Java 持久性 API,试图在 SQL 和 NoSQL 世界之间架起一座桥梁。
  • 迷你蒙戈 https://github.com/slacy/minimongo:轻量级、无模式、Pythonic 面向对象的 MongoDB 接口

这就是我在 stackoverflow 上得到的结果。偶尔有人会问一个悬而未决的问题,我不得不付出 2 美分(冒着影响我自己的项目时间表的风险)。

我刚刚完成了一个项目,我必须将 ORM 与模型分离,以便我可以实现 NoSQL 解决方案,并且发现这并不困难,尽管有时试图找出最佳方法很困难。因此,在不详细介绍我的实现的情况下,我将谈谈我必须做些什么才能使其发挥作用,因为当您沿着相同的道路前进时,它可能会提供一些启发。

我的设置:

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

Goal:

  • 在 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 解决方案时遇到的所有主要障碍,如果您有任何其他问题,请随时联系我。

- 编辑 -

对评论的回应:

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

  2. 开发我自己的 NoSQL 解决方案更多的是对自我的挑战。在工作中,有一个项目要实现一个定制的 NoSQL 解决方案(在 MogileFS 上有过不好的经历),坦率地说,设计和实现都很糟糕。但我并没有仅仅指出不好的地方,而是挑战自己提供一个更好的解决方案,但只是为了一个业余项目。由于面临挑战,我没有研究任何现有的 NoSQL 解决方案,但事后看来我可能应该研究一下。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 MVC 框架中将 noSQL 和 ORM 结合起来用于实际案例应用程序 的相关文章

随机推荐

  • 线程 - 访问资源避免饥饿

    我知道这不是一个 作业助手网站 但最近几天我疯了 因为我必须实现对资源的访问以避免饥饿 但我不知道如何做到这一点 谁能帮助我提供一些应用程序示例或文档 分配是 资源可以由两种类型的进程使用 黑色和白色 当白色进程使用该资源时 黑色进程就不能
  • 自定义 Bootstrap 4 中的折叠过渡

    Bootstrap 4 使用该类 collapsing在打开 关闭 collapse element 时对它的宽度 高度进行动画处理 不幸的是 实际的更改是通过将宽度 高度作为内联样式添加到元素并在过渡的开始和结束处添加和删除类来实现的 因
  • php将所有链接转换为绝对url

    我正在用 php 编写一个网站爬虫 并且我已经有了可以从网站提取所有链接的代码 问题 网站使用绝对 URL 和相对 URL 的组合 示例 http 替换为 hxxp 因为我无法发布超链接 hxxp site com site com sit
  • 服务器<->设备的数据同步框架/算法?

    我正在寻求实现服务器和分布式客户端之间的数据同步 服务器上的数据源是mysql 上面是django 客户可能会有所不同 更新可以在客户端或服务器上进行 并且服务器和客户端之间的连接不可靠 例如 可以在断开连接的手机上进行更改 当手机再次连接
  • 如何“实时”检查输入的内容

    我正在开发一个网络表单 它已经设置了一个文本字段来接收预期的数值 如果此字段的内容不是数字 则表单不会提交 但没有放置错误消息来让用户知道他们填写了错误的此字段 我的问题是 有没有办法实时检查输入内容并采取措施告诉用户他们没有正确填写 如果
  • 如何抑制某些文件的智能感知错误?

    Visual Studio 2015 提供了在同一窗口中显示 Intellisense 错误的选项 该窗口还显示常规生成错误 我喜欢它 因为我什至不需要构建来查看代码的语法是否正确 然而 该窗口还显示一个误报错误 该错误似乎与智能感知错误有
  • 如何使用 iOS 7 自定义过渡在顶部呈现半模态视图控制器

    我将如何在主视图控制器的顶部呈现 半视图 控制器 要求 呈现在主视图控制器顶部滑动的第二个视图控制器 第二个视图控制器应该只显示主视图控制器的一半以上 主视图控制器应在第二视图控制器后面保持可见 透明背景 下面不显示黑色 第二个视图控制器应
  • HTML 多重选择值作为 GET 变量中的逗号分隔字符串

    我设置了一个多选列表 如下所示
  • Java 9 HttpClient 挂起

    我正在尝试HTTP 2客户来自jdk 9 ea 171 代码取自这个例子 https labs consol de development 2017 03 14 getting started with java9 httpclient h
  • PySide.QtGui RuntimeError:对象基类的“__init__”方法未调用...但它是

    一些环境基础知识 Python版本 3 4 2 操作系统 Windows 8 1 到目前为止的搜索 我怀疑这另一个问题 https stackoverflow com questions 12280371 python runtimeerr
  • 使用 R 计算边际税率

    我正在编写一个函数来根据给定的收入水平计算所欠税款澳大利亚的边际税率 https www ato gov au rates individual income tax rates 我编写了该函数的一个简单版本 该函数使用以下代码得出正确的应
  • 如何在保存之前对 Emacs 中更改的行执行操作?

    我想添加一个 before save hook 我可以在其中仅对自上次保存以来更改的行执行一些操作 例如 删除尾随空格 检查缩进等 我不想对整个文件执行此操作 并且我知道每个选项都有单独的选项 只是为了删除所有更改行的尾随空格 等等 但我想
  • 如何使用 Apache PDFBox 将 .png 图像添加到 pdf

    当我尝试使用 pdfBox 绘制 png 图像时 页面保持空白 有没有办法使用pdfBox插入png图像 public void createPDFFromImage String inputFile String image String
  • 如何从复合泛型类型中检索值?

    如何从泛型中检索值 具体来说 我正在尝试以下操作 Test let result Validate goodInput How to access record let request getRequest result 这是代码 type
  • 长文本微调器无法正常工作

    我的旋转器有一些问题 根据我的日期 我必须添加到TableRow a TextView与EditText or a Spinner 我必须在 Spinner 中显示的数组有点长 我用带有短文本的数组测试了我的代码 它看起来像这样 这里唯一的
  • Rails - 具有空数组的强参数

    我正在发送一组关联 ID 例如foo ids到我的控制器 为了允许值数组 我使用 params permit foo ids 现在的问题是 如果我发送一个空数组foo ids 该参数被忽略 而不是清除所有foos正如空数组应该做的那样 关联
  • 如何在响应拦截器中再次发送请求?

    我在我的应用程序中创建了一个拦截器来检测会话丢失 服务器发送 HTTP 419 在这种情况下 我需要从服务器请求一个新会话 然后我想自动再次发送原始请求 也许我可以将请求保存在请求拦截器中 然后再次发送 但可能有更简单的解决方案 请注意 我
  • Android 新的 CallLog.Calls.NUMBER_PRESENTATION 字段有什么用?

    我注意到 API 级别 19 Kitkat 中添加了一个名为 CallLog Calls NUMBER PRESENTATION 的新字段 The 文档 http developer android com reference androi
  • 在Java中,是否可以执行一个方法一段时间,并在达到时间限制后停止?

    我有下载网页的代码 HttpURLConnection connection private String downloadContent InputStream content Source parser try content conn
  • 在 MVC 框架中将 noSQL 和 ORM 结合起来用于实际案例应用程序

    一段时间以来 我一直在尝试将过去几年中读到的一些有关 noSQL couchDB mongoDB Redis 的 酷 东西投入实际使用 我非常习惯使用 Django 编写应用程序 并开始使用 Play 当 Java 是唯一可接受的部署选项