我正在使用Laravels的默认迁移来创建通知表。
public function up()
{
Schema::create('notifications', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('type');
$table->morphs('notifiable');
$table->text('data');
$table->timestamp('read_at')->nullable();
$table->timestamps();
});
}
但是在尝试使用它时出现错误:
[Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `notifications` add index `n
otifications_notifiable_id_notifiable_type_index`(`notifiable_id`, `notifiable_type`))
[Doctrine\DBAL\Driver\PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
更新
我将索引列的名称更改为notifiable_index,但它仍然抱怨索引键的长度。
[Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `notifications` add index `n
otifiable_index`(`notifiable_id`, `notifiable_type`))
[Doctrine\DBAL\Driver\PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
答案 0 :(得分:7)
如果您正在使用Laravel 5.4并运行早于5.7.7版本的MySQL版本。您可以通过在Schema::defaultStringLength
班级AppServiceProvider
方法中调用boot
方法来解决此问题。
public function boot()
{
Schema::defaultStringLength(191);
}
答案 1 :(得分:1)
我最终做的是我刚刚为可通知的id创建了一个手动索引。这是迁移:
Schema::create('notifications', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('type');
$table->text('data');
$table->timestamp('read_at')->nullable();
$table->timestamps();
$table->unsignedInteger("notifiable_id");
$table->string("notifiable_type");
$table->index('notifiable_id');
});
而不是命令:
$table->morphs('notifiable');
我有3行:
$table->unsignedInteger("notifiable_id");
$table->string("notifiable_type");
$table->index('notifiable_id');
缺点是索引没有基于类型+ id组合,它只基于id。但因为我只有可以通知的用户模型,这对我来说没问题。
答案 2 :(得分:-1)
Laravel根据您的表和名称使用外键约定。但是您可以为密钥提供自己的名称:
$table->morphs('notifiable', 'mykeyname');
这样,您可以确保密钥名称足够短。
来源:https://github.com/laravel/framework/blob/5.3/src/Illuminate/Database/Schema/Blueprint.php#L963