Sqlstate 42000 syntax error or access violation 1071 specified key was too long

Laravel Version: 5.6.26 PHP Version: 7.1.16 Database Driver & Version: MySQL 5.7.21 Description: SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key leng...

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement. We’ll occasionally send you account related emails.

Already on GitHub?
Sign in
to your account

Comments

@marcosjosemenezes

  • Laravel Version: 5.6.26
  • PHP Version: 7.1.16
  • Database Driver & Version: MySQL 5.7.21

Description:

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

Steps To Reproduce:

a. Cria-se um novo projeto: laravel new [project]
b. cd na pasta do [project] criada
c. Altera as informações do arquivo «.env» banco de dados
d. Executa o «php artisan migrate»

Qual a causa:

O limite de comprimento da chave UNIQUE KEY do MySQL é de 1000 bytes e o sistema esta tentando gerar uma chave maior.

Correção

a. Edite o arquivo «vendor laravel framework src Illuminate Database Schema Builder.php».
b. Faça a seguinte alteração
[código original] public static $defaultStringLength = 255;
[código alterado] public static $defaultStringLength = 250;
c. Remova as tabelas que foram criadas no banco de dados
— migrations
— users
d. Execute novamente o «php artisan migrate»
e. Pronto resolvido

@decadence

vpratfr, zeroterminal, ArnoutPullen, ultrono, aram810, esternwinluck, iTeije, vodd, crizise, abinash-mlbd, and 4 more reacted with thumbs up emoji
felix-penrose, 389883538, amineflex, petrnagy, clintontolbert, Illusionist3886, sapheko, and Sun3-11 reacted with thumbs down emoji
mohammedali933 reacted with laugh emoji
alnahian2003 reacted with confused emoji

@wellingguzman

A temporary solution would be going to your config/database.php and change the charset and collation from utf8mb4 to utf8

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

This happens because utf8mb4 uses 4 bytes per character, and the email column has a 255 character length which is greater than the limit 767 bytes. 255 x 4bytes = 1020b.

To fix this the email column length should be at most 191. 191 x 4 bytes = 764b.

marcosjosemenezes, HieuBk, borispacex, jasmanylara, comsianabrar, barcelonabk90, MohammadDayeh, rewindthetrend, 101t, compimprove, and 128 more reacted with thumbs up emoji
blancessanchez, sefirakarina, indrakumarprajapat, ultrono, bacnd, imyuvii, zamisyh, GeorgievAlex, bacardiel05, diazsmartiansyah, and 11 more reacted with laugh emoji
comrade-tea, prashantpatil14, jeni1616, Anas-shamia, sefirakarina, indrakumarprajapat, ultrono, bacnd, imyuvii, sinonodd, and 19 more reacted with hooray emoji
borispacex, Minpyaephyooo, compimprove, prashantpatil14, SamiKhan9892, jeni1616, Anas-shamia, sefirakarina, khalidsgh, srshubho, and 40 more reacted with heart emoji
imyuvii, zamisyh, farridkun, GeorgievAlex, bacardiel05, rgttamala, diazsmartiansyah, TheMrBlackLord, abinash-mlbd, diya-ing, and 14 more reacted with rocket emoji

@wellingguzman

@sisve

@wellingguzman How is that solution temporary? Can it be easily reverted and start working with utf8mb4 later on?

@wellingguzman

@sisve You can change it later on if you want to, this may not be the ideal solution if you want to use utf8mb4 charset.

There’s three way to solve this:

Changing the migration length to 191

Changing the length to 191 or less.

$table->string('name', 191);

Change the string default length

Changing the default (global) string type length to 191. This can be done using the schema facade.

IlluminateSupportFacadesSchema::defaultStringLength(191);

You can add this line to your AppServiceProvider.php boot() method located in app/Providers/ directory.

public function boot()
{
    IlluminateSupportFacadesSchema::defaultStringLength(191);
}

Use utf8 instead utf8mb4

This may not be the ideal one, but if you don’t care about utf8mb4 you can go to your config/database.php file and replace charset and collation to utf8

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

to

