普通用户默认不能建库是因为MySQL/MariaDB仅向root或显式授权用户授予CREATE权限;新用户仅有USAGE权限,需用GRANT CREATE ON myapp\_%.* TO 'appuser'@'localhost'精细授权。

不需要 root 账号也能创建数据库,但必须拥有 CREATE 权限 —— 这个权限可以单独授予普通用户,无需给 root 或 ALL PRIVILEGES。
为什么普通账号默认不能建库?
MySQL/MariaDB 默认只给 root 或显式授权用户分配 CREATE 数据库权限。新创建的用户(比如 'appuser'@'localhost')只有登录能力,不自动获得建库权。
常见错误现象:Access denied for user 'appuser'@'localhost' to database 'newdb' 或直接报 ERROR 1044 (42000): Access denied for user ... when using CREATE DATABASE。
- 不是密码错,也不是连接失败,是权限不足
-
SHOW GRANTS FOR 'appuser'@'localhost';会显示仅有USAGE权限 - 即使能连上 MySQL,
CREATE DATABASE仍会拒绝
如何给非 root 用户授建库权限?
用有管理权的账号(如 root)执行授权语句,粒度要细:只给 CREATE,不给 DROP、ALTER 等其它库级权限,更不要用 GRANT ALL ON *.*。
立即学习“PHP免费学习笔记(深入)”;
推荐命令:
GRANT CREATE ON `myapp\_%`.* TO 'appuser'@'localhost';
说明:
-
`myapp\_%`.*表示允许创建以myapp_开头的数据库(如myapp_prod、myapp_test),防止用户乱建库 - 反引号和下划线转义(
\_)必须写对,否则通配符不生效 - 执行后需运行
FLUSH PRIVILEGES;(仅在某些旧版本或特殊配置下必需) - PHP 中用
mysqli::query("CREATE DATABASE myapp_prod")就能成功
PHP 代码里建库要注意什么?
直接执行 CREATE DATABASE 是可行的,但要注意三点:
- 数据库名必须符合 MySQL 命名规则(不能含斜杠、空格、点号等),建议用
preg_replace('/[^a-zA-Z0-9_]/', '', $name)过滤 - 建库前最好先
SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?检查是否已存在,避免报错中断流程 - 如果用 PDO,记得关闭
PDO::ATTR_EMULATE_PREPARES,否则CREATE DATABASE这类语句无法参数化(它不支持预处理) - 建库后需重新连接或用
mysqli::select_db()切换,否则后续CREATE TABLE会报 “No database selected”
真正容易被忽略的是权限作用域:MySQL 的 CREATE 权限是“库级别”的,但它控制的是“创建新库”这个动作,而不是“在某个库里建表”。所以即使你只给了 CREATE ON `myapp\_%`.*,用户也不能往已有库(比如 mysql)里建表,也不能删别人建的库 —— 这正是最小权限原则落地的关键点。











