真正安全的mysql表级只读账号必须手动执行grant select on mydb.sales_summary to 'reporter'@'203.0.113.45',显式revoke所有写权限,并执行flush privileges;host字段指定客户端ip而非服务器ip,严禁用'%',需精确到表、ip和操作类型。

Navicat 本身不拦截 SQL 执行,界面里勾选“只读连接”或设为 Team Viewer 角色,对数据库真实读写权限毫无约束力。真正安全的跨部门只读共享,必须由后端数据库账号权限控制,且需精确到表、IP 和操作类型。
MySQL 表级只读账号必须手动执行 GRANT
Navicat 的「新建用户」向导只支持库级授权(如 mydb.*),无法指定单表或限制 IP 段,容易误开整库 SELECT 权限。要实现真正安全的只读,必须在 Navicat 查询窗口中手动执行 SQL:
-
GRANT SELECT ON mydb.sales_summary TO 'reporter'@'203.0.113.45'—— 精确到单表 + 合作方固定出口 IP -
REVOKE INSERT, UPDATE, DELETE, DROP, CREATE, ALTER ON mydb.* FROM 'reporter'@'203.0.113.45'—— 显式拒绝所有写类权限,避免隐式继承 -
FLUSH PRIVILEGES—— MySQL 8.0.29 之前版本必须执行,否则权限不生效
host 字段填的是客户端来源 IP,不是数据库服务器地址
很多人把 host 字段误解为数据库所在服务器的 IP,结果填错导致权限失效或过度开放。这个字段实际控制“谁可以连进来”,直接影响 'user'@'host' 的匹配逻辑:
- 填
%= 允许任意公网 IP 连接 → 生产环境严禁使用 - 填
10.20.30.0/24或203.0.113.45= 限定可信网段或机器 → 推荐做法 - 云函数(如 AWS Lambda)IP 不固定时,
@'%'不是妥协方案,得配数据库白名单 + 应用层代理,或改用临时凭证(如 IAM 认证)
PostgreSQL 需额外确认 schema 和 database 级权限
MySQL 用户常忽略 PostgreSQL 的两级权限模型:即使给了 SELECT 表权限,若缺少上层权限,SHOW TABLES 或 \dt 仍会返回空:
- 必须显式授予
CONNECT权限到目标 database:GRANT CONNECT ON DATABASE mydb TO reporter - 再授 schema 的
USAGE权限:GRANT USAGE ON SCHEMA public TO reporter - 最后授表级
SELECT:GRANT SELECT ON TABLE public.orders TO reporter
最容易被忽略的点是:Navicat Cloud 或 Team 的 Viewer 角色,只锁住编辑连接配置和保存的 Query 文件,完全不限制 SQL 执行——只要账号有权限,DELETE FROM users 依然能成功运行。所以,权限必须落在数据库账号本身,且 host、database、table、privilege 四个维度一个都不能松动。