'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
techadjuvant, pawansa3, rchen, Mukhami, SKIDDOW, Snackys07, ayatmustafa, mhdalkhiami, dhhdev, diniart, and 17 more reacted with thumbs up emoji
Mukhami, SKIDDOW, Snackys07, dhhdev, akbarSalahshour, and Waseem-Almoliky reacted with hooray emoji
KyriakosMilad, SKIDDOW, Snackys07, dhhdev, diniart, silvarney, akbarSalahshour, JoeBannouna, Waseem-Almoliky, and alnahian2003 reacted with heart emoji

@sisve

No, he cannot change it later. His database server will not allow it next week; the exact same problem will still be there. And he’ll have to write migrations to fix all the things you just told him to do.

A fourth alternative is to enable innodb_large_prefix in his database. That’s enabled per default in newer versions of mysql. Properly configuring the database server means he does not have to change his application code, and he can deploy the code to both an old or a new mysql versions, without changing any code.

@marcosjosemenezes

As explicações agregam a resposta, obrigado a todos.

@ghost

@tback

Still appears on clean laravel project:

  • Laravel 5.7.9
  • PHP 7.2.10-1+0~20181001133118.7+stretch~1.gbpb6e829
  • Mariadb 10.1.26-MariaDB-0+deb9u1

Project created with composer create-project --prefer-dist laravel/laravel auth.
All I did was change DB_CONNECTION in .env to mysql.
Then I called artisan migrate

This behavior is frustrating and confusing for new users. Please reopen the issue.

@sisve

Configure your database to enable innodb_large_prefix. It may require you to start using the new innodb_file_format Barracuda (that mysql is using as default now).

@jeni1616

A temporary solution would be going to your config/database.php and change the charset and collation from utf8mb4 to utf8

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

This happens because utf8mb4 uses 4 bytes per character, and the email column has a 255 character length which is greater than the limit 767 bytes. 255 x 4bytes = 1020b.

To fix this the email column length should be at most 191. 191 x 4 bytes = 764b.

Thanks, this worked !

@oubihis

Go in the AppProvidersAppServiceProvider class and change the boot method to look like this

use IlluminateSupportFacadesSchema;

public function boot()
{
    Schema::defaultStringLength(191);
}

@khanks

