ORM 教会我的事:学好 SQL 就够了 (2014)
What ORMs have taught me: just learn SQL (2014)

原始链接: https://wozniak.ca/blog/2014/08/03/1/index.html

作者认为,对象关系映射器(ORM)往往会加剧性能和架构问题,特别是“属性蔓延”和过度对象膨胀。 随着数据库表增长到包含数百个属性,ORM(通常默认获取整个实体)的表现就像 `SELECT *` 查询一样,迫使系统浪费资源将庞大的行数据转换为对象。外键的“有害”使用进一步加剧了这一问题,可能引发非预期的深层关联查询,从而严重拖累性能。 作者指出,虽然可以通过复杂的投影和精细的配置来缓解这些问题,但这些“修复”方案需要开发者对底层 SQL 有深刻的理解。最终,作者认为由于 ORM 并未真正实现数据库抽象,开发者直接使用 SQL 会更好。这样不仅绕过了代码到查询的转换开销,还省去了学习 ORM 数据映射机制(这些机制往往晦涩难懂)的必要。

这篇 Hacker News 讨论反映了关于对象关系映射(ORM)与原生 SQL 之间长期存在的争论。 ORM 的支持者认为,通过类型安全、IDE 自动补全和简化的模式管理,ORM 提供了更出色的开发体验。许多人强调 ORM 与 SQL 并非互斥;开发者可以使用 ORM 处理标准 CRUD 操作,同时将复杂的查询或性能关键型任务留给原生 SQL。 相反,批评者认为 ORM 制造了一种“泄漏的抽象”,强迫开发者为了调试 N+1 问题或低效查询生成等问题,仍必须理解 SQL。许多参与者视 SQL 为一项关键的基础技能,并指出 ORM 往往难以处理大规模数据处理(OLAP),将 SQL 视为“二等公民”会导致可维护性问题。 归根结底,共识倾向于务实的方法:虽然 ORM 可以作为简化样板代码和处理基本数据库交互的有效工具,但它们无法替代对 SQL 的深入了解。开发者必须具备编写原生查询的能力,以优化性能并处理 ORM 难以胜任的专业工作负载。
相关文章

原文

Perhaps the most subversive issue I’ve had with ORMs is “attribute creep” or “wide tables”, that is, tables that just keep accruing attributes. As much as I’d like to avoid it, sometimes it becomes necessary (although things like Postgres’ hstore can help). For example, a client may be providing you with lots of data that they want attached to reports based on various business logic. Furthermore, you don’t have much insight into this data; you’re just schlepping it around.

This in and of itself isn’t a terrible thing in a database. It becomes a real pain point with an ORM. Specifically, the problem starts to show up in any query that uses the entity directly to create the query. You may have a Hibernate query like so early on in the project.

query(Foo.class).add(Restriction.eq("x", value))

This may be fine when Foo has five attributes, but becomes a data fire hose when it has a hundred. This is the equivalent of using SELECT *, which is usually saying more than what is intended. ORMs, however, encourage this use and often make writing precise projections as tedious as they are in SQL. (I have optimized such queries by adding the appropriate projection and reduced the run time from minutes to seconds; all the time was spent translating the database row into a Java object.)

Which leads to another bad experience: the pernicious use of foreign keys. In the ORMs I’ve used, links between classes are represented in the data model as foreign keys which, if not configured carefully, result in a large number of joins when retrieving the object. (A recent count of one such table in my work resulted in over 600 attributes and 14 joins to access a single object, using the preferred query methodology.)

Attribute creep and excessive use of foreign keys shows me is that in order to use ORMs effectively, you still need to know SQL. My contention with ORMs is that, if you need to know SQL, just use SQL since it prevents the need to know how non-SQL gets translated to SQL.

联系我们 contact @ memedata.com