Laravel表前缀由config/database.php的prefix配置控制,迁移文件不写前缀,模型通过$table属性可覆盖或禁用前缀,修改配置后需清缓存并验证。

迁移文件里不写表名前缀,Eloquent 模型里也不硬编码
Laravel 默认不会在迁移中自动加前缀,php artisan migrate 生成的表名就是你 create_xxx_table 里写的原始名称。前缀只在运行时由框架注入,所以迁移文件应保持干净,避免写死 prefix_users 这类名字。
真正起作用的是配置层和模型层的联动:
-
config/database.php中的'prefix' => 'myapp_'控制全局默认前缀 - Eloquent 模型可通过
$table属性显式指定完整表名(含前缀),但更推荐用$connection+ 全局前缀组合 - 若某张表完全不想加前缀,模型里设
protected $table = 'log_entries'即可跳过前缀拼接
修改 config/database.php 的 prefix 配置项
这是最直接生效的位置,所有使用默认连接(mysql)且未在模型中覆盖 $table 的 Eloquent 查询都会自动加上该前缀。
打开 config/database.php,找到 connections.mysql 下的 prefix 键:
'connections' => [
'mysql' => [
// ...
'prefix' => 'myapp_',
'prefix_indexes' => true,
],
],注意两个细节:
-
'prefix_indexes' => true表示数据库索引名也会被加前缀(如myapp_users_email_unique),避免多项目共用数据库时索引名冲突 - 这个前缀只影响 Eloquent 和 Query Builder 的表名解析,不影响原始 SQL 执行(比如
DB::select("SELECT * FROM users")不会自动加前缀) - 如果用的是读写分离连接,需分别设置
read.prefix和write.prefix
模型里用 $table 覆盖或禁用前缀
当某个模型需要映射到无前缀的表,或前缀逻辑特殊(比如按租户动态切换),就不能依赖全局配置。
常见做法:
- 完全跳过前缀:
protected $table = 'settings';—— 此时无论 config 中 prefix 是什么,都查settings表 - 手动拼前缀:
protected $table = 'myapp_posts';—— 不推荐,破坏配置一致性 - 动态前缀(如多租户):
protected $table = ''; public function getTable() { return tenant()->id . '_posts'; }
注意:一旦设置了 $table,Laravel 就不会再帮你拼接 prefix,哪怕值是空字符串也会被当作已定义而跳过前缀逻辑。
运行迁移前确认 DB 连接和前缀是否生效
容易踩的坑是改了 config/database.php 但没清缓存,导致 php artisan migrate 仍用旧前缀建表。
执行迁移前务必检查:
- 运行
php artisan config:clear(尤其在生产环境部署后) - 用
php artisan tinker快速验证:>>> DB::getTablePrefix() => "myapp_"
- 查看迁移生成的 SQL(加
--pretend):php artisan migrate --pretend,确认输出的 CREATE TABLE 语句里表名是否含预期前缀
如果用了多数据库连接,还要确认模型的 $connection 属性是否指向正确连接,否则前缀配置可能根本没加载进来。










