【问题标题】:How to store object-based data in a database so it remains queryable?如何将基于对象的数据存储在数据库中,使其保持可查询状态?
【发布时间】:2015-04-13 11:51:53
【问题描述】:

我正在从头构建一个 PHP 框架(不幸的是我在这件事上没有任何选择)。框架需要高度依赖面向对象的数据,因此需要具备高效存储大量面向对象数据的能力。

我正在为第二部分苦苦挣扎。

我已经为此工作了几个月。最初,我被介绍了 ORM 的想法,在尝试了一些预构建的库(Doctrine 2、Redbean 等)之后,我喜欢这个想法,但我找不到的东西都没有按照要求的方式运行,所以我开始着手创建我自己的 ORM,结果非常好。唯一真正的问题是它的性能受到影响,并且在花了一些时间尝试优化它之后,我现在确信 ORM 并不能完全解决这个问题。虽然很接近,但它并没有完全削减它。

我曾简要研究过其他解决方案,但由于我缺乏这方面的经验,我正在努力找出解决方案。

以下是数据存储引擎的要求:

  • 最终,它需要能够存储键值对
  • “值”部分可以是简单的数据类型,也可以是对象,也可以是同类型对象的数组。
  • 应用程序定义每个对象(或 SCHEMA)的结构,有点像 .wsdl 文件的工作方式,因此引擎需要喜欢严格的格式。
  • 对象可以重复使用它们的实例,也可以不重复使用。这意味着如果一个对象作为子对象存在于多个位置(跨越许多对象),它的值在它所在的任何地方都是相同的(如果它被重复使用)。否则,每个现有对象都会存在一个新的对象实例(不重复使用)。
  • 需要能够有效地查询数据,对对象的任何部分进行比较以找到它。例如:find a customer where customer.address.postcode LIKE ('%XXX%')

任何建议将不胜感激

编辑

感谢那些迄今为止在我有点疯狂的努力中试图帮助我的人。回答一些迄今为止被问到的问题:

您尝试了哪些解决方案,为什么它们不起作用?

ORM 系统

我尝试了少量的 PHP 预建 ORM 库。包括教义 2 和红豆。对于 Doctrine,它更多地与您如何指定模型的 SCHEMA 有关,因为您需要在 docblocks 中这样做。由于我的要求,我发现这使用起来特别尴尬,特别是因为我知道有很多方法可以避免这种情况。我最终确实设法让 Doctrine 以我想要的方式工作,但这是在破解代码之后。再一次,这很有趣,但它不正确。

Redbean 主动要求我更改对象的属性名称。我的要求之一是基本上能够插入任何类型的面向文档的对象并存储它。因此,必须专门命名属性才能做到这一点是违反直觉的。同样,我确实与 Redbean 一起玩了一段时间以使其正常工作,这是不对的。

在使用了更多的 ORM 系统之后,我觉得自己具备了制作自己的知识。同样,我制作的 ORM 系统也很好,因为它准确地满足了要求。由于性能不佳,特别是在处理大量数据时,它被严重拖累,但在处理非常复杂的模型时更是如此。

在 XML 文件中存储对象

有一小段时间我考虑过这个问题,我想也许我的要求意味着我最终总是会遇到性能问题。所以我开始设计一种生成基于文本的存储的方法,最终创建了一个完整的 SCHEMA 引擎和一堆其他有趣的东西。结果这只是一个有趣的项目,我根本无法让它执行。

NoSQL

我最近的努力使我走上了 MongoDB 等系统和一些其他 NoSQL 系统的道路,这些系统像 Cassandra 一样我没有深入了解。

MongoDB 非常接近成为我可以使用的工具,但是它需要我添加一个额外的层,因为我确实需要一个 SCHEMA,因为我的对象总是符合特定的结构体。我正在慢慢接受 MongoDB 可能是解决方案,但我想在我花更多时间之前确定一下。

高效到底是什么意思?

