Laravel 模式构建器主键作为外键

Posted

技术标签:

【中文标题】Laravel 模式构建器主键作为外键【英文标题】:Laravel schema builder primary key as foreign key 【发布时间】:2017-05-21 03:05:25 【问题描述】:

我正在使用 Laravel 4.2 架构构建器创建一些相互引用的表,但遇到了一些问题。

我有一个简化的 ERD。请注意,仅显示相关列:

请注意,我不能以任何方式修改 tblcurrenciestbldomains 表,因为我正在开发一个模块来连接到现有系统。

我正在努力实现以下目标:

    extensions 表包含有关tbldomains 表中行的额外信息 prices 表包含以特定货币表示的域的定价信息,以及附加类型值(注册、续订、转让) 我想使用外键来级联删除。

目前,我使用以下代码来创建这两个表:

Capsule::schema()->create('extensions', function ($table) 
    $table->engine = 'InnoDB';
    $table->integer('relid', 10);
    // ...
    $table->primary(['relid']);
    $table->foreign('relid')->references('id')->on('tbldomains')->onDelete('cascade');
);

Capsule::schema()->create('prices', function ($table) 
    $table->engine = 'InnoDB';
    $table->integer('relid', 10);
    $table->integer('currency', 10);
    $table->enum('type', ['domainregister', 'domainrenew', 'domaintransfer']);
    // ...
    $table->primary(['relid', 'currency', 'type']);
    $table->foreign('relid')->references('relid')->on('extensions')->onDelete('cascade');
    $table->foreign('currency')->references('id')->on('tblcurrencies')->onDelete('cascade');
);

prices 表的创建脚本导致以下 SQL 查询:

create table `prices` (`relid` int unsigned null auto_increment primary key, `currency` int unsigned null auto_increment primary key, `type` enum('domainregister', 'domainrenew', 'domaintransfer') not null, ...) engine = InnoDB

这又会导致以下错误:

SQLSTATE[42000]:语法错误或访问冲突:1075 表定义不正确;只能有一个自动列,并且必须定义为一个键

我也尝试将主键设置为唯一,我认为 Laravel 可能会自动将主整数键设置为自动递增。

此外,我尝试按照this 和this 回答的建议将列设置为unsignedindex

如何阻止架构生成器将 relidcurrency 字段设置为自动递增,因为它们只是外键?

【问题讨论】:

【参考方案1】:

基于以下链接上的 Laravel 文档 Api,只有 string() 方法可以具有长度属性。 Laravel Documentation Api

所以要使这两列 unsigned 而不是 primary keyauto increment 进行以下更改:

从此:

$table->integer('relid', 10);
$table->integer('currency', 10);

到这里:

$table->integer('relid', false, true);
$table->integer('currency', false, true);

因为根据文档,integer() 方法语法是:

integer(string $column, bool $autoIncrement = false, bool $unsigned = false)

您所做的就是将值 (10) 分配给布尔变量 ($autoIncrement),在这种情况下该变量将始终返回 true。要进一步证明这一点,请从 php.net 返回以下链接。 php.net Boolean

我之前也遇到过同样的问题,当我开始参考 Laravel 文档时,90% 的困惑都会被清除。希望对您有所帮助。


注意:您也可以使用unsignedInteger() 方法,我认为它更明确且更容易记住:

unsignedInteger(string $column, bool $autoIncrement = false)

所以代码会是这样的:

$table->unsignedInteger('relid');
$table->unsignedInteger('currency');

【讨论】:

以上是关于Laravel 模式构建器主键作为外键的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Laravel 中定义和使用外键作为主键?

如何在 laravel 查询生成器上获取主键名称

模式构建器 laravel 迁移在两列上是唯一的

如何为具有复合主键的表构建外键?

如何在laravel中将主键本身设置为外键?

在自定义主键和外键中定义 Laravel 关系