求求了,别再在应用中使用 Stored Procedures

We need to stop using Stored Procedures

作为一名开发者,我恳请大家停止在应用代码中依赖 Stored Procedures。这并非为了否定数据库管理员的价值,而是为了将数据库访问逻辑与应用逻辑统一版本控制,避免部署时的噩梦。通过直接使用参数化查询,我们既能获得查询计划缓存和参数化带来的性能优势,又能确保代码的可维护性与回滚能力。文章还深入探讨了如何优化网络请求、合理使用 Indexes、警惕 ORM 中的 N+1 问题以及避免 Cartesian Explosions。让我们重新掌握 SQL 的主动权,与 DBA 协作而非对抗,共同构建更健壮的数据库交互模式。

应用开发者和数据库管理员,我恳求你们:停止使用 Stored Procedures 作为弥补应用开发者不足的权宜之计,转而引导开发者掌握 SQL、索引、查询计划、事务、隔离级别、参数化查询、参数嗅探、Sargability、性能分析、书签查找、模式设计、范式、反范式、基数、B(+)-树、WAL 以及 CPU/Log IO/Data IO 的圣三位一体等核心知识。
  1. saxenaabhi

    这篇文章写得非常糟糕,基本事实都错了。

    > 那么存储过程能给我们带来什么?

    > 什么都给不了!好吧,我的意思是,除了头疼。

    > ……我们不得不部署迁移脚本来更新查询,还得运行 diff migration_for_my_sproc migration_for_my_sproc_n 来查看变化。

    1) 你可以在代码仓库中版本化管理 SQL 函数,并随数据库迁移一起部署 SQL 函数(甚至可以在同一个事务中完成)。

    每个 SQL 函数单独一个文件,如果你像我一样有 600 个存储过程,还可以计算校验和来加速。

    2) 使用存储过程时,执行多条语句时无需在服务器端调用 db.startTransaction,也不必等待数据库往返。这往往是大家偏爱存储过程的最大原因。

    3) 我在医疗和金融领域见过这样的系统:不同团队无法访问底层表,数据库只暴露 SQL 存储过程。每次调用存储过程时,还会在审计表中添加一条日志记录。

    数据库是一项很棒的技术!学会正确使用它,能为业务价值创造带来巨大回报。

    编辑:文章没提到,但人们常提到存储过程的测试难题。

    你可以用正常的 vitest 测试,配合内存版的 pglite 来测试你的 postgres 函数。

  2. JeffRosenberg

    > 我们的应用代码和数据库访问是分开版本控制的,我们的存储过程可能会在不知情的情况下被那些行为异常(即极其罕见、疯狂)的 DBA 修改。

    你的数据库(及其迁移脚本)应该和其余代码一样纳入版本控制。问题解决了,现在你可以充分利用存储过程的一些真正优势了!

  3. noddingham

    (在我们的本地 SQL Server 环境中)我们将存储过程像 API 契约一样暴露给 Web 开发者,以确保他们与数据库交互时具备一定的一致性和健壮性。我们发现如今 Web 开发者的 SQL 知识参差不齐,我宁愿让 DBA 来设计模式并提供存储过程。

同日更多故事

2026-09-20