mysql不支持自动绑定用户名与数据库名,需手动为每个用户创建同名数据库并授权,如create database username; grant select,insert,update,delete on username.* to 'username'@'%'; flush privileges;。
mysql 中如何让用户只能访问自己同名的数据库
直接结论:mysql 本身不支持“自动绑定用户名与数据库名”的权限机制,必须手动为每个用户创建对应权限,并确保数据库名、用户名严格一致——靠命名约定 + 脚本化管理来实现“看起来像自动匹配”。
CREATE DATABASE 和 GRANT 权限要分两步走,不能跳过
常见错误是建库后忘记授权,或者用 GRANT ALL ON *.* 误放全局权限。用户连上 MySQL 后默认能看到所有数据库名(哪怕没权限进),但执行 USE db_name 或查询时会报 Access denied for user。
- 先用
CREATE DATABASE `username`;建库(注意反引号,避免用户名含特殊字符出错) - 再执行
GRANT SELECT, INSERT, UPDATE, DELETE ON `username`.* TO 'username'@'%'; - 必须加
FLUSH PRIVILEGES;,否则权限不生效(尤其在直接改mysql.db表后) - 不要用
GRANT ... ON *.*,哪怕只给USAGE也会让SHOW DATABASES列出全部库名
用户看到哪些数据库,取决于 mysql.db 表里的 host+user+db 三元组
MySQL 的 SHOW DATABASES 结果不是“当前用户能 USE 的库”,而是“当前用户在 mysql.db 表中有任意权限记录的库” + 系统库(如 information_schema)。这意味着:
- 如果给
'alice'@'%' ON `alice`.*授权,SHOW DATABASES就只显示alice和系统库 - 如果误加了一条
'alice'@'%' ON `bob`.*,那 alice 就能看见 bob 库(哪怕没权限操作) -
mysql.db表中Db字段支持通配符(如alice\_%),但不推荐——容易漏转义或匹配越界
自动化配置时,别忽略 host 值和 SQL 模式差异
脚本批量建库授权时,'user'@'localhost' 和 'user'@'%' 是两个完全独立的账号,权限不互通。另外,如果 MySQL 开启了 sql_mode=STRICT_TRANS_TABLES,建库语句里带横杠(如 my-app)会失败,必须用反引号包裹。
- 统一用
'username'@'%'避免本地/远程权限不一致(除非明确需要限制连接来源) - 建库前检查
SELECT @@sql_mode;,若含ANSI_QUOTES,则双引号也会被当作标识符,建议全程用反引号 - 执行
GRANT前先SELECT COUNT(*) FROM mysql.db WHERE User='username' AND Host='%';,确认没残留旧权限
最易被忽略的是:MySQL 8.0+ 默认启用 caching_sha2_password 插件,新建用户若没指定 IDENTIFIED WITH mysql_native_password,某些老客户端连不上——这和权限无关,但会让整个“只能看自己库”的验证卡在第一步。










