Laravel中如何为多个字段组合创建联合唯一索引?
Laravel多字段联合唯一约束实现方案
1. 建表时直接添加联合唯一约束
直接在现有迁移的字段定义下方调用unique()方法,传入需要组合的字段数组即可,修改后完整的建表迁移代码如下:
Schema::create('adresses', function (Blueprint $table) { $table->id(); $table->string('adress'); //adress $table->integer('houseNumber'); //house number $table->string('houseNumberAddition')->nullable(); //house number addition $table->timestamps(); // 添加三个字段的联合唯一约束 $table->unique(['adress', 'houseNumber', 'houseNumberAddition']); });
你也可以给约束自定义名称,避免框架自动生成的名称过长超过数据库限制,只需要传第二个参数即可:
$table->unique(['adress', 'houseNumber', 'houseNumberAddition'], 'adresses_uniq_address_house_addition');
2. 已创建表后新增联合唯一约束
如果已经执行过建表迁移,需要单独新增约束,新建一个迁移文件,使用Schema::table方法修改表结构即可:
Schema::table('adresses', function (Blueprint $table) { $table->unique(['adress', 'houseNumber', 'houseNumberAddition'], 'adresses_uniq_address_house_addition'); });
如果需要回滚该操作,在迁移的down()方法中删除约束即可:
Schema::table('adresses', function (Blueprint $table) { // 方式1:传入自定义的约束名 $table->dropUnique('adresses_uniq_address_house_addition'); // 方式2:直接传入字段数组,框架会自动解析约束名 // $table->dropUnique(['adress', 'houseNumber', 'houseNumberAddition']); });
注意事项
- 由于
houseNumberAddition字段设置了nullable,MySQL等数据库默认会把两个NULL值视为不相等的,即如果两条记录的adress和houseNumber相同,但houseNumberAddition都是NULL的话,不会触发唯一约束。如果需要把NULL也视为相同值,可以修改字段默认值为空字符串,取消nullable设置。 - 建议除了数据库层面的约束,在业务代码的表单验证层也添加对应校验,避免数据库报错直接暴露给用户,Laravel验证规则示例如下:
use Illuminate\Validation\Rule; $validated = $request->validate([ 'adress' => 'required|string', 'houseNumber' => 'required|integer', 'houseNumberAddition' => 'nullable|string', 'adress' => [ 'required', Rule::unique('adresses') ->where('houseNumber', $request->houseNumber) ->where('houseNumberAddition', $request->houseNumberAddition) ], ]);
内容的提问来源于stack exchange,提问作者Dave Hulst
相关产品推荐
相关产品推荐

