INDEX权限仅允许执行CREATE INDEX和DROP INDEX,不包含ALTER TABLE ADD INDEX(需ALTER权限);它纯属索引层面操作,不涉及表结构修改或数据访问,授予时须限定库或表级作用域。

MySQL中index权限到底控制什么
「index」权限只允许用户执行 CREATE INDEX 和 DROP INDEX,不包含 ALTER TABLE ... ADD INDEX(后者需要 ALTER 权限)。很多人误以为开了 index 就能随意加删索引,结果发现 ALTER TABLE t1 ADD INDEX idx_name(col) 报错 ERROR 1045 (28000): Access denied for user...,就是因为缺 ALTER 权限。
-
INDEX权限本身不赋予建表、改表结构或查询数据的能力,它纯粹是索引层面的开关 - 授予
INDEX时必须配合具体作用域:库级(db_name.*)、表级(db_name.table_name),不能只给全局*.*却期望限制到某张表 - 如果用户已有
ALTER权限,再单独授INDEX没实际意义——ALTER已隐含INDEX能力
如何精确授予创建索引权限(不带ALTER)
想让用户只能建/删索引,不能改字段、删表、清数据,就得拆开授权。例如只允许用户 dev_user 在 app_db.users 表上操作索引:
GRANT INDEX ON app_db.users TO 'dev_user'@'192.168.1.%';
注意三点:
- 不能写成
GRANT INDEX ON app_db.*—— 这会让用户能在整个库所有表上建索引,超出最小权限原则 - 执行后必须
FLUSH PRIVILEGES;,否则权限不生效(尤其在非 root 用户下修改后) - 若用户此前没有
SELECT权限,即使有INDEX,执行SHOW CREATE TABLE users查看现有索引也会被拒绝——索引操作虽不读数据,但元信息访问仍需基础权限
为什么revoke index后还能alter table加索引
常见现象:执行了 REVOKE INDEX ON app_db.users FROM 'dev_user'@'%';,但用户仍能用 ALTER TABLE users ADD INDEX ... 成功。这是因为:
-
ALTER权限本身就覆盖了索引变更行为,INDEX是它的子集 -
REVOKE INDEX不会自动撤销ALTER,必须显式REVOKE ALTER ON app_db.users FROM ... - 检查当前实际权限用
SHOW GRANTS FOR 'dev_user'@'%';,别只信自己“记得” revoke 过什么
生产环境该不该单独开放INDEX权限
绝大多数场景下,不建议单独开放 INDEX 权限。原因很实在:
- 索引不是孤立操作:建错索引会导致查询变慢、写入锁表、磁盘爆满,影响远超单条 SQL
- DBA 通常通过 SQL 审核平台统一管控 DDL,而不是靠数据库原生权限卡住——权限太细反而绕过审核
- 真正需要频繁调优索引的,往往是 DBA 或后端资深开发,他们本就该有
ALTER;普通开发连EXPLAIN都跑不熟,给INDEX只会增加误操作风险
真要放开,优先走审批+SQL工单流程,而不是在 mysql.user 表里反复 GRANT/REVOKE —— 权限粒度越细,越容易漏掉依赖项或忘记回收。


