It seems obvious that newer versions of MySQL/MariaDB should not have this ‘key length’ error. But it also seems obvious to me that the solutions presented here have some issues of their own. Both Oracle and Percona have vacillated on turning innodb_large_prefix «ON» or «OFF» by default and both of them have it listed as ‘deprecated’ (Mysql ->https://dev.mysql.com/worklog/task/?id=7703, last paragraph says they will remove it. Percona docs have similar comments).
As for changing the AppServiceProvider ‘default’ string length, how does that help a situation where a developer specifically defines a varchar of 255? (side note: as a DB guy, I always wonder why anyone would define an index on a varchar).
Changing the collation seems, IMHO, to be the least fraught with weirdness (as long as you haven’t already stored data using utf8mb4 that actually required utf8mb4). Someone commented that «no, you cannot change it later». Well man, I’ve changed several of my databases back and forth from UTF-8 to UTF8MB4 a number of times and never had a problem. But I’m serving English-only users and they don’t use weird things like emoticons in a business website.
I realize I’ve not offered a great ‘solution’ for people (like me) who are not on the latest version of mysql/mariadb. I just thought these points needed to be brought up, for those who don’t already have enough to think about. Smile (no emoji needed to convey that).

@sisve

Hi @khanks ,

It sounds like you’re against modifying the innodb_large_prefix because Oracle/Percona have discussions about it. Just to clarify, the linked discussion argues for removing the setting entirely, and forcing it to the setting ON, which is my suggested solution for this problem. The last two paragraphs is interesting to read.

The parameter innodb_large_prefix was introduced in MySQL 5.5, so that users could avoid accidentally creating tables that would be incompatible with the InnoDB Plugin in MySQL 5.1. Now that MySQL 5.1 is not supported any more, it makes no sense to use any other value than innodb_large_prefix=ON.

Basically, the only purpose of innodb_file_format and innodb_large_prefix is to cripple the capabilities of InnoDB. This is the reason to change the default values to ‘uncrippled’ and to deprecate and remove the parameters for future removal, so that InnoDB cannot be accidentally crippled.

It was I that said that the collation couldn’t be changed later. The context is important, the poster cannot change the collation later because his database settings would still not allow it. If the correct settings where set, then the utf8mb4 collation can be used with the field sizes in question. My argument here was that it made more sense to modify those settings a year ago, when the question was asked, instead of waiting. They need to be changed someday anyhow.

@aleedhillon

If you are looking for a permanent solution then just change the default storage engine in Mysql ini configuration file to InnoDB which is the default storage engine in Mysql v5.5 and later.
default-storage-engine=InnoDB
In many cases like mine people complain that they have the latest version of Mysql but still having this error but the problem is sometime latest versions use old configuration files sitting in servers which uses MYISAM as default engine which create above problem.

@khanks

On 11/8/2019 2:13 PM, Ali A. Dhillon wrote:

If you are looking for a permanent solution then just change the
default storage engine in Mysql ini configuration file to *InnoDB*
which is the default storage engine in *Mysql v5.5* and later. In many
cases like mine people complain that they have the latest version of
Mysql but still having this error but the problem is sometime latest
versions use old configuration files stored in servers.
|default-storage-engine=InnoDB|


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#24711?email_source=notifications&email_token=AAG67TKAO773FLB4N42PLYDQSXB6JA5CNFSM4FHYIT62YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEDTHH2I#issuecomment-551973865>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAG67TNQHW7A67IV4BMFKPTQSXB6JANCNFSM4FHYIT6Q>.

Thanks, that’s a great point. I don’t have that command specifically set
in my «my.ini», but I verified the default storage engine is InnoDb by
doing a «SHOW ENGINES» query. Good point though, and definitely worth
looking at.

@aleedhillon

@khanks I am using WAMP and in my case it had the old configuration my.ini which has the
default-storage-engine=MYISAM but in mysql v5.5 or latere InnoDB is default engine so if you just omit the above line (if there is any) it will use the default engine which is InnoDB.
So you don’t have to explicitly set the default-storage-engine=InnoDB if you are using mysql v5.5+. That’s why you don’t have this in you my.ini but still your storage engine is InnoDB.

If you omit the ENGINE option, the default storage engine is used. The default engine is InnoDB as of MySQL 5.5.5 (MyISAM before 5.5.5). You can specify the default engine by using the —default-storage-engine server startup option, or by setting the default-storage-engine option in the my.cnf configuration file.Ref

@farridkun

A temporary solution would be going to your config/database.php and change the charset and collation from utf8mb4 to utf8

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

This happens because utf8mb4 uses 4 bytes per character, and the email column has a 255 character length which is greater than the limit 767 bytes. 255 x 4bytes = 1020b.

To fix this the email column length should be at most 191. 191 x 4 bytes = 764b.

This is Work for me, Thanks Dude!

@prabaharanh

A temporary solution would be going to your config/database.php and change the charset and collation from utf8mb4 to utf8

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

This happens because utf8mb4 uses 4 bytes per character, and the email column has a 255 character length which is greater than the limit 767 bytes. 255 x 4bytes = 1020b.

To fix this the email column length should be at most 191. 191 x 4 bytes = 764b.

Success!!!!

@israelkingz

A temporary solution would be going to your config/database.php and change the charset and collation from utf8mb4 to utf8

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

This happens because utf8mb4 uses 4 bytes per character, and the email column has a 255 character length which is greater than the limit 767 bytes. 255 x 4bytes = 1020b.
To fix this the email column length should be at most 191. 191 x 4 bytes = 764b.

Thanks, this worked !

Thanks, It worked

@caiofelipedossantos

@khanks I am using WAMP and in my case it had the old configuration my.ini which has the
default-storage-engine=MYISAM but in mysql v5.5 or latere InnoDB is default engine so if you just omit the above line (if there is any) it will use the default engine which is InnoDB.
So you don’t have to explicitly set the default-storage-engine=InnoDB if you are using mysql v5.5+. That’s why you don’t have this in you my.ini but still your storage engine is InnoDB.

If you omit the ENGINE option, the default storage engine is used. The default engine is InnoDB as of MySQL 5.5.5 (MyISAM before 5.5.5). You can specify the default engine by using the —default-storage-engine server startup option, or by setting the default-storage-engine option in the my.cnf configuration file.Ref

Thanks, It worked.

@khanks

Thanks. I figured out a solution long ago. And when my host finally updates
the version of MySQL that they provide, it will be a non-issue.
Also, there are about 50 duplicates of this same answer and every time
somebody posts one of those duplicates, I get copied on it — and probably
many others do as well. So maybe we shouldn’t pursue this thread anymore.
The real question for me, was why in the hell anybody would define an email
field as big as Laravel defined that default. it’s ridiculous.

On Fri, Jun 26, 2020, 8:59 PM Caio Felipe ***@***.***> wrote:
@khanks <https://github.com/khanks> I am using WAMP and in my case it had
the old configuration my.ini which has the
default-storage-engine=MYISAM but in mysql v5.5 or latere InnoDB is
default engine so if you just omit the above line (if there is any) it will
use the default engine which is InnoDB.
So you don’t have to explicitly set the default-storage-engine=InnoDB if
you are using mysql v5.5+. That’s why you don’t have this in you my.ini but
still your storage engine is InnoDB.

If you omit the ENGINE option, the default storage engine is used. The
default engine is InnoDB as of MySQL 5.5.5 (MyISAM before 5.5.5). You can
specify the default engine by using the —default-storage-engine server
startup option, or by setting the default-storage-engine option in the
my.cnf configuration file.Ref
<https://dev.mysql.com/doc/refman/5.5/en/storage-engine-setting.html>

Thanks, It worked.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#24711 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAG67TNBRXADWHOZL6GANCTRYVHAXANCNFSM4FHYIT6Q>
.

@khanks

In addition, my default storage engine has always been Innodb — I don’t
even use Myisam.

On Fri, Jun 26, 2020, 9:27 PM Smiddick Hanks ***@***.***> wrote:
Thanks. I figured out a solution long ago. And when my host finally
updates the version of MySQL that they provide, it will be a non-issue.
Also, there are about 50 duplicates of this same answer and every time
somebody posts one of those duplicates, I get copied on it — and probably
many others do as well. So maybe we shouldn’t pursue this thread anymore.
The real question for me, was why in the hell anybody would define an email
field as big as Laravel defined that default. it’s ridiculous.

On Fri, Jun 26, 2020, 8:59 PM Caio Felipe ***@***.***>
wrote:

> @khanks <https://github.com/khanks> I am using WAMP and in my case it
> had the old configuration my.ini which has the
> default-storage-engine=MYISAM but in mysql v5.5 or latere InnoDB is
> default engine so if you just omit the above line (if there is any) it will
> use the default engine which is InnoDB.
> So you don’t have to explicitly set the default-storage-engine=InnoDB if
> you are using mysql v5.5+. That’s why you don’t have this in you my.ini but
> still your storage engine is InnoDB.
>
> If you omit the ENGINE option, the default storage engine is used. The
> default engine is InnoDB as of MySQL 5.5.5 (MyISAM before 5.5.5). You can
> specify the default engine by using the —default-storage-engine server
> startup option, or by setting the default-storage-engine option in the
> my.cnf configuration file.Ref
> <https://dev.mysql.com/doc/refman/5.5/en/storage-engine-setting.html>
>
> Thanks, It worked.
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <#24711 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AAG67TNBRXADWHOZL6GANCTRYVHAXANCNFSM4FHYIT6Q>
> .
>

@skino2019

A temporary solution would be going to your config/database.php and change the charset and collation from utf8mb4 to utf8

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

This happens because utf8mb4 uses 4 bytes per character, and the email column has a 255 character length which is greater than the limit 767 bytes. 255 x 4bytes = 1020b.

To fix this the email column length should be at most 191. 191 x 4 bytes = 764b.

This fixed it for me. when i created the DB it set to utf8mb and collation utf8mb_general_ci… changed the formatting and worked out the box.

@anasroud

A temporary solution would be going to your config/database.php and change the charset and collation from utf8mb4 to utf8

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

This happens because utf8mb4 uses 4 bytes per character, and the email column has a 255 character length which is greater than the limit 767 bytes. 255 x 4bytes = 1020b.

To fix this the email column length should be at most 191. 191 x 4 bytes = 764b.

This fixed it for me. thank you so much.

@Alexis2421

@sisve Puede cambiarlo más adelante si lo desea, esta puede no ser la solución ideal si desea usar utf8mb4charset.

Hay tres formas de resolver esto:

Cambiar la duración de la migración a 191

Cambiando la longitud 191ao menos.

$table->string('name', 191);

Cambiar la longitud predeterminada de la cadena

Cambiar la stringlongitud de tipo predeterminada (global) a 191. Esto se puede hacer usando la fachada del esquema.

IlluminateSupportFacadesSchema::defaultStringLength(191);

Puede agregar esta línea a su AppServiceProvider.php boot()método ubicado en el app/Providers/directorio.

public function boot()
{
    IlluminateSupportFacadesSchema::defaultStringLength(191);
}

Utilizar en su utf8lugarutf8mb4

Esto puede no ser la ideal, pero si no se preocupan por utf8mb4usted puede ir a su config/database.phparchivo y reemplazar charsety collationalutf8

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

a

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

Muchas Gracias, la solución para mi fue cambiar la longitud a 191, pero primero revise que hubiera borrado en la base de datos las migraciones que había podido realizar, y luego ejecutar nuevamente el comando php artisan migrate

@anopchaksu

simpley login to phpmyadmin of hosting account and select database >> go to «operations» >> change the collections to ‘utf8mb4_unicode_ci’ and restored backup now work for me.

@Lakshsay

PLEASE ANYONE HELP?

IlluminateDatabaseQueryException

SQLSTATE[42S02]: Base table or view not found: 1146 Table ‘hello.core_settings’ doesn’t exist (SQL: select * from core_settings where name = site_locale limit 1)

at vendor/laravel/framework/src/Illuminate/Database/Connection.php:671
667| // If an exception occurs when attempting to run a query, we’ll format the error
668| // message to include the bindings with SQL, which will make this exception a
669| // lot more helpful to the developer instead of just the database’s errors.
670| catch (Exception $e) {

671| throw new QueryException(
672| $query, $this->prepareBindings($bindings), $e
673| );
674| }
675|

1 [internal]:0
IlluminateFoundationApplication::IlluminateFoundation{closure}(Object(AppProvidersAppServiceProvider))

14 modules/Core/Models/Settings.php:31
IlluminateDatabaseEloquentBuilder::first()

@caiofelipedossantos

Good afternoon @Lakshsay, could I put the Model Settings source code?
Apparently the table name is wrong — hello.core_settings.

@Lakshsay

@polares552 Yes please advice me the steps / changes needs to be done.
where exactly I need to make changes.
im a student so learning

@caiofelipedossantos

@Lakshsay add your application’s source code here or provide the repository link so we can help you.
You can start by checking your migrations, the migrations are inside the databases folder.
If you haven’t created it, make sure the connection to your database is working, the connection settings can be adjusted in the .env file at the root of the project, then run the command php artisan migrate in your command terminal.
Check your controller where the SQL statement is being assembled via Eloquent or QueryBuilder.
If you prefer you can call me on Skype caiofelipe.up@hotmail.com.

@Lakshsay

@polares552 best personality I have ever came across. you are so helpful , polite and understandable. listened to all the concerns and resolved it I am really thankful to you.

@caiofelipedossantos

@polares552 best personality I have ever came across. you are so helpful , polite and understandable. listened to all the concerns and resolved it I am really thankful to you.

Thanks!!!

@felipeminello

A temporary solution would be going to your config/database.php and change the charset and collation from utf8mb4 to utf8

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

This happens because utf8mb4 uses 4 bytes per character, and the email column has a 255 character length which is greater than the limit 767 bytes. 255 x 4bytes = 1020b.

To fix this the email column length should be at most 191. 191 x 4 bytes = 764b.

THANKS!
Works on Heroku

@putroandrianto

A temporary solution would be going to your config/database.php and change the charset and collation from utf8mb4 to utf8

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

This happens because utf8mb4 uses 4 bytes per character, and the email column has a 255 character length which is greater than the limit 767 bytes. 255 x 4bytes = 1020b.
To fix this the email column length should be at most 191. 191 x 4 bytes = 764b.

This fixed it for me. thank you so much.

wow thanks

Странная ошибка, возникающая при выполнении первой миграции в Laravel 8, тянется ещё со времён Laravel 5.4. И её почему-то до сих пор не устранили. Связано ли это с тем, что программисты, работающие с Laravel, предпочитают исключительно MySQL и люто ненавидят MariaDB, или ещё по какой причине, но ошибка случается и поправить её на самом деле, не составляет труда.

Ошибка выглядит следующим образом. При выполнении команды:

php artisan migrate

Миграции начинают обрабатываться:

Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table

Но тут же вылетает сообщение об ошибке:

   IlluminateDatabaseQueryException

  SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `users` add unique `users_email_unique`(`email`))

  at vendor/laravel/framework/src/Illuminate/Database/Connection.php:671
    667▕         // If an exception occurs when attempting to run a query, we'll format the error
    668▕         // message to include the bindings with SQL, which will make this exception a
    669▕         // lot more helpful to the developer instead of just the database's errors.
    670▕         catch (Exception $e) {
  ➜ 671▕             throw new QueryException(
    672▕                 $query, $this->prepareBindings($bindings), $e
    673▕             );
    674▕         }
    675▕

      +9 vendor frames
  10  database/migrations/2014_10_12_000000_create_users_table.php:26
      IlluminateSupportFacadesFacade::__callStatic("create")

      +21 vendor frames
  32  artisan:37
      IlluminateFoundationConsoleKernel::handle(Object(SymfonyComponentConsoleInputArgvInput), Object(SymfonyComponentConsoleOutputConsoleOutput))

Решение проблемы с ошибкой php artisan migrate — SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes при применении миграции в Laravel

Для устранения этой ошибки нужно внести изменения в метод boot класса AppServiceProvider. Для этого открываем файл, находящийся по адресу:

/папка_проекта/app/Providers/AppServiceProvider.php

Изначально он имеет вид:

<?php

namespace AppProviders;

use IlluminateSupportServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

В него нужно вписать 2 строчки (использование библиотеки фасадов use IlluminateSupportFacadesSchema; и модификацию метода bootSchema::defaultStringLength(191);) таким вот образом:

use IlluminateSupportFacadesSchema;

public function boot()
{
    Schema::defaultStringLength(191);
}

Таким образом модифицированный файл с классом AppServiceProvider будет иметь вид (добавляется 6-я и 26-я строки):

<?php

namespace AppProviders;

use IlluminateSupportServiceProvider;
use IlluminateSupportFacadesSchema;
class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Schema::defaultStringLength(191);
    }
}

После сохранения этих изменений, команда php artisan migrate работает без ошибок, все миграции применяются и проект на фреймворке Laravel оживает. =)

Важно(!)
Перед тем, как накатывать повторно миграции, удалите созданные ранее таблицы из базы данных.
Иначе будет новая ошибка! ;)

По материалам:
laravel-news.com

