it-swarm.com.ru

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

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

[Осветить\База данных\QueryException] SQLSTATE [42000]: синтаксическая ошибка или нарушение прав доступа: 1071 Указан слишком длинный ключ; максимальная длина ключа 767 байт (SQL: изменить таблицу 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');
});

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

127
harryg

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

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

Что по умолчанию, на самом деле:

$table->string('email');

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

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

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

use Illuminate\Support\Facades\Schema;

public function boot()
{
    Schema::defaultStringLength(191);
}
224
Antonio Carlos Ribeiro

Обновление 1

Начиная с Laravel 5.4 эти изменения больше не нужны.

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

Обновление 2

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

Решение

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

В Laravel config/database.php определите:

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

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

Настройки сервера (по умолчанию включены в 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

А затем ОСТАНОВИТЕ ваш сервер MySQL/MariaDB. После этого СТАРТ. Горячая перезагрузка может не работать.

Sudo systemctl stop mysqld
Sudo systemctl start mysqld

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

95
scorer

Если вы включены или обновлены до 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

41
varta

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

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

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

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

32
Brendan

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

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

18
user3278647

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

13
Ramv V

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

App\Providers\AppServiceProvider.php

use Illuminate\Support\Facades\Schema;

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

Для 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'
10
Avijit Mandal

Я столкнулся с той же проблемой и исправил ее, добавив две строки ниже в мой app/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
Muthu17

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

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

Измените эту строку на эту:

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

TO ->
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
5
Faizan Noor

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

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

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

Спасибо

4
Purvesh

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

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

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

4
Manoj Thapliyal

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

  use Illuminate\Support\Facades\Schema;

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

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

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.

2
dilantha111

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

Добавьте это в ваш app\Providers\AppServiceProvider.php

use Illuminate\Support\Facades\Schema;

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

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

2
Irteza Asad

Если вы используете или обновили Laravel 5.4 и последнюю версию, это работает;
Просто 1 изменение в AppServiceProvider.php

use Illuminate\Support\Facades\Schema;

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

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

Открыть файл AppServiceProvider.php

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

use Illuminate\Support\Facades\Schema;

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

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

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-errorhttps://laravel.com/docs/5.5/migrations#indexes

1
Barakat Turki

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

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

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

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

php artisan migrate
1
Emerson Santana Cunha

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

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

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

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

public function boot()
{
    Schema::defaultStringLength(191);
}
1
Samuel Aiala Ferreira

Измените кодировку с utf8mb4 на utf8 и

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

в файле config/database.php

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

1
Chetan Godhani

включить эту строку сверху

use Illuminate\Support\Facades\Schema;

затем внутри функции загрузки добавить это 

public function boot()
{
    Schema::defaultStringLenght(191);
}
0
Danish Jamshed

24 октября 2016 года Taylor Otwell объявил об авторе Laravel в Твиттере

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

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

В течение этого столетия многие веб-приложения, включая чат или какую-то другую платформу, позволяли пользователям общаться, и многим людям нравится использовать смайлики или смайлики. и это какие-то суперсимволы, которые требуют больше места для хранения, и это возможно только при использовании utf8mb4 в качестве charset. Вот почему они мигрируют в 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-байтовая кодировка UTF-8 Unicode)Ограничения на количество столбцов таблицы и размер строки

0
Yves Kipondo

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

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

0
kroko

Установить движок базы данных 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();
        });
0
Harshad Vala

Если вы видите эту ошибку, то вам определенно необходимо внести следующие изменения в файл 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

0
Sandesh Poudel

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

НО ХОРОШО, это не то, о чем этот ответ! дело даже в том, что, выполнив вышеизложенное вы захотите получить еще одну ошибку (вот когда вам нравится команда запуска php artisan migrate и из-за проблемы длины, операция, как застрявшая в середине. solution ниже, и пользовательская таблица как будто создана без остатка или не совсем корректно) нам нужно бросить 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
0
Mohamed Allal

У вас не будет этой проблемы, если вы используете 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 (прокрутите вниз до: Длина строки переноса по умолчанию)

0
Richard Dawson

РЕШЕНИЕ:

Сначала измените defaultStringLength на 191, в app\Providers\AppServiceProvider.php:

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

Затем измените значения charset и collation следующим образом, в config\database.php:

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

( ссылка, чтобы знать о charset MariaDB )

0
Naveen Kumar V

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

php artisan migrate:fresh
0
Treasure