gam2046
2022-06-25 03:31:02 +08:00
复杂的数据库请求,手写 SQL 基本很难避免,各个语言的 ORM 对于简单的查询支持都没问题,比如单表查询,简单的多表查询,但是一旦复杂起来,ORM 生成的 SQL 通常只是能用,但执行效率很一般。
另外就是一些关于数据库相关的特殊语法,ORM 支持程度也很有限。以我常用的 postgresql 为例,如果需要跨数据库查询,甚至需要使用 join 语句进行 update ,ORM 都无法完成,需要使用许多代码,先进行查询,数据送到应用程序内,再通过游标逐条判断进行 update 。而这些对于现代的数据库,基本上都提供了原生的支持。还是以我常用的 postgresql 为例,上面的需求只需要这样的一句 SQL 即可完成。
with t as (
select t1.identifier as tid,t2.created_at
from table_devices t1 left join dblink('self','select identifier,created_at from table_devices')
as t2(identifier text,created_at timestamp)
on t1.identifier = t2.identifier
)
update table_devices
set created_at = t.created_at
from t
where identifier=t.tid and t.created_at is not null
就我个人而言,ORM 的主要用途是提供了数据库表到编程语言的类( golang 中的 struct )以及数据类型的对应关系。如果不是单表操作,我更倾向于手写 SQL 。
至于 ORM 支持不同数据库之间的水平迁移,本身就是个伪需求,实际生产中,几乎不会出现底层数据库的切换。如果真的发生,本身就需要细致的测试。简单的 select/join 这种操作,原本就是所有关系型数据库都支持,并不需要 ORM 。而带有数据库特色的语法,多数 ORM 也根本就不支持,这些功能就是手写的。