Php 拉威尔设置了一个外键
我是拉雷维尔的新手。我正在做一个项目,用户首先注册,他的信息将存储在用户表中。然后,他或她登录到网站,用户将提供另一个表格,注册为一名献血者。此信息将存储另一个表,即blooddonner表。因此,我想在blooddonner表中创建一个外键。外键将是用户表中的id。这就是我为blooddonner表创建迁移的原因Php 拉威尔设置了一个外键,php,mysql,laravel-4,Php,Mysql,Laravel 4,我是拉雷维尔的新手。我正在做一个项目,用户首先注册,他的信息将存储在用户表中。然后,他或她登录到网站,用户将提供另一个表格,注册为一名献血者。此信息将存储另一个表,即blooddonner表。因此,我想在blooddonner表中创建一个外键。外键将是用户表中的id。这就是我为blooddonner表创建迁移的原因 <?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migr
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateBlooddonnerTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('blooddonners', function(Blueprint $table)
{
$table->increments('id');
$table->unsignedInteger('donner_id');
$table->foreign('donner_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade');
$table->string('donner_name');
$table->string('email')->unique();
$table->string('blood_group');
$table->string('phone_number')->unique();
$table->string('location');
$table->date('date_of_birth');
$table->date('last_date_of_donation');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('blooddonners');
}
}
虽然我对Laravel很陌生,但我有一个问题,我在迁移文件中设置外键的方式是否是设置外键的正确方式?因为错误与该外键有关。设置外键的方式没有问题。事实证明,MySQL实际上是在阻止您插入违反您要求它强制执行的外键的条目。问题是您试图添加一个
献血者
条目,但没有指定与之相关的用户
。您有两个选择,然后:
provider\u id
是外键,但如果您需要,它可以为null,尽管您需要告诉Laravel/MySQL$table->unsignedInteger('donor_id')->nullable();
我冒昧更正了你的拼写:blood donner>blood provider。正确的拼写也有助于代码的可读性;)
编辑 如果您想了解如何改进数据库设计以充分利用外键的建议,下面是我的方法: 第一件事:如果不是每个用户都是献血者,我只会有一个次要的献血者表。如果你的用户100%都是献血者,不要把事情复杂化:只使用一个表并添加更多列。否则,请继续阅读 我的
users
表可能包含与一般个人信息相关的所有列:
- 名字
- 电子邮件
- 电话号码(用户唯一)
- 位置
- 出生日期
外键“链接”用户
表和献血者
表,这样我就不必重复了。我只需要知道哪个用户对应哪个献血者,我只需要完成一个id。这样,当我对数据库进行查询时,无论是在献血者
还是用户
表中,我都可以轻松地将这两个表连接在一起,同时拥有所有数据,没有在两个不同的地方重复
因此,回到您的迁移,这就足够了:
Schema::create('blooddonners', function(Blueprint $table)
{
$table->increments('id');
$table->unsignedInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade');
$table->string('blood_group');
$table->date('last_date_of_donation');
$table->timestamps();
});
i、 e.您不需要在献血者
表中输入“献血者姓名”,因为您已经将其记录在用户表中,而且他们毕竟是同一个人。你应该有只与献血相关的专栏
然后,您可以通过如下查询访问所有这些数据(假设您已经设置了模型):
您将拥有一个同时包含两个表的列的对象。请注意,具有完全相同名称的列将在最终对象中相互覆盖,因此,如果要可靠地访问该对象中的两个id
,最好在查询的select
部分指定别名。如果有必要,您甚至可以更改列名。在Laravel中,您可以这样做:
User::select('users.*', 'users.name as donor_name', 'blood_donors.id as donor_id')
->join('blood_donors', 'users.id', '=', 'blood_donors.user_id')
->get();
请查看,看看如何进一步进行数据库设计,并保持干净易读的代码。谢谢您的回答,我还有最后一个问题要问您,如何指定用户和用户Id,事实上,献血者实际上是注册的同一用户,所以我不想提供不同的Id,这就是我从用户表中为献血者表创建外键的原因。根据您的建议添加外键后,在提交献血者表单后,我面临一个错误:SQLSTATE[23000]:完整性约束冲突:1452无法添加或更新子行:外键约束失败(needa
blooddonners
,CONSTRAINTblooddonners\u donner\u id\u foreign
外键(donner\u id
)引用用户
(id
)删除级联更新级联)这意味着您正在尝试添加一个没有相应用户的献血者。如果您有外来ID,则无法执行此操作。如果该用户不存在,则必须首先创建该用户,然后继续插入献血者。请参阅我的原始答案。
User::join('blood_donors', 'users.id', '=', 'blood_donors.user_id')->get();
User::select('users.*', 'users.name as donor_name', 'blood_donors.id as donor_id')
->join('blood_donors', 'users.id', '=', 'blood_donors.user_id')
->get();