As @Devart says, the total length of your index is too long.
The short answer is that you shouldn’t be indexing such long VARCHAR columns anyway, because the index will be very bulky and inefficient.
The best practice is to use prefix indexes so you’re only indexing a left substring of the data. Most of your data will be a lot shorter than 255 characters anyway.
You can declare a prefix length per column as you define the index. For example:
...
KEY `index` (`parent_menu_id`,`menu_link`(50),`plugin`(50),`alias`(50))
...
But what’s the best prefix length for a given column? Here’s a method to find out:
SELECT
ROUND(SUM(LENGTH(`menu_link`)<10)*100/COUNT(`menu_link`),2) AS pct_length_10,
ROUND(SUM(LENGTH(`menu_link`)<20)*100/COUNT(`menu_link`),2) AS pct_length_20,
ROUND(SUM(LENGTH(`menu_link`)<50)*100/COUNT(`menu_link`),2) AS pct_length_50,
ROUND(SUM(LENGTH(`menu_link`)<100)*100/COUNT(`menu_link`),2) AS pct_length_100
FROM `pds_core_menu_items`;
It tells you the proportion of rows that have no more than a given string length in the menu_link
column. You might see output like this:
+---------------+---------------+---------------+----------------+
| pct_length_10 | pct_length_20 | pct_length_50 | pct_length_100 |
+---------------+---------------+---------------+----------------+
| 21.78 | 80.20 | 100.00 | 100.00 |
+---------------+---------------+---------------+----------------+
This tells you that 80% of your strings are less than 20 characters, and all of your strings are less than 50 characters. So there’s no need to index more than a prefix length of 50, and certainly no need to index the full length of 255 characters.
PS: The INT(1)
and INT(32)
data types indicates another misunderstanding about MySQL. The numeric argument has no effect related to storage or the range of values allowed for the column. INT
is always 4 bytes, and it always allows values from -2147483648 to 2147483647. The numeric argument is about padding values during display, which has no effect unless you use the ZEROFILL
option.
NO_ENGINE_SUBSTITUTION disabled with INNODB not active, a bad combination
- Up to MySql 5.5 the sqlmode default was a blank string, that means that the sqlmode NO_ENGINE_SUBSTITUTION was not set by default
According to MySql docs (see https://dev.mysql.com/doc/refman/5.6/en/sql-mode.html#sqlmode_no_engine_substitution) this is the meaning of sqlmode NO_ENGINE_SUBSTITUTION:
Control automatic substitution of the default storage engine when a
statement such as CREATE TABLE or ALTER TABLE specifies a storage
engine that is disabled or not compiled in.Because storage engines can be pluggable at runtime, unavailable
engines are treated the same way:With NO_ENGINE_SUBSTITUTION disabled, for CREATE TABLE the default
engine is used and a warning occurs if the desired engine is
unavailable. For ALTER TABLE, a warning occurs and the table is not
altered.With NO_ENGINE_SUBSTITUTION enabled, an error occurs and the table is
not created or altered if the desired engine is unavailable.
- So: if NO_ENGINE_SUBSTITUTION is disabled AND INNODB is switched OFF, MySql will switch to MYISAM also if you specify INNODB in your CREATE TABLE statement.
- If the table you are creating is OK for MYISAM, you just receive a warning and the table is created. That is not your case, your creation statement include an index that is beyond the 1000 bytes limit of MYISAM, then the creation fails with error 1071 reporting the error of MYISAM. That is because the working engine is MYISAM, not INNODB.
PROOF
MySql version 5.1.56 community
Case 1:
Options in my.cnf
sql-mode=""
default-storage-engine=MYISAM
skip-innodb uncommented (without#)
Return on execution of your create statement:
Error Code: 1071. Specified key was too long; max key length is 1000 bytes
Explanation: INNODB is not active, the engine is automatically switched to MYISAM
that returns this error as they key is longer than MYISAM 1000 bytes limit.
The key length is:
2 fields x 255 char x 3 bytes utf8 encoding + 2 x 1 length byte = 1532 bytes
Case 2:
Options in my.cnf
sql-mode="NO_ENGINE_SUBSTITUTION"
default-storage-engine=MYISAM
skip-innodb uncommented (without#)
Return on execution of your create statement:
Error Code: 1286. Unknown table engine 'INNODB'
Explanation: INNODB is not active but the engine substitution is not permitted
by sql mode therefore the DB returns an error about the attempt of using a disabled engine.
Case 3:
Options in my.cnf
sql-mode="NO_ENGINE_SUBSTITUTION"
default-storage-engine=MYISAM
skip-innodb commented (with#)
Return on execution of your create statement:
Table creation OK!
Explanation: INNODB is active (skip-innodb commented) and it is used also if
the default engine is MYISAM.
To reproduce the tests restart MySql after every change in my.cnf.
Since MySql version 5.6 sqlmode is no more empty by default and contains NO_ENGINE_SUBSTITUTION, moreover INNODB is the default engine, so the error is difficult to meet.
OTHER TESTS
No other way of reproducing the error:
Error Code: 1071. Specified key was too long; max key length is 1000 bytes
while trying to create an INNODB table has been found.
In INNODB you have two kinds of ERROR 1071:
Error Code: 1071. Specified key was too long; max key length is 767 bytes
this has nothing to do with innodb_large_prefix ON or OFF, but is only related to the size of a single VARCHAR column being used as an index.
Mysql store varchar utf8 with 3 bytes plus 1 byte for the length up 255 character and 2 after (see: http://dev.mysql.com/doc/refman/5.7/en/storage-requirements.html), so if you try to set a key with VARCHAR(256) utf8 you get:
256 x 3 + 2 = 770 bytes
and you get the previous error, as the max key length for a single column is 767 bytes for an InnoDB table. A VARCHAR(255) is ok, because:
255 x 3 + 1 = 766 bytes
I tested it on four installations of Mysql, version 5.1.56, 5.5.33, 5.6 and 5.7, and that is confirmed. No issue with your query with VARCHAR(255), issue with VARCHAR(256):
Error Code: 1071. Specified key was too long; max key length is 767 bytes
As you can see the message is different, because it is an INNODB message not a MYISAM one!
The other type of ERROR 1071 for INNODB tables is:
Error Code: 1071. Specified key was too long; max key length is 3072 bytes
This is related to keys with multiple columns. For those keys to be enabled you need to set innodb_large_prefix to on.
Anyway, if you try to run something like this:
CREATE TABLE `phppos_modules_actions` (
`action_id` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
`module_id` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
`action_name_key` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
`action_name_key1` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
`action_name_key2` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
`sort` INT NOT NULL ,
PRIMARY KEY ( `action_id` , `module_id`, `action_name_key`, `action_name_key1`, `action_name_key2` )
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci;
With a key of 5 VARCHAR(255) utf8 columns, that is 3830 bytes, you will run into the:
Error Code: 1071. Specified key was too long; max key length is 3072 bytes
Exotic Hypothesis
During the search of the cause I formulated and tested different and pretty weird hypothesis:
ROW format
Tested REDUNDANT, COMPACT, COMPRESS, DYNAMIC: no impact on table creation with your statement.
FILE format
Tested Antelope and Barracuda: no impact on table creation with your statement.
MySql built
Tested 32bit and 64 bit MySql: no impact on table creation with your statement.
Others similar failures
Here you can find the same error in the same situation:
https://www.drupal.org/node/2466287
I tested that statement in the 3 test situations listed in PROOF and it reproduced exactly the same behavior as yours, so I can say the issue is the same. In that case they switched to other DB, but the problem is the mix of setting, not the DB version.
References
A very good article of indexing with INNODB is given here:
http://mechanics.flite.com/blog/2014/07/29/using-innodb-large-prefix-to-avoid-error-1071/
WARNING: disabling INNODB by uncommenting skip-innodb in my.cnf after the creation of INNODB table with index longer than 1000 will not permit the start of MySql service
Regards
You may to have adjust some VARCHAR length in some table based on the Character Set you are using.
That exact error message is actually posted as a bug report from Nov 2004, when in fact, it is not really a bug. That should direct you on how to adjust key lengths, especially your PRIMARY KEYs.
If you know which table is causing the Error 1071
, you have to do the following:
Step 01) mysqldump only database schema
mysqldump --routines --triggers --all-databases --no-data > MySQLSchema.sql
Step 02) mysqldump only data
mysqldump --all-databases --no-create-info > MySQLData.sql
Step 03) Using vi or some other editor, edit the table’s PRIMARY KEY to manually limit the PRIMARY KEY in such a way that the key does not exceed 1000 characters.
Step 04) Load the schema
mysql -A < MySQLSchema.sql
Step 05) Load the data
mysql -A < MySQLData.sql
You may have to resort to this if you cannot otherwise figure this out,
UPDATE 2012-01-23 11:43 EDT
Since you mentioned a certain table has the wrong storage engine, here is what you do:
Look above at Step 03. Go find the table in the file. Look for ENGINE=MyISAM
in the file and change it to ENGINE=InnoDB
. Then, load the schema file first and the data file afterwards.
UPDATE 2012-01-23 11:52 EDT
You should add this to to /etc/my.cnf
[mysqld]
default-storage-engine=InnoDB
then run service mysql restart
. If you cannot restart mysql at this time, run this in the mysql client:
mysql> SET GLOBAL default_storage_engine = 'InnoDB';
However, the mysqldump will still have the ENGINE=MyISAM
at the end of each CREATE TABLE
. You will have to perform the 5-Step plan I mentioned above including changing the ENGINE=MyISAM
to ENGINE=InnoDB
. DO NOT CHANGE THAT FOR THE mysql DATABASE !!! Change only those tables that are yours.
Согласно информации портала 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',
Теперь у Вас всё должно работать как полагается! Если у Вас остались вопросы — смело задавайте в комментариях.
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
- 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
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
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
.
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 How is that solution temporary? Can it be easily reverted and start working with utf8mb4
later on?
@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',
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
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.
As explicações agregam a resposta, obrigado a todos.
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.
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).
A temporary solution would be going to your
config/database.php
and change thecharset
andcollation
fromutf8mb4
toutf8
'charset' => 'utf8', 'collation' => 'utf8_unicode_ci',
This happens because
utf8mb4
uses 4 bytes per character, and the255
character length which is greater than the limit767
bytes.255 x 4bytes = 1020b
.To fix this the
191
.191 x 4 bytes = 764b
.
Thanks, this worked !
Go in the AppProvidersAppServiceProvider class and change the boot method to look like this
use IlluminateSupportFacadesSchema;
public function boot()
{
Schema::defaultStringLength(191);
}
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).
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.
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.
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.
@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
A temporary solution would be going to your
config/database.php
and change thecharset
andcollation
fromutf8mb4
toutf8
'charset' => 'utf8', 'collation' => 'utf8_unicode_ci',
This happens because
utf8mb4
uses 4 bytes per character, and the255
character length which is greater than the limit767
bytes.255 x 4bytes = 1020b
.To fix this the
191
.191 x 4 bytes = 764b
.
This is Work for me, Thanks Dude!
A temporary solution would be going to your
config/database.php
and change thecharset
andcollation
fromutf8mb4
toutf8
'charset' => 'utf8', 'collation' => 'utf8_unicode_ci',
This happens because
utf8mb4
uses 4 bytes per character, and the255
character length which is greater than the limit767
bytes.255 x 4bytes = 1020b
.To fix this the
191
.191 x 4 bytes = 764b
.
Success!!!!
A temporary solution would be going to your
config/database.php
and change thecharset
andcollation
fromutf8mb4
toutf8
'charset' => 'utf8', 'collation' => 'utf8_unicode_ci',
This happens because
utf8mb4
uses 4 bytes per character, and the255
character length which is greater than the limit767
bytes.255 x 4bytes = 1020b
.
To fix this the191
.191 x 4 bytes = 764b
.Thanks, this worked !
Thanks, It worked
@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 thedefault-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.
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>
.
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>
> .
>
A temporary solution would be going to your
config/database.php
and change thecharset
andcollation
fromutf8mb4
toutf8
'charset' => 'utf8', 'collation' => 'utf8_unicode_ci',
This happens because
utf8mb4
uses 4 bytes per character, and the255
character length which is greater than the limit767
bytes.255 x 4bytes = 1020b
.To fix this the
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.
A temporary solution would be going to your
config/database.php
and change thecharset
andcollation
fromutf8mb4
toutf8
'charset' => 'utf8', 'collation' => 'utf8_unicode_ci',
This happens because
utf8mb4
uses 4 bytes per character, and the255
character length which is greater than the limit767
bytes.255 x 4bytes = 1020b
.To fix this the
191
.191 x 4 bytes = 764b
.
This fixed it for me. thank you so much.
@sisve Puede cambiarlo más adelante si lo desea, esta puede no ser la solución ideal si desea usar
utf8mb4
charset.Hay tres formas de resolver esto:
Cambiar la duración de la migración a
191
Cambiando la longitud
191
ao menos.$table->string('name', 191);
Cambiar la longitud predeterminada de la cadena
Cambiar la
string
longitud de tipo predeterminada (global) a191
. 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 elapp/Providers/
directorio.public function boot() { IlluminateSupportFacadesSchema::defaultStringLength(191); }
Utilizar en su
utf8
lugarutf8mb4
Esto puede no ser la ideal, pero si no se preocupan por
utf8mb4
usted puede ir a suconfig/database.php
archivo y reemplazarcharset
ycollation
alutf8
'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
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.
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()
Good afternoon @Lakshsay, could I put the Model Settings source code?
Apparently the table name is wrong — hello.core_settings.
@polares552 Yes please advice me the steps / changes needs to be done.
where exactly I need to make changes.
im a student so learning
@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.
@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.
@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!!!
A temporary solution would be going to your
config/database.php
and change thecharset
andcollation
fromutf8mb4
toutf8
'charset' => 'utf8', 'collation' => 'utf8_unicode_ci',
This happens because
utf8mb4
uses 4 bytes per character, and the255
character length which is greater than the limit767
bytes.255 x 4bytes = 1020b
.To fix this the
191
.191 x 4 bytes = 764b
.
THANKS!
Works on Heroku
A temporary solution would be going to your
config/database.php
and change thecharset
andcollation
fromutf8mb4
toutf8
'charset' => 'utf8', 'collation' => 'utf8_unicode_ci',
This happens because
utf8mb4
uses 4 bytes per character, and the255
character length which is greater than the limit767
bytes.255 x 4bytes = 1020b
.
To fix this the191
.191 x 4 bytes = 764b
.This fixed it for me. thank you so much.
wow thanks
I’m trying to create a table in MySQL with the statement:
CREATE TABLE tags (Tag VARCHAR(200) NOT NULL default '', Login VARCHAR(255) NOT NULL default '', PRIMARY KEY (Tag, Login)) ENGINE=MyISAM;
However I’m getting an error:
ERROR 1071 (42000): Specified key was too long; max key length is 1000 bytes
If I reduce the Tag field to VARCHAR(78) the table is created, however VARCHAR(79) fails. Why is any varchar size above 78 failing? I’ve read a few posts around the web about MySQL storing VARCHAR as UTF-8 which can take up to six bytes, but 79 * 6 is 474 which is well within the 1000 byte limit so not sure they UTF-8 thing is accurate.
asked Jan 11, 2013 at 15:37
Server FaultServer Fault
3,5248 gold badges52 silver badges88 bronze badges
1
Your primary key consists of both Tag and Login, which combined are 355 characters long.
If Tag is 78 characters the combined total is 333, so it looks like MySQL makes a 3-byte-per-character assumption:
(78 + 255) * 3 = 999, (79 + 255) * 3 = 1002
That said, VARCHAR values are notoriously unsuited for Primary Keys.
Consider adding an INT instead.
answered Jan 11, 2013 at 15:42
1
Странная ошибка, возникающая при выполнении первой миграции в 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;
и модификацию метода boot
: Schema::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
Заберите ссылку на статью к себе, чтобы потом легко её найти!
Выберите, то, чем пользуетесь чаще всего: