Миграция Laravel: уникальный ключ слишком длинный, даже если указан

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

[Illuminate\Database\QueryException] SQLSTATE [42000]: Синтаксическая ошибка или нарушение доступа: 1071 Указанный ключ был слишком длинным; максимальная длина ключа составляет 767 байт (SQL: alter table users добавить уникальный users_email_uniq (email))

моя миграция выглядит следующим образом:

Schema::create('users', function(Blueprint $table)
{
    $table->increments('id');
    $table->string('name', 32);
    $table->string('username', 32);
    $table->string('email', 320);
    $table->string('password', 64);
    $table->string('role', 32);
    $table->string('confirmation_code');
    $table->boolean('confirmed')->default(true);
    $table->timestamps();

    $table->unique('email', 'users_email_uniq');
});

После некоторого googling я встретил этот отчет об ошибках, где Тейлор говорит, что вы можете указать индексный ключ как второй параметр unique(), который я сделал. Он все еще дает ошибку. Что здесь происходит?

Ответ 1

Укажите меньшую длину для вашего электронного письма:

$table->string('email', 250);

Это значение по умолчанию:

$table->string('email');

И ты должен быть хорошим.

Для Laravel 5.4 вы можете найти решение в этом Laravel 5.4: Указанный ключ был слишком длинной ошибкой, сообщение Laravel News:

Как указано в Руководстве по миграции, чтобы исправить это все, что вам нужно сделать, это отредактировать файл AppServiceProvider.php и внутри метода загрузки установить длину строки по умолчанию:

use Illuminate\Support\Facades\Schema;

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

Ответ 2

Обновление 1

В Laravel 5.4 эти изменения больше не нужны.

Laravel 5.4 использует по умолчанию набор символов utf8mb4, который включает в себя поддержку для хранения "emojis" в базе данных. Если вы обновляете свое приложение из Laravel 5.3, вам не требуется переключаться на этот набор символов.

Обновление 2

Текущее исполнение версий MariaDB НЕ поддерживает этот параметр по умолчанию по всему миру. Он реализован в MariaDB 10.2.2+ по умолчанию.

Решение

И если вы намеренно хотите использовать правильное будущее-умолчанию (начиная с Laravel 5.4), многобайтовая поддержка UTF8 utf8mb4 для 😀, тогда начните исправление вашей конфигурации базы данных.

В Laravel config/database.php define:

'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',

DYNAMIC позволяет хранить индексы long key.

Настройки сервера (по умолчанию включены в MySQL 5.7.7+/MariaDB 10.2.2 +):

[mysqld]
# default character set and collation
collation-server = utf8mb4_unicode_ci
character-set-server = utf8mb4

# utf8mb4 long key index
innodb_large_prefix = 1
innodb_file_format = barracuda
innodb_file_format_max = barracuda
innodb_file_per_table = 1

Для клиентов:

[mysql]
default-character-set=utf8mb4

И затем STOP ваш сервер MySQL/MariaDB. После этого СНВ. Горячий RESTART может не работать.

sudo systemctl stop mysqld
sudo systemctl start mysqld

Теперь у вас есть Laravel 5.x с поддержкой UTF8.

Ответ 3

Если вы включены или обновлены в Laravel 5.4, это сработало для меня;

Всего 1 изменение. в AppServiceProvider.php

use Illuminate\Support\Facades\Schema;

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

Как упоминалось в руководстве по миграции https://laravel.com/docs/master/migrations#creating-indexes

Ответ 4

Если кто-то еще наткнется на этот ответ, как я, но по другой причине, вы можете проверить свою кодировку/сортировку DB Laravel.

Я устанавливал приложение (Snipe-IT) и настраивал конфигурацию базы данных Laravel для использования следующего:

'charset' => 'utf8mb4',
'collation' => 'utf8mb4_general_ci',

Удаление mb4 из обеих строк исправило проблему, хотя я считаю, что ответ Антонио - это реальное решение проблемы.

Ответ 5

Это сработало для меня:

 $table->charset = 'utf8';
 $table->collation = 'utf8_unicode_ci';

Ответ 6

