web-dev-qa-db-de.com

Laravel-Migration: Eindeutiger Schlüssel ist zu lang, selbst wenn angegeben

Ich versuche, einen Benutzertisch in Laravel zu migrieren. Wenn ich meine Migration durchführe, erhalte ich folgende Fehlermeldung:

[Illuminate\Database\QueryException] SQLSTATE [42000]: Syntaxfehler oder Zugriffsverletzung: 1071 Angegebener Schlüssel war zu lang; maximale Schlüssellänge ist 767 Byte (SQL: alter table users add unique users_email_uniq (email))

meine Migration ist wie folgt:

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

Nach etwas Googeln stieß ich auf diesen Fehlerbericht , in dem Taylor sagt, dass Sie den Indexschlüssel als zweiten Parameter von unique() angeben können, was ich getan habe. Es gibt immer noch den Fehler. Was geht hier vor sich?

127
harryg

Geben Sie eine kleinere Länge für Ihre E-Mail an:

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

Welches ist eigentlich der Standard:

$table->string('email');

Und du solltest gut sein.

Für Laravel 5.4 finden Sie eine Lösung in dieser Laravel 5.4: Angegebener Schlüssel war zu lang Fehler, Laravel News post:

Wie im Migrationshandbuch beschrieben, um dies zu beheben, müssen Sie lediglich die Datei AppServiceProvider.php bearbeiten und in der Boot-Methode eine Standardzeichenfolgenlänge festlegen:

use Illuminate\Support\Facades\Schema;

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

Update 1

Ab Laravel 5.4 sind diese Änderungen nicht mehr erforderlich.

Laravel 5.4 verwendet standardmäßig den Zeichensatz utf8mb4, der die Speicherung von "Emojis" in der Datenbank unterstützt. Wenn Sie Ihre Anwendung von Laravel 5.3 aktualisieren, müssen Sie nicht zu diesem Zeichensatz wechseln.

Update 2

Aktuelle MariaDB-Versionen der Produktion DO NOT unterstützen diese Einstellung standardmäßig global. Es ist standardmäßig in MariaDB 10.2.2+ implementiert .

Lösung

Und wenn Sie absichtlich den korrekten Future-Standard (ab Laravel 5.4) verwenden möchten, unterstützt UTF8 Multibyte utf8mb4 für ???? dann anfangen zu beheben ???? Ihre Datenbankkonfiguration.

In Laravel config/database.php definieren Sie:

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

DYNAMIC erlaubt das Speichern von long key indexes.

Servereinstellungen (standardmäßig in MySQL 5.7.7+/MariaDB 10.2.2+ enthalten):

[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

Für Kunden:

[mysql]
default-character-set=utf8mb4

Und dann STOP Ihren MySQL/MariaDB-Server. Nach diesem START. Hot RESTART funktioniert möglicherweise nicht.

Sudo systemctl stop mysqld
Sudo systemctl start mysqld

Jetzt haben Sie Laravel 5.x mit UTF8-Unterstützung.

95
scorer

Wenn Sie sich auf Laravel 5.4 befinden oder ein Update von diesem System erhalten haben, funktionierte dies für mich.

Nur 1 Änderung. in AppServiceProvider.php

use Illuminate\Support\Facades\Schema;

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

Wie im Migrationshandbuch erwähnt https://laravel.com/docs/master/migrations#creating-indexes

41
varta

Wenn jemand anderes auf diese Antwort stößt wie ich, aber aus einem anderen Grund, können Sie Ihren Laravel DB-Zeichensatz/die Kollatierung überprüfen.

Ich installierte eine Anwendung (Snipe-IT) und hatte die Laravel-Datenbankkonfiguration für die Verwendung der folgenden Konfiguration konfiguriert:

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

Durch das Entfernen von mb4 aus beiden Zeichenketten wurde das Problem behoben. Ich glaube jedoch, dass die Antwort von Antonio die wirkliche Lösung des Problems ist.

32
Brendan

Das hat für mich funktioniert: 

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

18
user3278647

Entfernen Sie mb4 aus dem Zeichensatz und der Kollatierung aus der Datei config/database.php. Anschließend wird es erfolgreich ausgeführt.
'Zeichensatz' => 'utf8',
'Kollatierung' => 'utf8_unicode_ci',

13
Ramv V

Bei Laravel 5.4 einfach die Datei bearbeiten 

App\Providers\AppServiceProvider.php

use Illuminate\Support\Facades\Schema;

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

Für Laravel 5.6 
Diese Lösung löst mein Problem 
gehe zu config/database.php 
Den Code finden Sie unten

'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,
],

Ändern Sie dieses Feld 

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

Mit diesem 

'charset' => 'utf8',
'collation' => 'utf8_unicode_ci'
10
Avijit Mandal

Ich bin mit demselben Problem konfrontiert und habe es behoben, indem ich die beiden folgenden Zeilen in meiner app/database.php eingefügt habe

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

