欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

Laravel Migration Error: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes


Migration error on Laravel 5.4 with php artisan make:auth

[Illuminate\Database\QueryException] SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter tabl e users add unique users_email_unique(email))

[PDOException] SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes

 
2 
You should answer your question in an answer. Not in the question. stackoverflow.com/help/self-answer – Can Vural Feb 15 at 9:35
   
Thanks for the suggestion @can-vural, I did. – absiddiqueLive Feb 15 at 9:57

7 Answers 正确答案

 

The issue solved by the following way.

Add the following code in 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 reserves always the max amount for a UTF8 field which is 4 bytes so with 255 + 255 with your DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; you are over the 767 max key length limit. By @scaisedge

 
 

This issue is caused in Laravel 5.4 by the database version.

According to the docs (in the Index Lengths & MySQL / MariaDB section):

Laravel uses the utf8mb4 character set by default, which includes support for storing "emojis" in the database. If you are running a version of MySQL older than the 5.7.7 release or MariaDB older than the 10.2.2 release, you may need to manually configure the default string length generated by migrations in order for MySQL to create indexes for them. You may configure this by calling the Schema::defaultStringLength method within your AppServiceProvider.

In other words, in <ROOT>/app/Providers/AppServiceProvider.php:

// Import Schema
use Illuminate\Support\Facades\Schema;
// ...

class AppServiceProvider extends ServiceProvider
{

public function boot()
{
    // Add the following line
    Schema::defaultStringLength(191);
}

// ...

}

But as the comment on the other answer says:

Be careful about this solution. If you index email fields for example, stored emails can only have a max length of 191 chars. This is less than the official RFC states.

So the documentation also proposes another solution:

Alternatively, you may enable the innodb_large_prefix option for your database. Refer to your database's documentation for instructions on how to properly enable this option.

 

In the AppServiceProvider.php,you include this code top of the file.

use Illuminate\Support\Facades\Schema;

And you add this code in boot method.

 Schema::defaultStringLength(191);
 

For someone who don't want to change AppServiceProvider.php. (In my opinion, it's bad idea to change AppServiceProvider.php just for migrateion)

You can add back the data length to the migration file under database/migrations/ as below:

create_users_table.php

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

create_password_resets_table.php

$table->string('email',128)->index();
shareimprove this answer
 
   
This can be a problem since emails can be up to 255(ish) characters – Half Crazed Jun 18 at 1:02
   
You are right @HalfCrazed, but I suggest this answer stackoverflow.com/questions/1297272 – helloroy Jun 19 at 1:17

I don't know why the above solution and the official solution which is adding

Schema::defaultStringLength(191);

in AppServiceProvider didn't work for me. What worked for was editing the database.php file in config folder. Just edit

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

to

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

and it should work. Hope it helps.

shareimprove this answer
 

Instead of setting a limit on lenght I think this is better , what is perfectly work for me :)

Inside

config/database.php

replace this line for mysql

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

upon

'engine' => null,
 

If you want to change in AppServiceProvider then you need to define the length of email field in migration. just replace the first line of code to the second line.

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();

After successfully changes you can run the migration.
Note: first you have to delete (if you have) users tablepassword_resets table from the database and delete users and password_resets entries from migration table.

 

来自 https://stackoverflow.com/questions/42244541/laravel-migration-error-syntax-error-or-access-violatio...


 

laravel迁移错误:语法错误或非法访问:1071指定的键太长;最大长度是767字节

偏移误差对laravel 5.4php artisan make:auth

[说明] \数据库\上海SQLSTATE [ 42000 ]:语法错误或非法访问:1071指定的键太长;最大长度是767字节(SQL:改变表users添加独特的users_email_uniqueemail))

【PDOException ] SQLSTATE [ 42000 ]:语法错误或非法访问:1071指定的键太长;最大长度是767字节









7个答案 正确答案

了投票二十三投票表决认可的

通过以下方式解决问题。

添加以下代码appserviceprovider.php

L5_root/app/Providers/AppServiceProvider.php

代码块

use Illuminate\Support\Facades\Schema; //Import Schema

function boot()
{
    Schema::defaultStringLength(191); //Solved by increasing StringLength
}

MySQL的储备总是最大金额为utf8的领域是4个字节,255 255你的默认字符集utf8mb4整理utf8mb4_unicode_ci;你是在767的最大长度限制。“scaisedge

 
  
关于这个解决方案仔细。如果指数的电子邮件领域例如,存储邮件只能有一个最大长度191个字符。这是低于官方RFC规定。shock_gone_wild2月16日下午12:30
  
  
它的工作是一个有效的解决方案,但我只是想指出,有可能存在的缺陷,使用这种方法。shock_gone_wild2月17日上午9:48
  
我希望这个解不来咬我的屁股在未来,但现在,这个作品。我要小心我的邮件虽然指数。deusofnull5月12日下午2:43
  
为什么191个字符@ absiddiquelivepseudoajJun 15 at 7:56
 

这个问题是由数据库版本引起laravel 5.4。

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

Laravel使用utf8mb4设置默认字符,包括支持存储“emojis”数据库。如果你正在运行一个版本的MySQL比5.7.7释放或比MariaDB年长10.2.2版本,您可能需要手动配置的默认字符串长度以MySQL为它们创造指标为迁移的产生。你可以配置通过调用架构:defaultstringlength方法在你AppServiceProvider

换句话说,在<ROOT>/app/Providers/AppServiceProvider.php

// 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你的数据库选项。请参考您的数据库的文件说明如何启用此选项。

 

AppServiceProvider.php你有这个代码,上面的文件。

use Illuminate\Support\Facades\Schema;

你添加此代码在启动方法。

 Schema::defaultStringLength(191);
 

谁不想改变appserviceprovider。PHP。(在我看来,这是不好的想法改变appserviceprovider.php只是migrateion)

您可以添加回来的数据长度,数据库/移民/下迁移文件如下:

create_users_table.php

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

create_password_resets_table.php

$table->string('email',128)->index();
 
  
这可以从电子邮件可以达到255是一个问题(ISH)的特点半疯狂君18 AT 1:02
  
你是对的”halfcrazed,但是我建议这个答案stackoverflow.com/questions/1297272helloroy六月19 AT 1:17

我不知道为什么上述溶液和官方的溶液,加入

Schema::defaultStringLength(191);

进入AppServiceProvider我没有工作,什么工作是编辑database.php文件config只是编辑文件夹

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

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

它应该工作。希望有帮助。

 

而不是设置一个限制长度的我认为这是更好的,什么是完美的工作我:)

里面

database.php配置

本线取代MySQL

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

在上面

'engine' => null,
分享提高这个答案
 

如果你想改变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();

成功后,你可以运行迁移变化。
注意:你必须先删除(如果有)用户表password_resets表从数据库中删除用户和password_resets条目迁移表。

 

来自 https://stackoverflow.com/questions/42244541/laravel-migration-error-syntax-error-or-access-violatio...

 
你应该回答你的问题的回答。没有问题。stackoverflow.com/help/self-answer可公司2月15日9:35
  
为感谢可以建议公司,我做的。absiddiquelive2月15日上午9时57分
 

普通分类: