MySQL 8.0.16起才真正支持列级授权,5.7及更早版本仅语法兼容但无效;必须用GRANT ... ON db.tbl(col)显式指定列名,不支持通配符,且权限检查以最严格为准。
MySQL 8.0+ 才支持真正的列级授权
MySQL 5.7 及更早版本不支持对单列执行
;所谓“列权限”只是语法上允许写,实际授权后仍无法生效——连接后执行对应列的
会直接报
。只有 MySQL 8.0.16 起才真正实现列级权限检查,且必须用
显式指定列名。
常见错误现象:
在 5.7 上能执行成功,但
登录后
依然被拒绝。
确认版本:运行
,低于
的别折腾列授权
列名必须明确列出,不支持通配符(如
或
)
同一用户对同一张表可混合授予不同列的权限,例如:先授
,再授
GRANT 语句里列名写错位置就完全失效
列权限只能在
子句中、紧跟表名后用括号声明,不能放在
动词后面,也不能塞进引号或变量里。写成
是合法的;但
或
(反引号包表名但漏了列括号)都会被 MySQL 当作语法错误或降级为表级授权。
正确格式:
错误示例:
→ 报错
错误示例:
→ 单引号导致列名被当字符串字面量,权限不生效
注意大小写:列名区分大小写(取决于
设置,但列名本身按定义时的大小写匹配)
列权限和表权限叠加时,以“最严格”为准
如果一个用户既被授予了整张表的
权限,又被单独授予某几列的
权限,MySQL 不会合并——它只认“最小交集”。比如:用户有
(全表),又额外被收回
,那
列仍然不可查;反过来,如果只给了
,没给表级权限,那哪怕
里包含
,只要语句里出现其他列,整个查询就失败。
MySQL(Linux)
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
下载
✅(只查被授权列)
❌(
未授权,整条语句拒绝)
❌(即使其中一列被授权,
展开后含未授权列)
撤销列权限用
,不是
或
SHOW GRANTS 看不到列权限细节,得查系统表
默认只显示表级权限,哪怕你确实授过列权限,输出里也不会出现括号列名——容易误以为没生效。真实授权信息存在
表里,需手动查:
注意:
表权限是行级缓存的,修改后要执行
才能立即生效(虽然多数情况下自动重载,但遇到权限不生效,先刷一下)。
容易被忽略的是:列权限不会出现在
中,也不受角色(ROLE)的间接继承影响——MySQL 目前不支持把列权限赋予 ROLE 再分配给用户。
GRANTSELECTERROR 1142 (42000): SELECT command deniedGRANT ... ON database.table(column_name)GRANT SELECT (name) ON test.users TO 'u1'@'%';u1SELECT name FROM test.usersSELECT VERSION();8.0.16(*)(name, *)SELECT (id, name)UPDATE (email)ONGRANTGRANT SELECT(name) ON test.usersGRANT SELECT ON test.users(name)GRANT SELECT (name) ON test.`users`GRANT SELECT (id, email) ON mydb.t1 TO 'u2'@'localhost';GRANT SELECT ON mydb.t1(id)ERROR 1064 (42000)GRANT SELECT ('name') ON mydb.t1lower_case_table_namesSELECTSELECTSELECT ON test.t1SELECT (ssn) ON test.t1ssnSELECT (name)SELECT *nameSELECT name FROM t1SELECT name, email FROM t1emailSELECT * FROM t1*REVOKE SELECT (ssn) ON db.tbl FROM 'u'@'%';DROPDELETESHOW GRANTS FOR 'u'@'%'mysql.columns_privSELECT User, Host, Db, Table_name, Column_name, Select_priv
FROM mysql.columns_priv
WHERE User = 'u1' AND Db = 'test' AND Table_name = 'users';columns_privFLUSH PRIVILEGES;INFORMATION_SCHEMA.ROLE_TABLE_GRANTS