Заберите ссылку на статью к себе, чтобы потом легко её найти!
Выберите, то, чем пользуетесь чаще всего:

Согласно информации портала laravel-news, начиная с версии Laravel 5.4 были внесены изменения в дефолтный charset базы данных. Если быть более точным, то 25.10.2016 года Taylor Otwell сделал соответствующий коммит с аннотацией «use utf8mb4 as default character set». Данная кодировка поддерживает хранение emoji.

Таким образом, во всех современных релизах Laravel, после 25.10.16 установлена кодировка по умолчанию utf8mb4. Именно она и вызывает ошибку Specified key was too long. Однако, ошибка не должна проявляться при выполнении миграции для БД MySQL v5.7.7 или старше или MariaDB старше чем 10.2.2.

Но что же делать, если у Вас все таки при выполнении миграций:

php artisan migrate

 в консоли появляется вот такая неприятная ошибка?

IlluminateDatabaseQueryException  : SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 1000 bytes (SQL: alter table `users` add unique `users_email_unique`(`email`))

Exception trace:

1   DoctrineDBALDriverPDOException::("SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 1000 bytes")

Ну что же, если Вам не повезло и подобная ошибка все таки появилась — не расстраивайтесь. Она довольно быстро и легко исправляется и сейчас я расскажу, как это можно сделать.

