如何将基于对象的数据存储在数据库中以使其保持可查询状态?
How to store object-based data in a database so it remains queryable?
我正在从头构建一个 PHP 框架(不幸的是,我在这件事上别无选择)。要求框架高度依赖面向对象数据,因此需要具备高效存储大量面向对象数据的能力。
我正在为第二部分而苦苦挣扎。
我已经为此工作了几个月。最初我被介绍了 ORM 的想法,在尝试了一些预构建的库(Doctrine 2、Redbean 等)之后我喜欢这个想法,但是我能找到的 none 以所需的方式运行,所以我着手创建自己的 ORM,结果非常好。唯一的问题确实是它的性能受到影响,在花了一些时间尝试优化它之后,我现在确信 ORM 并不是解决问题的完全方法。虽然很接近,但还不够。
我已经简要研究了其他解决方案,但由于我在这方面缺乏经验,我很难找到解决方案。
以下是数据存储引擎的要求:
- 最终,它需要能够存储键值对
- "value"部分可以是简单数据类型,也可以是对象,或者同类型对象的数组。
- 应用程序定义了每个对象(或 SCHEMA)的结构,有点像 .wsdl 文件的工作方式,因此引擎需要喜欢严格的格式。
- 对象可以重用它们的实例,也可以不重用。这意味着如果一个对象作为子对象存在于多个位置(跨越许多对象),那么它的值在它所在的任何地方都是相同的(如果它被重新使用)。否则,每个现有对象都存在一个对象的新实例(不重复使用)。
- 需要能够有效地查询数据,对对象的任何部分进行比较以找到它。例如:
find a customer where customer.address.postcode LIKE ('%XXX%')
如有任何建议,我们将不胜感激
编辑
感谢那些迄今为止在我有点疯狂的努力中试图帮助我的人。回答到目前为止提出的一些问题:
您尝试过哪些解决方案,为什么它们不起作用?
ORM 系统
我已经为 PHP 尝试了少量预构建的 ORM 库。包括 Doctrine 2 和 Redbean。对于 Doctrine,它更多地与您如何指定模型的 SCHEMA 有关,因为您需要在文档块中这样做。由于我的要求,我发现这特别难用,特别是因为我知道有很多方法可以避免这种情况。我最终确实设法让 Doctrine 以我想要的方式工作,但这是在破解代码之后。同样,这很有趣,但不正确。
Redbean 主动要求我更改对象的 属性 名称。我的要求之一是基本上能够插入任何类型的面向文档的对象,并存储它。因此,必须专门命名属性才能做到这一点是违反直觉的。再一次,我确实用 Redbean 玩了一会儿让它工作,这是不对的。
在尝试了更多的 ORM 系统之后,我觉得我有能力制作自己的 ORM 系统。还是那句话,我做的ORM系统还是不错的,正好符合要求。由于性能不佳,特别是在处理大量数据时,尤其是在处理非常复杂的模型时,它表现得非常糟糕。
将对象存储在 XML 个文件中
我有很短的时间考虑过这个问题,认为也许我的要求意味着我总是会以性能问题告终。因此,我着手设计一种生成基于文本的存储的方法,并最终创建了一个完整的 SCHEMA 引擎和许多其他有趣的东西。最后证明这只是一个有趣的项目,我根本无法执行它。
NoSQL
我最近的努力让我走上了 MongoDB 和其他一些我不太了解的 NoSQL 系统的道路,比如 Cassandra。
MongoDB 非常接近我 可以 使用的工具,但是它需要我添加一个额外的层,因为我实际上需要一个 SCHEMA ,因为我的对象总是符合特定的结构。我正在慢慢接受 MongoDB 可能是解决方案,但是我想在花更多时间之前先确定一下。
高效到底是什么意思?
当我提到效率时,我并不是 100% 谈论性能,虽然性能肯定是我用来考虑我的选择的一个重要因素,但我明白沿着这条路而不是关系数据库之类的东西,性能自然会出问题
我更多的是在谈论使用正确的工具。我从不喜欢必须破解某人的代码才能使事情正常进行。对我来说,感觉好像我把事情推向了一条系统没有设计好的道路上,在未来的某个时候它会咬我一口。
所以真的,当我提到我正在寻找一些东西时 "efficient",我的意思是尽可能匹配需求的工具,所以我只是 using/extending 功能,而不是而不是重写它。
这里有一些要研究的路线。您对存储 "objects" 的要求(对于数据库而言是一个相当宽泛的术语)让我想到:
- 以序列化格式将数据存储在数据库中,例如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,也许你得到的反馈会更具体 - 并带您朝着更好的方向前进)。
我正在从头构建一个 PHP 框架(不幸的是,我在这件事上别无选择)。要求框架高度依赖面向对象数据,因此需要具备高效存储大量面向对象数据的能力。
我正在为第二部分而苦苦挣扎。
我已经为此工作了几个月。最初我被介绍了 ORM 的想法,在尝试了一些预构建的库(Doctrine 2、Redbean 等)之后我喜欢这个想法,但是我能找到的 none 以所需的方式运行,所以我着手创建自己的 ORM,结果非常好。唯一的问题确实是它的性能受到影响,在花了一些时间尝试优化它之后,我现在确信 ORM 并不是解决问题的完全方法。虽然很接近,但还不够。
我已经简要研究了其他解决方案,但由于我在这方面缺乏经验,我很难找到解决方案。
以下是数据存储引擎的要求:
- 最终,它需要能够存储键值对
- "value"部分可以是简单数据类型,也可以是对象,或者同类型对象的数组。
- 应用程序定义了每个对象(或 SCHEMA)的结构,有点像 .wsdl 文件的工作方式,因此引擎需要喜欢严格的格式。
- 对象可以重用它们的实例,也可以不重用。这意味着如果一个对象作为子对象存在于多个位置(跨越许多对象),那么它的值在它所在的任何地方都是相同的(如果它被重新使用)。否则,每个现有对象都存在一个对象的新实例(不重复使用)。
- 需要能够有效地查询数据,对对象的任何部分进行比较以找到它。例如:
find a customer where customer.address.postcode LIKE ('%XXX%')
如有任何建议,我们将不胜感激
编辑
感谢那些迄今为止在我有点疯狂的努力中试图帮助我的人。回答到目前为止提出的一些问题:
您尝试过哪些解决方案,为什么它们不起作用?
ORM 系统
我已经为 PHP 尝试了少量预构建的 ORM 库。包括 Doctrine 2 和 Redbean。对于 Doctrine,它更多地与您如何指定模型的 SCHEMA 有关,因为您需要在文档块中这样做。由于我的要求,我发现这特别难用,特别是因为我知道有很多方法可以避免这种情况。我最终确实设法让 Doctrine 以我想要的方式工作,但这是在破解代码之后。同样,这很有趣,但不正确。
Redbean 主动要求我更改对象的 属性 名称。我的要求之一是基本上能够插入任何类型的面向文档的对象,并存储它。因此,必须专门命名属性才能做到这一点是违反直觉的。再一次,我确实用 Redbean 玩了一会儿让它工作,这是不对的。
在尝试了更多的 ORM 系统之后,我觉得我有能力制作自己的 ORM 系统。还是那句话,我做的ORM系统还是不错的,正好符合要求。由于性能不佳,特别是在处理大量数据时,尤其是在处理非常复杂的模型时,它表现得非常糟糕。
将对象存储在 XML 个文件中
我有很短的时间考虑过这个问题,认为也许我的要求意味着我总是会以性能问题告终。因此,我着手设计一种生成基于文本的存储的方法,并最终创建了一个完整的 SCHEMA 引擎和许多其他有趣的东西。最后证明这只是一个有趣的项目,我根本无法执行它。
NoSQL
我最近的努力让我走上了 MongoDB 和其他一些我不太了解的 NoSQL 系统的道路,比如 Cassandra。
MongoDB 非常接近我 可以 使用的工具,但是它需要我添加一个额外的层,因为我实际上需要一个 SCHEMA ,因为我的对象总是符合特定的结构。我正在慢慢接受 MongoDB 可能是解决方案,但是我想在花更多时间之前先确定一下。
高效到底是什么意思?
当我提到效率时,我并不是 100% 谈论性能,虽然性能肯定是我用来考虑我的选择的一个重要因素,但我明白沿着这条路而不是关系数据库之类的东西,性能自然会出问题
我更多的是在谈论使用正确的工具。我从不喜欢必须破解某人的代码才能使事情正常进行。对我来说,感觉好像我把事情推向了一条系统没有设计好的道路上,在未来的某个时候它会咬我一口。
所以真的,当我提到我正在寻找一些东西时 "efficient",我的意思是尽可能匹配需求的工具,所以我只是 using/extending 功能,而不是而不是重写它。
这里有一些要研究的路线。您对存储 "objects" 的要求(对于数据库而言是一个相当宽泛的术语)让我想到:
- 以序列化格式将数据存储在数据库中,例如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,也许你得到的反馈会更具体 - 并带您朝着更好的方向前进)。