我经常听到人们因为缺乏灵活性和“漏洞抽象”而抨击ORM,但你真的没有听到为什么他们有问题。如果使用得当,ORM的错误究竟是什么?我问这个是因为我正在研究一个PHP orm,我希望它能解决许多其他ORM失败的问题,例如延迟加载和缺少子查询。
请具体说明您的答案。显示一些代码或描述ORM挣扎的数据库模式。与语言或ORM无关。
答案 0 :(得分:5)
我用过的所有ORM注意到的一个更重要的问题是只更新几个字段而不先检索对象。
例如,假设我在我的数据库中映射了一个Project对象,其中包含以下字段:Id,name,description,owning_user。比方说,通过ajax,我想只更新描述字段。在大多数ORM中,只有具有Id和描述值才能更新数据库表的唯一方法是从数据库中检索项目对象,设置描述然后将对象发送回数据库(因此需要两个数据库操作)只是为了一个简单的更新)或通过存储过程(这是我目前使用的方法)更新它。
答案 1 :(得分:4)
对象和数据库记录确实不是那么相似。他们有类型的插槽,你可以存储的东西,但就是这样。与编程语言相比,数据库具有完全不同的身份概念。它们无法很好地处理复合对象,因此您必须使用其他表和外键。大多数都没有类型继承的概念。并且导航对象网络的自然方式(跟随一个对象中的一些指针,获取另一个对象,再次取消引用)在映射到数据库世界时效率低得多,因为您必须进行多次往返并检索批次您不关心的数据。
换句话说:抽象不能在一开始就做得很好; ORM工具不是坏的,而是它们实现的隐喻。它不是一个完美的同构,而只是一种肤浅的相似性,所以任务本身并不是一个很好的抽象。 (尽管如此,它仍然比必须更好地理解数据库更有用。对ORM工具的蔑视主要来自DBA,只关注程序员。)
答案 2 :(得分:3)
ORM也可以编写效率不高的代码。由于数据库性能对于大多数系统而言至关重要,因此如果人类编写代码,它们可能会导致本来可以避免的问题(但如果相关人员不了解数据库性能调整,则可能没有更好的问题)。当查询变得复杂时尤其如此。
我认为我最大的问题是,通过抽象细节,初级程序员对如何编写查询的理解变得越来越少,他们需要能够处理边缘情况以及ORM写入的地方糟糕的代码。当你从未理解基础知识时,很难学习高级的东西。在了解加入和分组以及高级查询的人手中的ORM是一件好事。在不了解布尔代数和连接以及一堆其他基本SQL概念的人手中,这是一件非常糟糕的事情,导致数据库和查询的设计非常糟糕。
关系数据库不是对象,不应该被视为对象。试图将老鹰变成丝绸钱包通常是不成功的。更好地了解老鹰擅长什么,为什么让鹰飞,而不是有一个坏钱包和一只死老鹰。
答案 3 :(得分:1)
我看待它的方式是这样的。要使用ORM,您通常必须堆叠多个php函数,然后连接到数据库,并且基本上仍然运行MySQL查询或类似的东西。
为什么代码和数据库之间的所有抽象?为什么我们不能只使用我们已经知道的东西?通常,Web开发人员知道他们的后端语言,他们的db语言(某种SQL),以及某种前端语言,例如html,css,js等......
本质上,我们试图添加一个包含许多函数的抽象层(我们都知道php函数可能比分配变量慢)。是的,这是一个微观计算,但仍然,它加起来。
我们现在不仅要完成多项功能,而且我们还必须了解ORM的工作方式,因此浪费了一些时间。我认为分离代码的整个想法是让你的代码在所有级别上分开。如果你在LAMP世界,只需创建你的查询(你应该知道MySQL)并使用现有的PHP功能来准备语句。 DONE!
LAMP WAY:
ORM WAY:
其他人是否有ORM堆栈的问题?为什么我们成为这样懒惰的开发者?还是那么有创意,我们正在损害我们的代码?如果没有破坏,请不要修理它。反过来,修复您的开发团队以了解Web开发的基础知识。
答案 4 :(得分:0)
ORM正试图解决一个非常复杂的问题。丰富的边缘案例和主要的设计权衡没有明确或明显的解决方案。当您针对情况A优化ORM设计时,您本身就会因为解决情况B而感到尴尬。
有些ORM以“足够好”的方式处理延迟加载和子查询,但几乎不可能从“足够好”到“好”。
在设计ORM时,您必须很好地处理ORM将要处理的所有可能的笨拙数据库设计。你必须明确地权衡你愿意处理哪些情况。
我不认为ORM是不灵活的,或者比普通的复杂抽象更漏洞。也就是说,某些ORM在这些方面比其他ORM更好。
祝你好运重新发明轮子。