Удалите mb4 из charset и сортировки из config/database.php, затем он будет успешно выполнен.
'charset' = > 'utf8',
'collation' = > 'utf8_unicode_ci',

Ответ 7

Для laravel 5.4 просто отредактируйте файл

App\Providers\AppServiceProvider.php

use Illuminate\Support\Facades\Schema;

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

Ответ 8

Для Laravel 5,6
Это решение решит мою проблему
перейдите в config/database.php
Найдите код ниже

'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' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix' => '',
    'strict' => true,
    'engine' => null,
],

Изменить это два поля

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

С этим

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

Ответ 9

Я столкнулся с той же проблемой и исправил ее, добавив две строки в мое приложение /database.php

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

Мой файл выглядит следующим образом:

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Default Database Connection Name
    |--------------------------------------------------------------------------
    |
    | Here you may specify which of the database connections below you wish
    | to use as your default connection for all database work. Of course
    | you may use many connections at once using the Database library.
    |
    */

    'default' => env('DB_CONNECTION', 'mysql'),

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

    ......

Ответ 10

File: config/database.php
change the following
FROM ->
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',

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

Ответ 11

В файле config/database.php где:

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

Измените эту строку следующим образом:

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

Ответ 12

У меня была та же проблема, и я использую wamp

Решение: Открыть файл: конфигурации /database.php

'engine' => null, => 'engine' => 'InnoDB',

Спасибо

Ответ 13

Я добавил к самой миграции

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

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

Ответ 14

Если у кого-то возникла эта проблема даже после выполнения вышеуказанных изменений. Для примера, в моем случае я сделал ниже изменения,

namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;

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

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

Но это не сработает сразу по двум причинам. Во-первых, если вы используете lumen вместо laravel, вам, возможно, придется сначала раскомментировать эту строку в файле app.php.

$app->register(App\Providers\AppServiceProvider::class);

А затем вам нужно снова создать сценарий миграции с помощью команды ремесленника,

php artisan make:migration <your_table_name>

Поскольку теперь будут работать только те изменения, которые вы внесли в ServiceProvider.

Ответ 15

для laravel 5.7 напишите этот код в appserviceprovider.php

  use Illuminate\Support\Facades\Schema;

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

Ответ 16

Измените charset на 'utf8mb4' на 'utf8' и

сопоставление с 'utf8mb4_unicode_ci' в 'utf8_unicode_ci'

в файле config/database.php

Это сработало для меня.

Ответ 17

Это потому, что Laravel 5.4 использует utf8mb4, который поддерживает сохранение emojis.

Добавьте это в свое приложение\Провайдеры\AppServiceProvider.php

use Illuminate\Support\Facades\Schema;

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

и вам должно быть хорошо идти.

Ответ 18

Если вы на или обновлены до версии Laravel 5.4 и последней версии, она работает.
Всего 1 изменение в AppServiceProvider.php

use Illuminate\Support\Facades\Schema;

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

Ответ 19

Для пользователей Laravel> = 5.6

Откройте файл AppServiceProvider.php

Используйте следующий класс

use Illuminate\Support\Facades\Schema;

Затем внутри метода boot добавьте следующую строку

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

Ответ 20

Laravel использует набор символов utf8mb4 по умолчанию, который включает в себя поддержку для хранения "emojis" в базе данных. Если вы используете версию MySQL старше версии 5.7.7 или MariaDB старше версии 10.2.2, вам может потребоваться вручную настроить длину строки по умолчанию, сгенерированную миграциями, чтобы MySQL создавал для них индексы. Вы можете настроить это, вызвав метод Schema::defaultStringLength в своем AppServiceProvider:

use Illuminate\Support\Facades\Schema;

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

Вы можете проверить

https://laravel-news.com/laravel-5-4-key-too-long-error https://laravel.com/docs/5.5/migrations#indexes

Ответ 21

Я хотел бы указать на то, что я пропустил...

Я новичок в Laravel, и я не скопировал "использовать Illuminate.....", потому что я действительно не обращал внимания, потому что прямо над загрузкой функции, которую вы уже прочитали, есть оператор использования.

Надеюсь, это поможет кому-нибудь

**use Illuminate\Support\Facades\Schema;**

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

