MySQL Bug #11472 终于修了。这个 Bug 是 2005 年 6 月提交的,挂了 21 年,够离谱吧?问题本身其实很好理解:父表 DELETE / UPDATE 触发外键 CASCADE,子表数据会被删掉或更新,但子表上的 trigger 不会执行。也就是说,数据动了,触发器没动。这就很坑。你如果用 trigger 记审计日志、同步缓存、维护反规范化字段,或者顺手挂了一点业务逻辑,那这条级联链路上就可能直接漏掉。不是订单没删。订单确实被级联删了。真正丢的是审计日志、缓存刷新、衍生字段更新这些副作用。这种问题最恶心的地方是,它不报错。它只是安安静静地跳过去,然后等你线上排查的时候再给你补一刀。这个场景在国内互联网业务开发里其实很少见。很多团队本来就不用数据库外键,更不会依赖 ON DELETE CASCADE + trigger 做核心业务逻辑。MySQL 9.7 这次终于补上了,引入 enable_cascade_triggers,允许 SQL 层外键级联时触发子表 trigger。不过默认还是关闭,而且要在 SQL-layer foreign key handling 生效时才有用。很 MySQL。不是不能修,是修得慢;不是不给能力,是先默认关着;不是没有历史包袱,是历史包袱真的不少。不过也别因为这个 Bug 就把 MySQL 贬得一无是处。MySQL 这二十多年能被这么多公司用下来,是因为它够简单,够稳,资料够多,出了问题也容易搜到前人踩过的坑。很多传统业务,说白了就是用户表、订单表、配置表、流水表这些东西,用 MySQL 真没什么毛病。但要说这几年的新鲜感,MySQL 确实弱了一点。现在做新项目,尤其是碰到 AI、向量检索、数据分析、地理信息这些场景,很多人第一反应已经不是 MySQL 了,而是 PostgreSQL。pgvector、PostGIS、TimescaleDB 这些扩展摆在那儿,能少接一个中间件,就少接一个中间件。这就是 PostgreSQL 现在最吃香的地方。它不像一个单纯的关系型数据库,更像一个可以不断往上挂能力的底座。项目刚开始可能只是存业务数据,后面要加向量、时序、全文检索、GIS,也不用一上来就把技术栈拆得七零八落。所以 MySQL 和 PostgreSQL 真没必要搞成互喷。MySQL 依然很能打,存量系统太多,中小型 CRUD 项目也完全够用。但 PostgreSQL 这几年确实在猛猛往前冲,而且冲的方向刚好踩在 AI 和复杂数据应用的节奏上。以前大家调侃,PostgreSQL 靠 MySQL 刷存在感。现在反过来了,很多时候是 MySQL 靠 PostgreSQL 刷存在感。