Варианты исправления ошибки Laravel: Specified key was too long

Собственно, как и всегда, у нас на выбор есть несколько вариантов решения данной проблемы. Рассмотрим их далее по очереди:

1. Переход на более новую версию MySQL

Это наиболее очевидный вариант. И если вы только создаете новое приложение, то конечно же лучше сразу выбрать более новую версию MySQL. Зачем разрабатывать на устаревших технологиях? Но! Если у вас шаред хостинг, то скорее всего опция смены версии БД у вас отсутствует.

2.  Изменить параметр defaultStringLegth

Если открыть оф. документацию Laravel в разделе «Создание Индексов», то разработчики фреймворка советуют установить вручную параметр defaultStringLegth равным 191 символам для более старых версий MySQL или MariaDB. Сделать это возможно, вызвав метод Schema::defaultStringLength внутри AppServiceProvider. Для этого открываем файл:

nano app/Providers/AppServiceProvider.php

и добавляем вызов в методе boot, предварительно импортировав неймспейс Schema:

use IlluminateSupportFacadesSchema;

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Schema::defaultStringLength(191);
}

После этого Ваши миграции будут успешно выполняться.

3. Уменьшить длину строки в отдельно взятой миграции

Вместо глобального изменения длины строки для всех миграций, возможно изменить длину строки непосредственно для определенной таблицы. К примеру, изменим значение длины строки для миграции, создающей таблицу пользователей:

