为何数据库优先ORM模型在Go社区受到欢迎? - Reddit


数据库优先ORM模型(db first ORM)的定义:根据数据库自动生成代码,而不是根据代码生成数据库表,如 sqlc、sqlBoiler;
另外一种ORM模型是:根据代码自动生成数据库表,这种称为代码优先ORM模型(code first ORM模型),如GORM、sqlx和sql helper。

为什么现在数据库优先ORM模型在Go社区中越来越受欢迎?
使用ORM的全部意义在于帮助分离关系数据库和数据模型,并且在构建业务逻辑时不再担心基于sql的关系。
虽然数据库优先ORM模型在某种程度上也可以实现了这一点,但开发人员对生成的数据模型却没有任何控制。这就使得数据模型与生成的代码紧密耦合在一起,最终迫使建立独立的应用模型,似乎并没有真正帮助提高生产力,而这正是使用ORM的全部意义。

但是,代码优先ORM模型虽然也会污染领域模型,但程度要比数据库优先ORM模型小得多。
而且,即使需要切换到其他ORM或者甚至是原始的sql,也不需要太多的额外工作。

数据库优先ORM模型与代码优先ORM模型的优势?


网友讨论:
1. 我喜欢 Go 的主要原因之一是编译时的类型安全。当你开始手写SQL的时候,这一点就完全消失了。这让人筋疲力尽。
我曾经用sqlx这样的代码优先ORM模型完成过整个大型项目,尽管这比标准的lib方式要好得多,但你最终不得不重新发明轮子,或者做一些奇怪的黑客来一次插入多条记录,特别是对于更复杂的关系。这样一来,你就失去了整个代码库与数据库交互方式的一致性。

也许这只是我的看法,但我觉得一个可靠的ORM所具有的一致性、类型安全和整体测试量使得任何缺点都是微不足道的,特别是在一个大型的代码库中。由于性能的原因,能够编写自定义的sql,这也抵消了一些关于这方面的担忧。

数据库是我们大多数人所做事情的基础。我们写的代码只是它上面的肉汁。如果数据库包含了我们可能关心的所有数据的超级集合,那么为什么不倚重这一事实,并使用一个以一致的、经过测试的方式与之交互的库。

我觉得很多人不喜欢 "魔力",或者被ORM中表现糟糕的查询所咬过。但我不知道能够为特定的情况写一个一次性的查询,怎么就不能解决这个问题。


2. 假设使用 ORM 的全部目的是帮助分离关系数据库模型,并在构建业务逻辑时不再担心基于 sql 的关系?
这是个糟糕的目标:你不能停止担心基于sql的关系,它们是大多数服务性能的主要驱动因素。我花了一年多的时间在一家大公司拥有一个大型的、老旧的、被滥用的postgres数据库,我无法告诉你使用活动记录的人有多频繁地引入N+1查询(根据他们与记录的关系找到一个id列表,然后使用for循环单独查询每个记录),因为他们忘记了在他们完全普通的for循环的另一边有一个数据库。我无法告诉你这对数据库的性能来说是多么的糟糕。

每当你看到一个 "无代码 "产品的广告,承诺PM和高管将能够从头开始构建整个产品,而不必与那些讨厌的工程师打交道时,你无疑会翻白眼。ORMs是数据库的无代码产品。不过,它们更糟糕,因为在我看来,对于PM来说,试图在不花25万买工程师或花5年时间学习代码的情况下完成更多工作是完全合法的。你是一个工程师!你是一个工程师。正确使用数据库的能力完全在你的掌握之中!

所以,现在你有很多人因为某种原因想要一个ORM,但也许已经认识到忽视被运行的SQL是一个问题,所以现在你有了db-first ORM(数据库优先ORM模型)解决方案。也许到时候,我们还可以把ORM完全干掉。


3. Java 和 Go 之类的语言并非旨在为数据库表建模。胡乱制作模型以便它们生成正确的表和高级查询并不有趣。
关于 ORM,我最喜欢的一点是它们使基本的数据库操作变得容易。CRUD 已经有了一个强类型函数。
DB-First ORM 提供了后者的好处,而没有前者的成本。大多数样板是自动生成的,所有非样板我可以按照自己的意愿去做。
编写用于创建表的 SQL,只是想不为简单的crud编写SQL而已。


4. banq:DDD领域模型 != ORM中领域模型或数据模型,很多ORM大咖在ORM教程中往往把与数据库表映射对应的数据模型称为领域模型,这实际是错误误导,因为领域模型不能依赖于数据库等基础设施技术,明白这个道理后,不如将ORM中数据对象模型或称为实体模型与DDD的实体模型或聚合模型等领域模型区别开来,各搞一套。这样,简单的系统就无需DDD领域模型,系统复杂起来,就专门建立领域层,将ORM实体数据模型驱赶降级到基础设施等DAO或持久层或DDD存储库Repository中,ORM 应该严格限制在 CRUD 中。