只给用户 CREATE 权限但禁止 CREATE DATABASE
MySQL 的
CREATE权限在全局(
GRANT ... ON *.*)下会隐含允许创建数据库,这是最容易踩的坑。想让用户只能建表、不能建库,必须把权限粒度控制在数据库级别,且不授予任何全局
CREATE权限。 ✅ 正确做法:先创建目标数据库(如
app_db),再对用户授予该库下的
CREATE、
INSERT、
SELECT等权限 ❌ 错误做法:执行
GRANT CREATE ON *.* TO 'user'@'%'—— 这会让用户能执行
CREATE DATABASE⚠️ 注意:
CREATE权限在库级作用域(
ON app_db.*)仅允许建表/视图/存储过程等,不包含建库
用 GRANT 语句精确授权建表权限
用户需要在指定数据库中建表,只需授予该库下的
CREATE和
ALTER(用于后续加字段),无需
CREATE TEMPORARY TABLES或
INDEX(除非明确需要)。
CREATE DATABASE IF NOT EXISTS app_db; GRANT CREATE, ALTER, INSERT, SELECT, UPDATE, DELETE ON app_db.* TO 'dev_user'@'%' IDENTIFIED BY 'strong-pass-2024'; FLUSH PRIVILEGES;
app_db.*表示权限仅作用于
app_db库内所有现有及未来表 不加
WITH GRANT OPTION,防止用户转授权限 如果用户还需建视图或存储过程,额外加
CREATE VIEW、
CREATE ROUTINE
验证用户是否真不能建库
用该用户连接后执行
CREATE DATABASE test_db;,应明确报错:
ERROR 1044 (42000): Access denied for user 'dev_user'@'%' to database 'test_db'。而建表操作应成功:
USE app_db; CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(50)); -- ✅ 成功若建库没报错,说明之前误授了全局
CREATE或用户有
root类高权限角色 检查权限实际生效情况:用
SHOW GRANTS FOR 'dev_user'@'%';查看当前有效授权 注意:MySQL 8.0+ 使用角色(ROLE)管理时,需确认角色本身未包含全局权限
生产环境建议禁用匿名用户与空密码
限制建库建表只是权限收紧的第一步。真实风险常来自弱口令或残留的
''@'localhost'匿名账户,它们可能拥有意外的高权限。 运行
SELECT User,Host,authentication_string FROM mysql.user WHERE User='';检查匿名用户 删除无用账户:
DROP USER ''@'localhost';确保
mysql.user表中没有
Super_priv或
Grant_priv为
Y的非运维账户
权限收缩不是一次性配置,而是每次新建用户都得重审授权范围——尤其当 DBA 习惯性复制旧
GRANT语句时,很容易把
ON *.*带进去。
