首页 文章

Laravel Migration Error:语法错误或访问冲突:1071指定密钥太长;最大密钥长度为767字节

提问于
浏览
66

Migration error on Laravel 5.4 with php artisan make:auth

[Illuminate \ Database \ QueryException] SQLSTATE [42000]:语法错误或访问冲突:1071指定密钥太长;最大密钥长度为767字节(SQL:alter tabl e users add unique users_email_unique(email))[PDOException] SQLSTATE [42000]:语法错误或访问冲突:1071指定密钥太长;最大密钥长度为767字节

23 回答

  • 0

    这很常见,因为Laravel 5.4将默认数据库字符集更改为utf8mb4 . 您需要做的是:通过将此代码放在类声明之前编辑您的App \ Providers.php

    use Illuminate\Support\Facades\Schema;
    

    另外,将此添加到'boot'函数 Schema::defaultStringLength(191);

  • 3

    我是 quickest 的解决方案 . 只需将默认数据库引擎设置为 'InnoDB' 即可

    /config/database.php

    'mysql' => [
        ...,
        ...,
        'engine' => 'InnoDB',
     ]
    

    然后运行 php artisan config:cache 清除并刷新配置缓存

  • 21

    The issue solved by the following way.

    AppServiceProvider.php 中添加以下代码

    L5_root/app/Providers/AppServiceProvider.php
    

    The code block

    use Illuminate\Support\Facades\Schema; //Import Schema
    
    function boot()
    {
        Schema::defaultStringLength(191); //Solved by increasing StringLength
    }
    

    MySQL总是保留UTF8字段的最大数量,即4字节,因此255 255与您的默认字符集utf8mb4 COLLATE utf8mb4_unicode_ci;你超过767最大密钥长度限制 . 由@scaisedge

  • 11

    我不知道为什么上面的解决方案和正在添加的官方解决方案

    Schema::defaultStringLength(191);
    

    AppServiceProvider 对我不起作用 . 有用的是编辑 config 文件夹中的 database.php 文件 . 只需编辑

    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    

    'charset' => 'utf8',
    'collation' => 'utf8_unicode_ci',
    

    它应该工作 . 希望能帮助到你 .

  • 4

    AppServiceProvider.php 中,您将此代码包含在文件顶部 .

    use Illuminate\Support\Facades\Schema;
    

    并在boot方法中添加此代码 .

    Schema::defaultStringLength(191);
    
  • 0

    此问题是由数据库版本在Laravel 5.4中引起的 .

    根据docs(在 Index Lengths & MySQL / MariaDB 部分):

    Laravel默认使用utf8mb4字符集,其中包括支持在数据库中存储“emojis” . 如果您运行的是早于5.7.7版本的MySQL版本或早于10.2.2版本的MariaDB,您可能需要手动配置迁移生成的默认字符串长度,以便MySQL为它们创建索引 . 您可以通过在AppServiceProvider中调用Schema :: defaultStringLength方法来配置它 .

    换句话说,在_919756中:

    // Import Schema
    use Illuminate\Support\Facades\Schema;
    // ...
    
    class AppServiceProvider extends ServiceProvider
    {
    
    public function boot()
    {
        // Add the following line
        Schema::defaultStringLength(191);
    }
    
    // ...
    
    }
    

    但正如对其他答案的评论所说:

    小心这个解决方案 . 例如,如果您对电子邮件字段编制索引,则存储的电子邮件最多只能包含191个字符 . 这比官方的RFC状态要少 .

    因此文档还提出了另一种解决方案:

    或者,您可以为数据库启用innodb_large_prefix选项 . 有关如何正确启用此选项的说明,请参阅数据库的文档 .

  • 93

    对于不想改变 AppServiceProvider.php 的人 . (在我看来,仅仅为了迁移而改变 AppServiceProvider.php 是个坏主意)

    您可以将数据长度添加回 database/migrations/ 下的迁移文件,如下所示:

    create_users_table.php

    $table->string('name',64);
    $table->string('email',128)->unique();
    

    create_password_resets_table.php

    $table->string('email',128)->index();
    
  • 5

    我已经解决了这个问题并编辑了我的config-> database.php文件,就像我的数据库 ('charset'=>'utf8')('collation'=>'utf8_general_ci') 一样,所以我的问题解决了以下代码:

    'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_general_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],
    
  • 21

    我没有设定长度限制,而是提出以下建议,这对我有用 .

    config / database.php

    将此行替换为mysql

    'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',
    

    upon

    'engine' => null,
    
  • 16

    如前所述,我们将添加到App / Providers中的AppServiceProvider.php

    use Illuminate\Support\Facades\Schema;  // add this
    
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Schema::defaultStringLength(191); // also this line
    }
    

    你可以在下面的链接中查看更多详细信息(搜索"Index Lengths & MySQL / MariaDB")https://laravel.com/docs/5.5/migrations

    BUT WELL THAT's not what I published all about! 即使在执行上述 you will likely to get another error 时也是如此(当你运行 php artisan migrate 命令时,由于长度问题,操作可能会卡在中间. solution is below ,用户表很可能是在没有剩下的情况下创建的,或者不是完全没有正确) we need to roll back . 默认回滚将不起作用 . 因为迁移的操作不喜欢完成 . 您需要手动删除数据库中新创建的表 .

    we can do it using tinker as in below:

    L:\todos> php artisan tinker
    
    Psy Shell v0.8.15 (PHP 7.1.10 — cli) by Justin Hileman
    
    >>> Schema::drop('users')
    
    => null
    

    我本人对用户表有问题 .

    之后你很高兴

    php artisan migrate:rollback

    php artisan migrate

  • 2

    如迁移guide中所述,要解决此问题,您只需编辑 app/Providers/AppServiceProvider.php 文件并在引导方法内设置默认字符串长度:

    use Illuminate\Support\Facades\Schema;
    
    public function boot()
    {
        Schema::defaultStringLength(191);
    }
    

    注意:首先必须从数据库中删除(如果有) users 表, password_resets 表,并从 migrations 表中删除users和password_resets条目 .

    要运行所有未完成的迁移,请执行 migrate Artisan命令:

    php artisan migrate
    

    之后,一切都应该正常工作 .

  • 0

    Schema::defaultStringLength(191); 将默认定义所有字符串191的长度,这可能会破坏您的数据库 . 你不能这样走 .

    只需定义数据库迁移类中任何特定列的长度即可 . 例如,我在 CreateUsersTable 类中定义了"name","username"和"email",如下所示:

    public function up()
        {
            Schema::create('users', function (Blueprint $table) {
                $table->increments('id');
                $table->string('name', 191);
                $table->string('username', 30)->unique();
                $table->string('email', 191)->unique();
                $table->string('password');
                $table->rememberToken();
                $table->timestamps();
            });
        }
    
  • 45

    如果要在AppServiceProvider中进行更改,则需要在迁移中定义电子邮件字段的长度 . 只需将第一行代码替换为第二行 .

    create_users_table

    $table->string('email')->unique();
    $table->string('email', 50)->unique();
    

    create_password_resets_table

    $table->string('email')->index();
    $table->string('email', 50)->index();
    

    成功更改后,您可以运行迁移 .
    注意:首先你必须从数据库中删除(如果有) users tablepassword_resets table 并从迁移表中删除users和password_resets条目 .

  • 1

    我正在添加两个适合我的sollution .

    1st sollution is:

    • 打开 database.php 文件insde config dir /文件夹 .

    • 编辑 'engine' => null,'engine' => 'InnoDB',

    这对我有用 .

    2nd sollution is:

    • 打开 database.php file insde config dir / folder .
    1. Edit
      'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci',

    'charset' => 'utf8', 'collation' => 'utf8_unicode_ci',

    Goodluck

  • 3

    更新并在app / Providers / AppServiceProvider.php中插入这些行

    use Illuminate\Support\Facades\Schema;  //insert this line
    public function boot()
    {
        Schema::defaultStringLength(191); //insert this line also
    }
    

    在'mysql'数组中的config / database.php中设置数据库引擎

    'engine' => 'InnoDB',
    
  • 0

    app/Providers/AppServiceProvider.php 方法中添加以下代码:

    use Illuminate\Support\Facades\Schema;
    
    public function boot()
    {
        Schema::defaultStringLength(191);
    }
    

    首先,您必须从数据库中删除(如果有)users表,password_resets表,并从迁移表中删除users和password_resets条目 .

  • 1

    avoid changing anything in your code ,只需 update your MySQL server to at least 5.7.7

    有关详细信息,请参阅此内容:https://laravel-news.com/laravel-5-4-key-too-long-error

  • 0

    建议的解决方案是启用MySQL的 innodb_large_prefix 选项,这样您就不会遇到后续问题 . 以下是如何做到这一点:

    打开 my.ini MySQL配置文件,并在 [mysqld] 行下添加以下行 .

    [mysqld]
    innodb_file_format = Barracuda
    innodb_large_prefix = 1
    innodb_file_per_table = ON
    

    之后,保存更改并重新启动MySQL服务 .

    如果需要,请回滚然后重新运行迁移 .


    如果问题仍然存在,请转到数据库配置文件并进行设置

    'engine' => null,'engine' => 'innodb row_format=dynamic'

    希望能帮助到你!

  • 2

    对于其他可能遇到此问题的人来说,我的问题是我正在制作一个类型为 string 的列,并试图将其设为 ->unsigned() ,当时我的意思是它是一个整数 .

  • 6

    我认为强制StringLenght到191是一个非常糟糕的主意 . 所以我调查了解发生了什么 .

    我注意到这条消息错误:

    SQLSTATE [42000]:语法错误或访问冲突:1071指定密钥太长;最大密钥长度为767字节

    我更新MySQL版本后开始显示 . 所以我注意到创建的所有新表都使用了排序规则 utf8mb4_unicode_ci 而不是 utf8_unicode_ci .

    在我的doctrine配置文件中,我注意到charset设置为utf8mb4,但我之前的所有表都是在utf8中创建的,所以我想这是一些更新魔法,它开始在utf8mb4上运行 .

    现在,简单的解决方法是更改ORM配置文件中的行字符集 . 然后,如果您处于开发模式,则使用utf8mb4_unicode_ci删除表,或者如果您不能删除它们,则修复字符集 .

    对于Symfony 4

    将charset:utf8mb4更改为charset:config / packages / doctrine.yaml中的utf8

    现在我的学说迁移工作再次正常 .

  • 2

    接近这个工作是通过第二个param与关键名称(一个短的):

    $table->string('my_field_name')->unique(null,'key_name');
    
  • 2

    对我来说,通过运行来更新依赖关系是有效的 .

    composer update
    

    您还应该安装最新的mysql版本 .

  • 2

    我刚刚在用户和password_resets迁移文件中修改了以下行 .

    旧:$ table-> string('email') - > unique();

    新:$ table-> string('email',128) - > unique();

    瞧!

相关问题