MySQL 8.0原生支持跨库联合查询,但需确保对每个涉及数据库显式授予SELECT权限、主机名严格匹配、库表名含特殊字符时用反引号包裹,且连接池需重启以生效新权限。
MySQL 8.0 原生支持跨库联合查询,不需要额外插件或配置开关,只要权限给对、语法写对,SELECT 就能跑通。关键不是“开启功能”,而是避免权限漏授、主机名不匹配、反引号缺失这些硬性拦路虎。
SELECT FROM db1.t1 JOIN db2.t2 报 ERROR 1142?这不是语法错误,是权限校验失败。MySQL 对每个库的 SELECT 权限单独检查,哪怕你对 db1 有全权,没给 db2 授过 SELECT,JOIN 就会卡在第二张表上。
SHOW GRANTS FOR CURRENT_USER; 必须输出至少两行 GRANT SELECT ON `db1`.* 和 GRANT SELECT ON `db2`.*,缺一不可'app'@'10.20.30.40',但你只给了 'app'@'%' —— 这俩权限不互通,必须严格匹配 Hostmy-app)却没用反引号包裹:GRANT SELECT ON my-app.* 会报错 ERROR 1144,正确写法是 GRANT SELECT ON `my-app`.*
GRANT 语句怎么写才安全有效?别碰 mysql.db 表,也别用 GRANT ALL ON *.* 图省事。生产环境必须显式、分库授权,且每条命令独立执行。
GRANT SELECT ON `db_name`.* TO 'user'@'host';,例如:GRANT SELECT ON `orders`.* TO 'reporter'@'%';
FLUSH PRIVILEGES;,尤其在非 root 用户下修改后,这是最稳妥的做法别依赖 USE db1; 后省略库名,也别指望 MySQL 自动推断上下文。所有跨库引用必须显式、完整、带反引号(如有必要)。
SELECT u.name, o.amount FROM `users_db`.`users` u JOIN `orders_db`.`orders` o ON u.id = o.user_id;
SELECT * FROM users JOIN orders_db.orders —— users 没带库前缀,MySQL 会去当前 USE 的库找,容易错表`users_db.users` —— 反引号必须分别包住库名和表名,`users_db`.`users` 才合法utf8mb4_0900_as_cs,另一个用 utf8mb4_general_ci)会导致 JOIN 字段隐式转换,索引失效最容易被忽略的是:权限生效不看配置文件改没改,而看 SHOW GRANTS 输出是否真实包含所有目标库;另外,跨库 SELECT 虽然没问题,但只要混进 UPDATE 或 INSERT,事务就无法跨库回滚——这得靠应用层自己兜底。