应授予 CREATE, ALTER, DROP, INDEX, CREATE VIEW, SHOW VIEW ON test_db.*,因MySQL无纯DDL权限,需显式组合;反引号防库名解析错误;INDEX独立于CREATE;FLUSH PRIVILEGES非必需;DROP权限不能删库但可TRUNCATE表。

只给 test_db 库的 DDL 权限,不碰其他库
MySQL 默认不支持“仅 DDL”粒度的权限控制,ALTER、CREATE、DROP 等权限都属于对象级(库或表),必须配合 GRANT 显式指定作用域。直接 GRANT ALL ON *.* 是最常见误操作,会意外开放生产库风险。
正确做法是:先确保开发人员账号已存在(如 'dev_user'@'%' ),再对目标库单独授权:
GRANT CREATE, ALTER, DROP, INDEX, CREATE VIEW, SHOW VIEW ON `test_db`.* TO 'dev_user'@'%';
注意反引号包裹库名——如果库名含短横线或大小写,不加反引号会导致语法错误;SHOW VIEW 虽属 DML 衍生,但建视图时必需,漏掉会报 ERROR 1142 (42000): CREATE VIEW command denied。
为什么不能只给 CREATE 不给 INDEX?
开发在测试库跑 ORM 迁移(如 Django migrate 或 Laravel php artisan migrate)时,常自动创建索引。MySQL 把 CREATE INDEX 视为独立权限,和 CREATE TABLE 分离。只授 CREATE 会导致迁移卡在建索引步骤,报错:
ERROR 1142 (42000): INDEX command denied to user 'dev_user'@'10.0.1.5' for table 'users'
-
CREATE允许建库/表/视图/存储过程 -
INDEX单独控制CREATE INDEX/DROP INDEX -
ALTER必须包含,否则无法改表结构(加字段、改类型等)
执行后记得 FLUSH PRIVILEGES 吗?
不需要。MySQL 8.0+ 使用数据字典持久化权限,GRANT 语句本身即生效;5.7 及更早版本也仅在内存中更新权限表,FLUSH PRIVILEGES 仅在手动修改 mysql.user 等系统表后才需调用。盲目执行反而可能触发锁或短暂权限抖动。
验证是否生效,让开发连上后执行:
MySQL 数据库管理技能,能够通过自然语言查询和管理数据库,支持 SELECT/INSERT/UPDATE/DELETE、表管理、备份恢复等操作。当用户提及 MySQL、数据库查询、建表或数据备份时使用此技能。
SHOW GRANTS FOR 'dev_user'@'%';
确认输出中明确出现 ON `test_db`.*,且不含 ON *.* 或其他库名。
DDL 权限不等于能删库,但要防误操作
DROP 权限允许删表、删视图、删存储过程,但**不能删库**——删库需要 DROP on *.* 或显式 GRANT DROP ON `test_db`.*(MySQL 会拒绝该语法,强制要求全局)。所以只要没授 GRANT DROP ON *.*,DROP DATABASE test_db 永远失败。
但仍有风险点:
- 开发可能用
TRUNCATE TABLE清空数据(无需额外权限,只要有DROP就能执行) - 若测试库启用了
innodb_file_per_table=OFF,反复建删大表可能碎片化共享表空间,影响后续性能 - 权限未限制 IP 段时,
'dev_user'@'%'可从任意地址连接,建议收紧为'dev_user'@'192.168.10.%'
真正难控的不是权限本身,而是开发在 test_db 里建了同名表覆盖已有结构,或用 ALTER TABLE ... ENGINE=InnoDB ROW_FORMAT=COMPRESSED 引入不兼容参数——这类操作不会报错,但上线前容易被忽略。