Meine Datei sieht wie folgt aus:

<?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

In der Datei config/database.php wo:

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

Ändern Sie diese Zeile so:

'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

ich hatte das gleiche Problem und benutze einen Wamp 

Lösung: Datei öffnen: Config/database.php

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

Vielen Dank

4
Purvesh

Ich habe die Migration selbst hinzugefügt

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

ja, ich weiß, ich muss es bei jeder Migration in Betracht ziehen, aber ich würde es lieber tun, als es bei einem völlig unabhängigen Service-Provider zu suchen

4
Manoj Thapliyal

für Laravel 5.7 schreiben Sie diesen Code in appserviceprovider.php

  use Illuminate\Support\Facades\Schema;

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

Wenn jemand dieses Problem auch nachher hat, ändert sich der oben erwähnte. In meinem Fall habe ich beispielsweise folgende Änderungen vorgenommen: 

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

Aber aus zwei Gründen würde es nicht gleich funktionieren. Wenn Sie Lumen anstelle von Laravel verwenden, müssen Sie diese Zeile in Ihrer app.php-Datei zuerst auskommentieren. 

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

Und dann müssen Sie das Migrationsskript erneut mit dem handwerklichen Befehl erstellen. 

php artisan make:migration <your_table_name>

Seitdem funktionieren nur die Änderungen, die Sie an ServiceProvider vorgenommen haben.

2
dilantha111

Es liegt daran, dass Laravel 5.4 verwendet utf8mb4 das Speichern von Emojis unterstützt.

Fügen Sie dies in Ihre app\Providers\AppServiceProvider.php ein.

use Illuminate\Support\Facades\Schema;

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

und du solltest gut sein.

2
Irteza Asad

Wenn Sie Laravel 5.4 oder die aktuellste Version verwenden oder ein Update davon erhalten, funktioniert es.
Nur 1 Änderung in AppServiceProvider.php

use Illuminate\Support\Facades\Schema;

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

Für Laravel> = 5.6 Benutzer

AppServiceProvider.php-Datei öffnen

Verwenden Sie die folgende Klasse

use Illuminate\Support\Facades\Schema;

Fügen Sie dann in der boot-Methode die folgende Zeile hinzu

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

Laravel verwendet standardmäßig den Zeichensatz utf8mb4, der die Speicherung von "Emojis" in der Datenbank unterstützt. Wenn Sie eine ältere MySQL-Version als 5.7.7 oder eine ältere MariaDB-Version als 10.2.2 ausführen, müssen Sie möglicherweise die von Migrationen generierte Standardzeichenfolgenlänge manuell konfigurieren, damit MySQL Indizes für sie erstellt. Sie können dies konfigurieren, indem Sie die Schema::defaultStringLength-Methode in Ihrer AppServiceProvider aufrufen:

use Illuminate\Support\Facades\Schema;

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

Sie können auschecken

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

1
Barakat Turki

Ich hatte ein Problem, die Konfiguration der 'config/database' ändern 

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

das gleiche Muster in der Datenbank beibehalten.

Ich gab dann den Befehl

php artisan migrate

Ich möchte das zeigen, was ich vermisst habe ...

Ich bin neu bei Laravel, und ich habe das "use Illuminate ....." nicht kopiert, weil ich wirklich keine Beachtung geschenkt habe, denn direkt über der Funktion boot haben Sie bereits eine use - Anweisung.

Hoffe das hilft jedem

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

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

Ändern Sie den Zeichensatz in 'utf8mb4' in 'utf8' und

kollation zu 'utf8mb4_unicode_ci' zu 'utf8_unicode_ci'

in der Datei config/database.php

Es hat für mich funktioniert.

1
Chetan Godhani

fügen Sie diese Zeile oben ein

use Illuminate\Support\Facades\Schema;

dann fügen Sie diese in der Boot-Funktion hinzu 

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

Am 24. Oktober 2016 Taylor Otwell kündigte der Autor von Laravel am Twitter an

"utf8mb4" ist der Standard-MySQL-Zeichensatz in Laravel 5.4, um die Emoji-Unterstützung zu verbessern. ???? Taylor Otwell Twitter Post

vor Version 5.4 war der Zeichensatz utf8

Während dieses Jahrhunderts viele Web-Apps, Chat oder eine Art Plattform, um ihre Benutzer Konversationen zu ermöglichen, und viele Leute verwenden gerne Emoji oder Smiley. Dies ist eine Art Superzeichen, für die mehr Leerzeichen gespeichert werden müssen. Dies ist nur möglich, wenn utf8mb4 als charset verwendet wird. Aus diesem Grund migrieren sie nur aus Platzgründen zu utf8mb4.

wenn Sie in der Illuminate\Database\Schema\Builder-Klasse nachschlagen, werden Sie feststellen, dass $defaultStringLength auf 255 gesetzt ist. Wenn Sie Änderungen vornehmen möchten, können Sie die Schema-Fassade verwenden und defaultStringLength Methode und geben Sie die neue Länge.

