创建通知表时,Laravel“指定密钥太长”

时间:2017-01-11 21:10:59

标签: mysql laravel laravel-5

我正在使用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

3 个答案:

答案 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