<p> 创建只读用户应直接授 SELECT 权限:CREATE USER ‘ro_user’@’%’ IDENTIFIED BY ‘strong_pass’; GRANT SELECT ON mydb.* TO ‘ro_user’@’%’; FLUSH PRIVILEGES; 避免先授全权再回收。</p>

MySQL 怎么创建只读用户(不给 DROP、DELETE、UPDATE 权限)
直接建用户 + 显式授权比“先授全权再回收”更可靠,MySQL 不支持 REVOKE 所有权限后再加回部分,容易漏掉隐式权限。只给 SELECT 是最干净的起点。
- 用
CREATE USER 'ro_user'@'%' IDENTIFIED BY 'strong_pass';创建用户,别用空密码或通配 host(如'ro_user'@'localhost'更安全) - 只执行
GRANT SELECT ON mydb.* TO 'ro_user'@'%';,不要加GRANT OPTION,否则用户能转授权限 - 执行
FLUSH PRIVILEGES;生效(仅在修改mysql.user表直改时才必须;用GRANT通常自动刷新)
PostgreSQL 中 REVOKE DELETE 为什么没用?
PostgreSQL 默认给 PUBLIC 组赋予了表的 SELECT 权限,但 DELETE 等写权限不会自动继承——所以问题往往出在用户属于某个有写权限的角色,或者你忘了撤掉表级权限之外的 schema 级权限。
- 检查用户实际拥有的角色:
SELECT rolname FROM pg_roles WHERE oid IN (SELECT member FROM pg_auth_members WHERE roleid = (SELECT oid FROM pg_roles WHERE rolname = 'your_user')); - 撤销指定表的写权限:
REVOKE INSERT, UPDATE, DELETE ON TABLE orders FROM ro_user; - 更重要的是:确认没给过
ro_user对整个 schema 的USAGE+SELECT以外的权限,比如REVOKE ALL ON SCHEMA public FROM ro_user;再重授USAGE和SELECT
SQL Server 设置只读用户后仍能删数据?查 db_datawriter 角色
SQL Server 的数据库角色是“开关式”权限容器,db_datawriter 会直接覆盖你手动 DENY DELETE 的效果——只要用户在该角色里,DENY 就无效。
- 运行
EXEC sp_helpuser 'ro_user';查看用户所属角色 - 如果输出里含
db_datawriter,立刻执行ALTER ROLE db_datawriter DROP MEMBER ro_user; - 别依赖
DENY DELETE ON OBJECT::mytable做主要防护,它优先级低于角色授予的权限,仅作兜底 - 生产环境建议用最小权限原则:新建自定义角色,只
GRANT SELECT,再把用户加进去
Oracle 的 READ ONLY 用户需要额外关掉 UNLIMITED TABLESPACE
Oracle 里光禁写操作不够,用户若拥有 UNLIMITED TABLESPACE 系统权限,就能建临时表、物化视图甚至通过 INSERT /*+ APPEND */ 绕过某些限制——这不是 bug,是设计如此。
- 检查权限:
SELECT * FROM DBA_SYS_PRIVS WHERE GRANTEE = 'RO_USER' AND PRIVILEGE LIKE '%TABLESPACE%'; - 收回权限:
REVOKE UNLIMITED TABLESPACE FROM ro_user; - 如果用户真需要临时段(比如大查询排序),改用
QUOTA 1M ON users;限定空间,而不是放开无限 - 注意:Oracle 12c+ 支持
CREATE USER …… DEFAULT TABLESPACE users READ ONLY;,但该READ ONLY仅控制表空间可写性,不等于用户只读,别混淆
权限模型差异太大,跨数据库照搬语句大概率失效;最稳的方式永远是:建新用户 → 只赋 SELECT → 验证连接和查询 → 再用真实业务 SQL 测一遍删 / 改是否真被拒。