Schema::defaultStringLength(191);

Schema::create('users', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->string('email')->unique();
    $table->timestamp('email_verified_at')->nullable();
    $table->string('password');
    $table->rememberToken();
    $table->timestamps();
});

4. Уменьшить длину индекса, но не уменьшать длину строки

Аналогично, тому как можно устанавливать длину строки непосредственно при выполнении миграции в отедльно взятую таблицу, можно уменьшить длину индекса в поле, но не уменьшать при этом длину самого поля. Для этого все в том же файле миграции нужно добавить:

$table->index([DB::raw('email(191)')]);

5. Изменить кодировку в таблице на utf8

Не знаю как Вам, но лично мне не сильно нравится рекомендуемый вариант с уменьшением длины строки. Вместо этого я предпочитаю изменить кодировку по умолчанию в своей БД на utf8, т.к. хранить emoji я в ней явно не планирую. За одно я всегда помимо смены кодировки (charset), еще и меняю сравнение (collation) на utf8_general_ci. Для этого в файле конфигурации БД:

nano app/config/database.php

я меняю для mySQL соответствующие значения на:

'charset' => 'utf8',
'collation' => 'utf8_general_ci',

Теперь у Вас всё должно работать как полагается! Если у Вас остались вопросы — смело задавайте в комментариях.

Instead of adding Schema::defaultStringLength(191); in the AppServiceProvider  boot method as described below, rather upgrade your version of MariaDB as outlined in our How to upgrade MariaDB from 10.1 to 10.3 Ubuntu Bionic (18.04) LTS Server Knowledgebase article.

Otherwise if upgrading is not possible, then do the following:

You try to do a normal migration on a new Linux PHP MySQL server and instead of the  default users table migration working, you get the following:

IlluminateDatabaseQueryException  : SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `users` add unique `users_email_unique`(`email`))
  at /home/arb/bitcoin-spread/vendor/laravel/framework/src/Illuminate/Database/Connection.php:664
    660|         // If an exception occurs when attempting to run a query, we'll format the error
    661|         // message to include the bindings with SQL, which will make this exception a
    662|         // lot more helpful to the developer instead of just the database's errors.
    663|         catch (Exception $e) {
  > 664|             throw new QueryException(
    665|                 $query, $this->prepareBindings($bindings), $e
    666|             );
    667|         }
    668|

  Exception trace:
  1   PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes")
      /home/arb/bitcoin-spread/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458
  2   PDOStatement::execute()
      /home/arb/bitcoin-spread/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458

  Please use the argument -v to see more details.

There is some key length incompatibility between the old MySQL database and the new one.

The solution is to add:

use Schema;

and

Schema::defaultStringLength(191);

to the AppServiceProvider boot method.

This file is in:

./app/Providers/AppServiceProvider.php

You can look for it using the command below:

find . -name "AppServiceProvider.php"

If you’ve already migrated doing ‘php artisan migrate’ is going to fail so rather do ‘php artisan migrate:fresh –seed’

Reference:
https://laravel-news.com/laravel-5-4-key-too-long-error but this is also documented in the Laravel Docs

Понравилась статья? Поделить с друзьями:
  • Sqlstate 42000 syntax error or access violation 1059 identifier name
  • Sqlstate 42000 native error 3271
  • Sqlstate 42000 error code 1064
  • Sqlstate 42000 error 229
  • Sqlstate 23502 not null violation 7 error