当我提到效率时,我并不是 100% 谈论性能,虽然性能肯定是我用来考虑我的选择的一个重要因素,但我明白沿着这条路线走,而不是像关系数据库这样的东西,性能自然会出问题。

我更多的是谈论使用正确的工具。我从不喜欢为了让事情正常工作而不得不破解某人的代码。对我来说,感觉好像我正在把事情推到系统设计不适合的道路上,并且在未来的某个时候它会咬我**。

所以说真的,当我提到我在寻找“高效”的东西时,我的意思是尽可能匹配需求的工具,所以我只是在使用/扩展功能,而不是重新编写它。

【问题讨论】:

  • 这听起来像是一场噩梦。我建议您说您不能这样做并继续进行另一个项目。从头开始构建由高技能工程师组成的大型团队多次完成的东西似乎很愚蠢。
  • @gnarly 我在一定程度上同意,但我找不到这样做的例子。至少不像我描述的那样。如果你能指出一些很好的例子
  • 我会使用 Doctrine,你说它不能满足你的需求,但也许可以改变需求以使用现有技术。这是在花费数千小时自己构建东西或做出妥协以避免繁重工作之间取得平衡。
  • 这个要求是“有趣的部分”:“需要有高效查询数据的能力”——参见:“任何大玩家”。无论如何,您需要定义“有效”。你看过什么?你为什么拒绝他们?
  • 你说的数据量是多少?估计记录数?卷?钥匙数量?不同数据之间有多少关系?您需要多快访问它?你目前的数据结构?它不能与你想要的东西一起工作。

标签: php database oop object


【解决方案1】:

这里有一些路线可供研究。您对存储“对象”(涉及数据库时相当宽泛的术语)的要求让我想到:

  • 以序列化格式将数据存储在数据库中,例如JSON。 PostgreSQL 这些天 has ways to reach into such a column 对其进行搜索操作,因此它不像以前认为的那样不可搜索(尽管我希望它比查询正确规范化的数据要慢)。
  • 存储customer.address.postcode 的要求使我认为您可以将数据存储为层次结构,在这种情况下,您可以使用多种算法。查看nested sets。这旨在与关系数据库很好地配合使用,而无需使用递归 SQL。
  • 这不是我的专业领域,但 graph databases 可能值得研究。

顺便说一句,据我所知,Doctrine 是一个很棒的库,但我怀疑您需要先弄清楚要使用什么技术。它被广泛设计为映射到关系数据库,因此如果您不能在原始 RDBMS 中清晰地表达您的问题,Doctrine 可能无济于事。

(这可能是XY question,很难说。你说过你需要Y,但如果你能告诉我们你想要实现X,也许你得到的反馈会更具体——并带您走向更好的方向)。

【讨论】:

  • 您的第一点是我前段时间尝试过的另一种技术。就性能而言,您的担忧是正确的。不过我得谢谢你。我不知道嵌套集,这似乎正是我正在寻找的!非常感谢您让我注意到这一点!
  • 太好了,@唐尼! Propel 和 Doctrine 都有嵌套的集合实现,你可以查看它们。据我回忆,Propel 一号真的很容易使用(没有尝试过 Doctrine 一号,应该也很简单)。
  • 我也会看看 Propel。研究嵌套集让我想到了图形数据库,这看起来也是另一个潜在的解决方案
  • 哈,是的,我想知道我是否应该提及图形数据库——不过从未尝试过。
  • 我仍然不能 100% 确定。图形数据库看起来更符合我的需求,但我已经注意到它似乎会产生更多需要解决的问题。我想我很可能注定要创建一个自定义 ORM,但是我将进行最后一次尝试,并将这个问题扩展到另一篇文章中,该文章将准确概述我正在尝试做的事情。有兴趣的朋友请继续关注!
猜你喜欢
  • 1970-01-01
  • 2014-06-22
  • 2019-08-15
  • 2021-11-27
  • 2017-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-05
相关资源
最近更新 更多