um diese Änderung durchzuführen, rufen Sie diese Methode in Ihrer AppServiceProvider-Klasse auf, die sich im folgenden Unterverzeichnis app\provider befindet

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
}

Ich werde vorschlagen, 191 als Wert zu verwenden, nur weil MySQL 767 Bytes unterstützt und weil 767 / 4 die Anzahl der Bytes ist, die von jedem Multibyte-Zeichen übernommen werden, 191.

Hier erfahren Sie mehr Der utf8mb4-Zeichensatz (4-Byte-UTF-8-Unicode-Codierung)Grenzen der Tabellenspaltenanzahl und Zeilengröße

0
Yves Kipondo

Ich habe gerade MariaDB 10.2.4 RC installiert, ein neues leeres Laravel 5.4-Projekt gestartet und die Standardmigration (varchar (255) -Spalten) funktioniert.

Es ist nicht notwendig, DB conf und Laravael config/database.php zu ändern. So wie @scorer über das Standardverhalten für 10.2.2 und höher berichtet hat.

0
kroko

Datenbank-Engine InnoDB einstellen:

  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

Geben Sie eine kürzere Länge für Ihre E-Mail-Zeichenfolge an, z.

$table->string('email',128)->unique(); //In create user table

Und

$table->string('email',128)->index(); // create password resets table

Das wird auf jeden Fall funktionieren.

0
Abid Shah

Wenn dieser Fehler angezeigt wird, müssen Sie auf jeden Fall die folgenden Änderungen an der AppServiceProvider.php-Datei vornehmen -> die in app->providers: gefunden werden kann.

Änderungen vorgenommen werden

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
}

dies sollte Ihr Problem lösen, da Sie mehr über die Laravel-Nachrichten zu diesem Problem erfahren können. https://laravel-news.com/laravel-5-4-key-too-long-error

0
Sandesh Poudel

Geben Sie eine kleinere Länge für Ihre E-Mail an:

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

100 WERKE

0
Pir Abdul

Alles wurde in den anderen Anwiers gut beschrieben Sie können weitere Details im Link unten sehen (Suche mit Schlüssel 'Index Lengths & MySQL/MariaDB ") https://laravel.com/docs/5.5/ Migrationen

Aber gut, darum geht es in dieser Antwort nicht! die Sache ist auch mit dem oben genannten Sie werden gerne einen anderen Fehler bekommen (das ist, wenn Sie den Befehl php artisan migrate starten möchten und wegen des Problems der Länge die Operation wie in der Mitte feststeckt. Lösung ist untenstehend, und die Benutzertabelle ist wie der Rest oder nicht ganz korrekt erstellt.) wir müssen bac k rollen. Das Standard-Rollback funktioniert nicht. weil die Operation der Migration nicht fertig war. Sie müssen die neu erstellten Tabellen in der Datenbank manuell löschen.

wir können es wie unten beschrieben basteln:

L:\todos> php artisan tinker

Psy Shell v0.8.15 (PHP 7.1.10 — cli) by Justin Hileman

>>> Schema::drop('users')

=> null

Ich selbst hatte ein Problem mit dem Benutzertisch. 

danach ist es gut zu gehen

php artisan migrate:rollback

php artisan migrate
0
Mohamed Allal

Dieses Problem tritt nicht auf, wenn Sie MySQL 5.7.7+ oder MariaDB 10.2.2+ verwenden.

Um MariaDB auf Ihrem Mac mithilfe von Brew zu aktualisieren, trennen Sie zunächst die Verknüpfung: brew unlink mariadb und installieren Sie dann einen dev mit brew install mariadb --devel

Nachdem die Installation abgeschlossen ist, stoppen/starten Sie den Dienst, der ausgeführt wird: brew services stop mariadb brew services start mariadb

Die aktuelle dev-Version ist 10.2.3. Nachdem die Installation abgeschlossen ist, müssen Sie sich nicht mehr darum kümmern, und Sie können utf8mb4 (das ist jetzt in Laravel 5.4 standardmäßig verwendet) verwenden, ohne auf utf8 zu wechseln oder den AppServiceProvider wie in der Laravel-Dokumentation vorgeschlagen zu bearbeiten: https://laravel.com/docs/master/releases#laravel-5.4 (nach unten scrollen zu: Standardlänge der Migration)

0
Richard Dawson

LÖSUNG:

Ändern Sie zunächst die defaultStringLength in 191 in app\Providers\AppServiceProvider.php:

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

Ändern Sie anschließend die Werte für charset und collation in config\database.php:

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

( Link zu MariaDB-Zeichensatz )

0
Naveen Kumar V

Wenn Sie alle anderen Antworten ausprobiert haben und sie nicht funktioniert haben, können Sie alle Tabellen aus der Datenbank löschen und dann den Migrationsbefehl mit diesem Befehl auf einmal ausführen:

php artisan migrate:fresh
0
Treasure