Laravel开发疑问:不使用迁移foreign仅用belongTo/hasMany可行吗?
Hey there! As a fellow Laravel developer who started out just like you, let’s unpack this question step by step.
首先:不用数据库外键,仅靠belongsTo/hasMany建立模型关系是可行的
Laravel’s Eloquent relationships are logical associations first and foremost. They rely on naming conventions (like having a user_id column in your posts table) rather than database-level foreign key constraints.
As long as your tables have the required columns (e.g., posts.user_id matching users.id), defining relationships in your models will work perfectly. You’ll still be able to do things like:
$user->poststo get all posts by a user$post->userto fetch the author of a post- Use eager loading (
User::with('posts')) to optimize queries
但为什么不推荐长期这么做?(关键缺点)
While it works for small projects or learning, skipping foreign keys comes with big tradeoffs that can bite you later:
1. No database-enforced data integrity
Without foreign keys, your database won’t stop you from inserting invalid data. For example, you could create a post with user_id=123 even if no user with ID 123 exists. This leads to "orphaned" records where $post->user returns null for no good reason, and tracking down these issues gets harder as your app grows.
2. Missing database-level automation
Foreign keys let you leverage database features like automatic cleanup:
onDelete('cascade'): Delete all related records (e.g., comments) when a post is deletedonDelete('set null'): Set the foreign key column tonullwhen the parent record is deleted
Without these, you’ll have to write custom code (model events, observers, or manual queries) to handle cleanup, which is error-prone and less efficient than letting the database do it.
3. Performance hits
When you define a foreign key, most databases automatically create an index for that column. Indexes drastically speed up queries that filter or join on that column (like fetching all posts for a user). If you skip foreign keys but don’t add an index manually, your app will slow down as your dataset grows.
Pro tip: Even if you skip foreign keys, always add an index to your relationship columns:
// In your posts migration $table->unsignedBigInteger('user_id')->index();
4. Team confusion
If you work with other developers, they’ll likely assume your database has foreign key constraints. This can lead to them writing code that doesn’t validate data, resulting in more orphaned records and bugs down the line.
关于你的删除问题:外键本身不是障碍
You mentioned you couldn’t delete posts easily with foreign keys—that’s not a flaw in foreign keys themselves, it’s just a matter of configuring them correctly.
For example, if your comments table has a foreign key to posts.id without an onDelete rule, deleting a post will fail because the database prevents orphaning comments. Fix this by updating your comments migration:
$table->foreignId('post_id')->constrained()->onDelete('cascade');
Now when you delete a post, all its comments will be automatically deleted by the database—no errors, no extra code needed.
总结
- Short-term/learning: Skipping foreign keys works, and it’s fine to experiment this way while you’re getting the hang of Laravel.
- Long-term/production: Always use database foreign keys. They keep your data clean, automate tedious tasks, and make your app more reliable.
内容的提问来源于stack exchange,提问作者ehsan

