MySQL不支持原生“只写”权限,需组合方案实现:1.视图+DEFINER隔离;2.存储过程封装+EXECUTE授权(推荐);3.应用层拦截+最小权限;4.注意隐含元数据访问及TRUNCATE/DROP风险。

1. 使用视图 + DEFINER 权限隔离
创建一个无查询能力的“写入专用视图”,并用 DEFINER 方式绕过权限检查:
- 创建一个仅包含 INSERT 操作的存储过程或视图(如视图基于目标表,但不暴露 SELECT 权限)
- 用高权限账号(如 root)创建视图,并设置 SQL SECURITY DEFINER
- 授予用户 INSERT 权限到该视图(而非基表),同时 不授予 对基表的任何 SELECT/UPDATE/DELETE 权限
- 注意:MySQL 视图本身不支持 INSERT-only 限制,但配合 DEFINER + 精确授权可阻止用户直连基表
2. 基于存储过程封装写入逻辑
这是最可靠、生产常用的方式:
- 用管理员账号创建一个存储过程,例如 sp_insert_log(data VARCHAR(255)),内部执行 INSERT INTO logs VALUES (...)
- 执行:GRANT EXECUTE ON PROCEDURE db_name.sp_insert_log TO 'user_mysql'@'%';
- 确保 不授予 user_mysql 对 logs 表的任何直接权限(包括 SELECT)
- 用户只能调用该过程写入,无法查看、修改或删除数据
3. 应用层强制拦截 + 数据库最小权限
数据库侧只放行 INSERT,应用代码负责逻辑兜底:
系统特色及功能简介,主要包括以下方面: 合一:包括语言、模板风格、用户群;此版本内订简体、繁体、英文于一体;可另增设其它语言选项;模板风格指可以存在多界面的情况下进行界面互换;用户群指可写于单用户版本,也可用于多用户商城版本,具体设置可通过会员组权限修改 会员组定制:系统初安装时,内订6级会员分组,即 游客组、管理员组、VIP用户组、柜台用户组、柜台VIP用户组;此6级会员组不可以删除。另管理
- 执行:GRANT INSERT ON db_name.table_name TO 'user_mysql'@'%'; FLUSH PRIVILEGES;
- 明确撤销其他权限:REVOKE SELECT, UPDATE, DELETE, DROP, ALTER ON db_name.table_name FROM 'user_mysql'@'%';
- 在应用中禁用所有 SELECT/UPDATE/DELETE 相关 SQL 拼装逻辑,只保留 INSERT
- 配合审计日志(general_log 或 audit plugin)监控异常语句
4. 注意事项与常见误区
避免踩坑:
- INSERT 权限隐含部分元数据访问:用户仍可能通过 INFORMATION_SCHEMA 查到表结构(但看不到数据),属 MySQL 设计限制
- 不能防止 TRUNCATE 或 DROP:需额外 REVOKE DROP、ALTER、CREATE 权限,否则用户可能清空或重建表
- 代理用户或角色管理更清晰:MySQL 8.0+ 支持 roles,可创建 role_write_only,再将 role_assign 给 user_mysql,便于批量维护
- 测试验证命令:SHOW GRANTS FOR 'user_mysql'@'%'; 确保输出里只有 INSERT 和必要 USAGE 权限









