<p>MySQL 8.0+ 不支持创建数据库后自动将权限授予角色。CREATE DATABASE 不触发权限分配,通配符授权 ON . 不覆盖新建库,必须显式执行 GRANT ON new_db.* 并确保角色存在、用户绑定及默认角色设置。</p>

MySQL 8.0+ 没有“自动赋予新库给角色”的原生机制
直接回答:MySQL 不支持创建数据库后自动把权限授予某个角色。CREATE DATABASE 语句本身不触发任何权限分配逻辑,也不会调用钩子或事件来联动 GRANT。所谓“自动”,必须靠外部逻辑补位——要么人工干预,要么用脚本/运维流程兜底。
为什么不能依赖 ON *.* 或通配符实现“自动覆盖”
GRANT SELECT ON *.* TO 'dev_role' 看似能覆盖所有库,但实际只作用于执行时已存在的数据库,后续新建的库完全不包含在内。更关键的是:* 不是正则,也不匹配未来创建的库名;而且它明确排除系统库(mysql、information_schema 等),哪怕你显式写 GRANT ALL ON mysql.*,MySQL 也会静默拒绝部分操作。
- 新建库后,
dev_role对该库没有任何权限,哪怕只执行SHOW TABLES都会报ERROR 1142 (42000): SELECT command denied -
GRANT ... ON `new_db`.* TO 'dev_role'必须显式执行,且需确保角色存在、语法正确、host 匹配(如角色定义为'dev_role'@'%',则授权也得带 host) - 如果用
GRANT ALL ON *.*,还可能意外开放对测试库、临时库甚至残留库的访问,违背最小权限原则
可行的实操方案:用脚本 + 权限模板兜底
真正落地的做法是把“建库 → 授权”变成原子化动作,避免人肉遗漏。核心是把角色权限当成模板复用,而不是指望 MySQL 自动识别新库。
- 每次创建新库前,先确认角色已存在:
CREATE ROLE IF NOT EXISTS 'dev_role'(注意:MySQL 8.0.16+ 才支持IF NOT EXISTS,旧版需先查mysql.role_edges) - 建库后立即执行标准授权语句:
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX, CREATE VIEW, SHOW VIEW, EXECUTE ON `new_db`.* TO 'dev_role' - 若团队使用 CI/CD 或 DBA 工具链,可将上述两步封装成 SQL 模板或 Python 脚本,输入库名后自动生成并执行完整命令
- 禁止在生产环境用
GRANT ... ON *.*替代,它无法解决“新库无权限”问题,反而埋下越权隐患
容易被忽略的关键点:角色激活与用户绑定必须分离处理
即使你把权限成功授给了 dev_role,开发人员登录后依然看不到新库——因为角色默认不激活,且用户未必绑定了该角色。
- 用户首次登录前,必须已完成:
GRANT 'dev_role' TO 'dev_user'@'192.168.50.%'和SET DEFAULT ROLE 'dev_role' TO 'dev_user'@'192.168.50.%' - 如果用户已存在,只补授权不够,必须补
GRANT ... TO和SET DEFAULT ROLE两步,缺一不可 - 验证是否生效,不要只查
SHOW GRANTS FOR 'dev_role',而要用目标用户连接后执行SELECT CURRENT_ROLE()和SHOW DATABASES
实际中,最常出问题的不是建库,而是建库之后忘了跑授权脚本,或者误以为角色绑定了就万事大吉。权限生效链条比想象中长:角色存在 → 角色有对应库权限 → 用户被授予该角色 → 用户设置了默认角色 → 用户登录后角色被激活。漏掉任意一环,开发就会卡在“看不见库”。


















