模式构建器 laravel 迁移在两列上是唯一的
Posted
技术标签:
【中文标题】模式构建器 laravel 迁移在两列上是唯一的【英文标题】:schema builder laravel migrations unique on two columns 【发布时间】:2013-12-02 15:51:03 【问题描述】:如何在两列上设置唯一约束?
class MyModel extends Migration
public function up()
Schema::create('storage_trackers', function(Blueprint $table)
$table->increments('id');
$table->string('mytext');
$table->unsignedInteger('user_id');
$table->engine = 'InnoDB';
$table->unique('mytext', 'user_id');
);
MyMode::create(array('mytext' => 'test', 'user_id' => 1);
// this fails??
MyMode::create(array('mytext' => 'test', 'user_id' => 2);
【问题讨论】:
Laravel 4: making a combination of values/columns unique的可能重复 遗憾的是,Laravel docs 中缺少此级别的详细信息。顺便提一下很容易。像这样的细节和 - 例如 - 框架似乎总是假设每个表都会自动递增id
,这给框架带来了边缘的业余感觉。我在吐槽吗? :-(
【参考方案1】:
第二个参数是手动设置唯一索引的名称。使用数组作为第一个参数来创建跨多列的唯一键。
$table->unique(array('mytext', 'user_id'));
或者(更整洁一点)
$table->unique(['mytext', 'user_id']);
【讨论】:
+1 感谢这个......不知道我是如何在文档中错过它的。我一定是瞎子:P 我也不知何故错过了第二个参数是手动命名索引的事实,我有一个自动生成的索引名称太长了。谢谢你,兄弟! +1 +1 表示array()
。因为我尝试不使用数组但它不起作用。我可以在通过 Schema builder 运行复合键时给出约束名称吗?
是的,这是第二个参数
如果有人不确定,生成的索引名称格式为table_column1_column2...n_unique
。然后删除唯一约束将引用 $table->dropUnique('table_column1_column2...n_unique');
【参考方案2】:
你可以使用
$table->primary(['first', 'second']);
参考:http://laravel.com/docs/master/migrations#creating-indexes
举个例子:
Schema::create('posts_tags', function (Blueprint $table)
$table->integer('post_id')->unsigned();
$table->integer('tag_id')->unsigned();
$table->foreign('post_id')->references('id')->on('posts');
$table->foreign('tag_id')->references('id')->on('tags');
$table->primary(['post_id', 'tag_id']);
);
【讨论】:
这并不能保证唯一性,它只是添加了一个复合索引。通常,您不希望在同一篇文章中出现两次相同的标签,因此对于这个用例,最好使用->unique()
。
@Fx32 这确实保证了唯一性,因为它创建了一个复合主键(被索引)。但是,我仍然同意->unique()
在这个特定问题中更合适,因为'mytext'
可能会像任何VARCHAR
或TEXT
列一样成为一个坏键。 ->primary([])
非常适合确保整数的唯一性,例如枢轴外键。
另请注意,复合主键通常被 Laravel 开发人员所反对,并且 Eloquent 不支持它们 - 请参阅 github.com/laravel/framework/issues/5355【参考方案3】:
如果您有一个包含一列的默认唯一索引,并且您将使用两列更改它,或者创建一个包含两列的新索引,则此脚本将为您执行此操作:
public function up()
Schema::table('user_plans', function (Blueprint $table)
$table->unique(["email", "plan_id"], 'user_plan_unique');
);
public function down()
Schema::table('user_plans', function (Blueprint $table)
$table->dropUnique('user_plan_unique');
);
【讨论】:
【参考方案4】:DB::statement("ALTER TABLE `project_majr_actvities`
ADD UNIQUE `unique_index`(`activity_sr_no`, `project_id`)");
【讨论】:
口头解释将有助于您的回答以上是关于模式构建器 laravel 迁移在两列上是唯一的的主要内容,如果未能解决你的问题,请参考以下文章