Ответ 22

У меня возникла проблема, измените конфигурацию "config/database"

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

сохраняя тот же шаблон в базе данных.

Затем я дал команду

php artisan migrate

Ответ 23

24 октября 2016 года Тейлор Отвелл, автор Laravel, объявил в Твиттере

"utf8mb4" будет набором символов MySQL по умолчанию в Laravel 5.4 для лучшей поддержки смайликов. Twitter Taylor Otwell Twitter Post

который до версии 5.4 набор символов был utf8

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

если вы посмотрите в классе Illuminate\Database\Schema\Builder то увидите, что для $defaultStringLength установлено значение 255, и для его изменения вы можете пройти через фасад Schema вызвать метод defaultStringLength и передать новую длину.

чтобы выполнить это изменение, вызовите этот метод в вашем классе AppServiceProvider который находится в подкаталоге app\provider, например:

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        // all other code ...

        Schema::defaultStringLength(191); 
    }
    // and all other code goes here
}

Я предложу использовать 191 в качестве значения только потому, что MySQL поддерживает 767 байт, а также потому, что 767/4 есть число байтов, которое занимает каждый многобайтовый символ, вы получите 191.

Вы можете узнать больше здесь Ограничения набора символов utf8mb4 (4-байтовое кодирование Unicode UTF-8) для числа столбцов таблицы и размера строки

Ответ 25

У вас не будет этой проблемы, если вы используете MySQL 5.7.7+ или MariaDB 10.2.2 +.

Чтобы обновить MariaDB на вашем Mac, используя Brew, сначала отмените текущий: brew unlink mariadb, а затем установите dev с помощью brew install mariadb --devel

После завершения установки остановить/запустить запущенную службу: brew services stop mariadb brew services start mariadb

Текущая версия для разработчиков - 10.2.3. После завершения установки вам больше не придется об этом беспокоиться, и вы можете использовать utf8mb4 (теперь это значение по умолчанию в Laravel 5.4), не возвращаясь к utf8 и не редактируя AppServiceProvider, как это предлагается в документации Laravel: https://laravel.com/docs/master/releases#laravel-5.4 (прокрутите вниз до: Миграция длины строки по умолчанию)

Ответ 26

Просто установлен MariaDB 10.2.4 RC, запускается новый пустой проект Laravel 5.4 и по умолчанию (столбцы varchar (255)).

Не нужно изменять DB conf и Laravael config/database.php. Таким образом, как @scorer отметил поведение по умолчанию для 10.2.2 +.

Ответ 27

Все было хорошо описано в других Anwser, более подробную информацию вы можете увидеть в ссылке ниже (поиск по ключу "Длина индекса и MySQL/MariaDB") https://laravel.com/docs/5.5/migrations

НО ХОРОШО, ЧЕМ НЕ О ЧЕМ ЭТО ОТВЕТ! дело даже в том, что, выполнив вышесказанное, вы захотите получить еще одну ошибку (когда вам нравится команда запуска php artisan migrate и из-за проблемы длины, операция как застрявшая посередине. решение ниже, а пользовательская таблица как созданный без остального или не совсем правильно) нам нужно бросить bac k. откат по умолчанию не подойдет. потому что операция миграции не понравилась. Вам необходимо удалить новые созданные таблицы в базе данных вручную.

мы можем сделать это с помощью повозки, как показано ниже:

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

Ответ 28

Установить движок базы данных InnoDB:

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

Ответ 29

Если вы попробовали все остальные ответы, но они не сработали, вы можете удалить все таблицы из базы данных, а затем сразу выполнить команду migrate, используя эту команду:

php artisan migrate:fresh

Ответ 30

Если вы видите эту ошибку, то, безусловно, вам нужно внести следующие изменения в файл AppServiceProvider.php ->, который можно найти внутри app->providers:

изменения должны быть сделаны

use Illuminate\Support\Facades\Schema; //see if you have this class if not add it.

public function boot()
{
    Schema::defaultStringLength(191); //make sure you add this line
}

это должно решить вашу проблему, чтобы больше вы могли видеть новости Laravel относительно этой проблемы. https://laravel-news.com/laravel-5-4-key-too-long-error