跨库权限必须显式逐库授予,不能继承或通配“所有库”;MySQL无独立“跨库权限”,本质是对每个目标库(如orders.*、customers.*)分别执行GRANT SELECT等操作,漏授任一库即导致ERROR 1142;通配符(如tenant_%.*)仅限GRANT语句中有效且需反引号包裹特殊库名;角色可批量管理但需SET DEFAULT ROLE激活;生产环境严禁ON .,并应收回基表权限、仅授视图权限以实现真正隔离。

跨库权限必须显式逐库授予,不能继承或通配“所有库”
MySQL没有“跨库权限”这个独立权限类型,所谓跨库控制,本质是给同一用户在多个db_name.*上分别授权。漏授任意一个库,该库就不可见——哪怕只差一个GRANT SELECT ON report_db.*,用户查report_db.sales就会报错ERROR 1142 (42000): SELECT command denied。
常见错误是误以为GRANT SELECT ON *.*能覆盖所有业务库,其实它只覆盖当前已存在且用户有访问权的库(不含系统库如mysql、information_schema),且严重违反最小权限原则。
- 必须确认目标用户已存在:
SELECT User, Host FROM mysql.user WHERE User = 'app_user',否则GRANT静默失败 - 每个库授权语句必须完整写成
ON db1.*,不能简写为ON db1,否则报错ERROR 1144 (42000): Wildcard denied for database - 若数据库名含特殊字符(如
prod-v2),必须用反引号包裹:ON `prod-v2`.*
用角色批量管理多库权限(MySQL 8.0+)
当用户需访问orders、customers、inventory三个库时,硬写三条GRANT语句难维护。改用角色可把权限打包,后续增减库只需改角色,不碰用户。
例如创建app_rw_role并授予权限:
CREATE ROLE 'app_rw_role'; GRANT SELECT, INSERT, UPDATE, DELETE ON orders.* TO 'app_rw_role'; GRANT SELECT, INSERT ON customers.* TO 'app_rw_role'; GRANT SELECT ON inventory.* TO 'app_rw_role'; GRANT 'app_rw_role' TO 'webapp'@'%';
注意:用户登录后默认不激活角色,需执行SET DEFAULT ROLE ALL TO 'webapp'@'%',否则权限不生效。
解析 MySQL 8.0 的 DDL 脚本,并将表结构导出为 Excel 格式。适用于用户需将 MySQL 的 `CREATE TABLE` 语句转换为结构化的 Excel 文件场景,导出内容包含字段名、数据类型、长度及精度等信息。支持多张表的批量处理,每张表对应 Excel 中的一个独立工作表。适用于数据库文档编写、数据字典生成及模式分析等任务。
- 角色不能跨实例复用,迁移时需重新创建
-
SHOW GRANTS FOR 'webapp'@'%'输出里若没出现app_rw_role,说明未成功赋予或未设为默认角色 - 角色本身不拥有连接权限,用户仍需有
USAGE(即能登录)
通配符匹配动态库名(慎用)
当业务库按命名规则生成(如tenant_001、tenant_002),可用%通配符一次性覆盖:
GRANT SELECT ON `tenant_%`.* TO 'tenant_reader'@'10.20.%';
但要注意:%只在GRANT语句中有效,运行时不会自动匹配新创建的库;且一旦创建了tenant_admin这样的库,也会被意外包含进来。
- 通配符不支持正则,
_只匹配单字符,tenant__%≠tenant_% - 通配授权后,新增库仍需手动
FLUSH PRIVILEGES才能让权限缓存识别(5.7+通常自动刷新,但保险起见建议执行) - 生产环境禁用
GRANT ... ON `*`.*,这等于开放所有当前及未来库
权限闭环的关键:收回基表直连能力
即使你用视图封装了跨库查询逻辑(比如JOIN orders和customers),只要用户仍有SELECT ON orders.*和SELECT ON customers.*权限,整套细粒度控制就形同虚设。
真正有效的做法是:
- 只授视图权限:
GRANT SELECT ON myviews.customer_order_summary TO 'reporter'@'%' - 立刻收回底层库权限:
REVOKE SELECT ON orders.* FROM 'reporter'@'%'; REVOKE SELECT ON customers.* FROM 'reporter'@'%'; - 验证结果:
SHOW GRANTS FOR 'reporter'@'%'输出里不能出现任何orders、customers字样
最容易被忽略的是:视图定义中涉及的每张基表,其DEFINER账户都必须拥有对应权限。缺一张,视图就无法创建或查询失败。

















