라 라벨 마이그레이션 오류 : 구문 오류 또는 액세스 위반 : 1071 지정된 키가 너무 깁니다. 최대 키 길이는 767 바이트입니다.


178

Laravel 5.4에서 마이그레이션 오류 php artisan make:auth

[Illuminate \ Database \ QueryException] SQLSTATE [42000] : 구문 오류 또는 액세스 위반 : 1071 지정된 키가 너무 깁니다. 최대 키 길이는 767 바이트입니다 (SQL : alter tabl e usersadd unique users_email_unique( email))

[PDOException] SQLSTATE [42000] : 구문 오류 또는 액세스 위반 : 1071 지정된 키가 너무 깁니다. 최대 키 길이는 767 바이트입니다.


3
당신은 대답으로 당신의 질문에 대답해야합니다. 질문에 없습니다. stackoverflow.com/help/self-answer
Vural 수

@ can-vural 제안에 감사드립니다.
absiddiqueLive

답변:


283

공식 문서 에 따르면 이것을 쉽게 해결할 수 있습니다.

AppServiceProvider.php에 다음 두 줄의 코드를 추가하십시오 (/app/Providers/AppServiceProvider.php)

use Illuminate\Database\Schema\Builder; // Import Builder where defaultStringLength method is defined

function boot()
{
    Builder::defaultStringLength(191); // Update defaultStringLength
}

MySQL은 항상 4 바이트 인 UTF8 필드의 최대량을 예약하므로 DEFAULT CHARACTER SET로 255 + 255를 사용합니다. utf8mb4 COLLATE utf8mb4_unicode_ci; 767 최대 키 길이 제한을 초과했습니다. @scaisedge 작성


3
이 솔루션에주의하십시오. 예를 들어 전자 메일 필드를 색인화하면 저장된 전자 메일의 최대 길이는 191 자입니다. 이것은 공식 RFC 상태보다 적습니다.
shock_gone_wild


작동하고 유효한 솔루션이지만이 접근법을 사용하여 가능한 함정이 있음을 지적하고 싶었습니다.
shock_gone_wild

이 솔루션이 미래의 엉덩이를 물지 않기를 바랍니다. 그러나 지금은 이것이 효과가 있습니다. 그래도 이메일 색인 생성 방법에주의해야합니다.
deusofnull

4
왜 정확히 191 자 @absiddiqueLive
PseudoAj

121

위의 솔루션과 공식 솔루션이 추가되는 이유를 모르겠습니다.

Schema::defaultStringLength(191);

에서 AppServiceProvider나를 위해 작동하지 않았다. 효과가 있었던 database.php것은 config폴더 에서 파일을 편집하는 것이 었습니다 . 그냥 편집

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

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

emoji와 같은 확장 멀티 바이트 문자를 저장할 수는 없지만 작동해야합니다 .

나는 Laravel 5.7로 해냈습니다. 도움이 되길 바랍니다.


5
이 문자 집합을 사용하면 표준 ASCII 만 저장할 수 있으며 아랍어, 히브리어, 대부분의 유럽 스크립트 및 이모티콘과 같은 멀티 바이트 특수 문자는 저장할 수 없습니다. 또한 참조 stackoverflow.com/a/15128103/4233593
제프 퍼켓

7
나는 당신이 use Illuminate\Support\Facades\Schema;상단 에이 부분을 놓친 것 같아요 .
pimpace

@KoushikDas 어떤 버전의 라 라벨을 사용하고 있습니까?
pimpace

이제 6.0에 있습니다. 나는 처음에 5.7 또는 5.6으로 그것을했다고 생각합니다.
Koushik Das

2
utf8mb4조합은 이유가있다, 당신이 할 수있는 경우에 사용하는 것이 좋습니다.
화염

85

나는이 답변을 여기에 추가하고 quickest있습니다. 기본 데이터베이스 엔진을 'InnoDB'켜기로 설정하십시오 .

/config/database.php

'mysql' => [
    ...,
    ...,
    'engine' => 'InnoDB',
 ]

그런 다음 실행 php artisan config:cache하여 구성 캐시를 지우고 새로 고칩니다.


1
이 질문에 대한 공식 답변 / 해결책이어야합니다 ... 감사합니다
Syamsoul Azrien

1
이것은 실제 해결책이며, 다른 해결책도 있습니다
Luís Cunha

3
그러나 이것의 논리는 무엇인가
Zulfiqar Tariq

1
이것이 올바른 해결책입니다. 그러나 기본 설치에 포함되지 않은 이유는 무엇입니까?
Ankit Chauhan

38

에서 AppServiceProvider.php, 당신은 파일의 코드 상단을 포함한다.

use Illuminate\Support\Facades\Schema;

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

덕분에 나를 도와
죽은 사람에게

24

이 문제는 데이터베이스 버전에 따라 Laravel 5.4에서 발생합니다.

문서 에 따르면 ( Index Lengths & MySQL / MariaDB섹션에서) :

라 라벨은 utf8mb4기본적으로 문자 세트를 사용하는데 , 여기에는 데이터베이스에 "이모 지"를 저장하는 기능이 포함됩니다. 5.7.7 릴리스 이전의 MySQL 버전 또는 10.2.2 릴리스 이전의 MariaDB를 실행중인 경우, MySQL이 인덱스를 작성하기 위해 마이그레이션에서 생성 된 기본 문자열 길이를 수동으로 구성해야 할 수도 있습니다. 에서 Schema::defaultStringLength메소드 를 호출하여이를 구성 할 수 있습니다 AppServiceProvider.

다시 말해 <ROOT>/app/Providers/AppServiceProvider.php:

// Import Schema
use Illuminate\Support\Facades\Schema;
// ...

class AppServiceProvider extends ServiceProvider
{

public function boot()
{
    // Add the following line
    Schema::defaultStringLength(191);
}

// ...

}

그러나 다른 답변에 대한 의견에서는 다음과 같이 말합니다.

이 솔루션에주의하십시오. 예를 들어 전자 메일 필드를 색인화하면 저장된 전자 메일의 최대 길이는 191 자입니다. 이것은 공식 RFC 상태보다 적습니다.

따라서 설명서에는 다른 솔루션도 제안되어 있습니다.

또는 innodb_large_prefix데이터베이스에 대한 옵션을 활성화 할 수 있습니다. 이 옵션을 올바르게 활성화하는 방법에 대한 지침은 데이터베이스 설명서를 참조하십시오.


16

변경하고 싶지 않은 사람을 위해 AppServiceProvider.php. (제 의견으로 AppServiceProvider.php는 마이그레이션을 위해서만 변경하는 것이 좋지 않습니다 )

database/migrations/아래와 같이 데이터 길이를 마이그레이션 파일에 다시 추가 할 수 있습니다 .

create_users_table.php

$table->string('name',64);
$table->string('email',128)->unique();

create_password_resets_table.php

$table->string('email',128)->index();

이메일은 최대 255 자까지 가능하므로 문제가 될 수 있습니다
Half Crazed

당신이 바로 @HalfCrazed 있습니다,하지만 난이 응답 제안 stackoverflow.com/questions/1297272
helloroy

내 문제는이 솔루션으로 정확하게 해결할 수있었습니다. 내 필드는 이메일이 아니 었습니다.
Tharaka Devinda

11

명령을 사용하는 동안 laravel에서 작업하는 동안이 오류가 발생 php artisan migrate 하면 파일에 두 줄을 추가하십시오 : app-> Providers-> AppServiceProvider.php

  1. use Schema;
  2. Schema::defaultStringLength(191);

이 이미지 를 확인 하십시오 . 그런 다음 php artisan migrate명령을 다시 실행 하십시오.


1
'use Schema;'를 추가하는 것이 매우 중요합니다. 그래서 이것이 가장 좋은 답변입니다
hxwtch

다음과 같이 두 번째 줄 앞에 백 슬래시 '\'를 추가하여 한 줄로이 작업을 수행 할 수도 있습니다\Schema::defaultStringLength(191);
Tahir Afridi

10

나는 나를 위해 두 가지 해결책 을 추가 하고 있습니다.

1 차 sollution입니다 :

  1. 열기 database.php의 파일 insde 설정 디렉토리 / 폴더에 있습니다.
  2. 편집 'engine' => null,하다'engine' => 'InnoDB',

    이것은 나를 위해 일했습니다.

두 번째 용해는 다음과 같습니다.

  1. 열기 database.php의 파일 insde 설정 디렉토리 / 폴더에 있습니다.
    2. 편집
    'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci',

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


행운을 빕니다


10

app / Providers / AppServiceProvider.php에이 줄을 업데이트하고 삽입하십시오

use Illuminate\Support\Facades\Schema;  // add this line at top of file

public function boot()
{
    Schema::defaultStringLength(191); // add this line in boot method
}

8

이 문제를 해결하고 내 데이터베이스 ( 'charset'=> 'utf8')( 'collation'=> 'utf8_general_ci') 과 같이 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' => 'utf8',
        'collation' => 'utf8_general_ci',
        'prefix' => '',
        'strict' => true,
        'engine' => null,
    ],

8

이 오류에 대한 두 가지 해결책을 찾았습니다.

옵션 1:

열려있는 사용자password_reset 테이블을 데이터베이스 / 마이그레이션의 폴더

그리고 이메일 길이를 변경하십시오.

$table->string('email',191)->unique();

옵션 2 :

app/Providers/AppServiceProvider.php파일을 열고 boot()메소드 내부에서 기본 문자열 길이를 설정하십시오.

use Illuminate\Support\Facades\Schema;

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

7

1-/config/database.php 이 줄로 이동

'mysql' => [
    ...,
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    ...,
    'engine' => null,
 ]

그것들을 다음과 같이 변경하십시오 :

'mysql' => [
    ...,
    'charset' => 'utf8',
    'collation' => 'utf8_unicode_ci',
    ...,
    'engine' => 'InnoDB',
 ]

2-라php artisan config:cache 라벨을 재구성하기 위해 실행

3- 데이터베이스에서 기존 테이블을 삭제 한 후 php artisan migrate다시 실행


1
이것이 laravel 5.8에 가장 적합한 답변입니다. 그러나 이미 생성 된 테이블 삭제
Magige Daniel

그러나 문서에 따르면 "utf8"은 더 이상 사용되지 않는 utf8 모드를 사용합니까?
NoBugs

5

에서 AppServiceProvider.php의 파일 :

 use Illuminate\Support\Facades\Schema;

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

5

길이 제한을 설정하는 대신 다음과 같이 제안했습니다.

내부:

config / database.php

이 줄을 mysql로 ​​바꾸십시오.

'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',

와:

'engine' => null,

4

이 문제를 해결하기 위해 마이그레이션 안내서 에 설명 된대로 app/Providers/AppServiceProvider.php파일을 편집 하고 부팅 방법 내에서 기본 문자열 길이를 설정하기 만하면됩니다.

use Illuminate\Support\Facades\Schema;

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

참고 : 먼저 데이터베이스에서 users 테이블, password_resets 테이블 (있는 경우)을 삭제하고 migrations 테이블 에서 users 및 password_resets 항목을 삭제해야 합니다.

미해결 마이그레이션을 모두 실행하려면 migrateArtisan 명령을 실행하십시오 .

php artisan migrate

그 후 모든 것이 정상적으로 작동합니다.


4

이미 지정한 바와 같이 App / Providers의 AppServiceProvider.php에 추가합니다

use Illuminate\Support\Facades\Schema;  // add this

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

자세한 내용은 링크 벨로우즈 ( "Index Lengths & MySQL / MariaDB"검색) https://laravel.com/docs/5.5/migrations에서 확인할 수 있습니다.

그러나 나는 그것이 전부에 관해 출판 한 것이 아니다! 위의 작업을 수행 할 때도 다른 오류가 발생할 수 있습니다 ( php artisan migrate명령 을 실행할 때 길이 문제로 인해 작업이 중간에 중단 될 수 있습니다. 솔루션이 아래 에 있으며 사용자 테이블이 생성 될 수 있음) 나머지가 없거나 완전히 올바르게되지 않은 경우) 롤백해야합니다 . 기본 롤백이 작동하지 않습니다. 마이그레이션 작업이 완료를 좋아하지 않았기 때문입니다. 데이터베이스에서 새로 작성된 테이블을 수동으로 삭제해야합니다.

우리는 아래와 같이 땜장이를 사용하여 그것을 할 수 있습니다 :

L:\todos> php artisan tinker

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

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

=> null

나 자신이 users 테이블에 문제가있었습니다.

그 후에는 잘가

php artisan migrate:rollback

php artisan migrate


4

아무도 알 수없는이 솔루션에 있다는 것입니다 MySQL의 버전 5.5 이후 InnoDB하지만 이 문제가 있지만, 많은 경우에 광산처럼 오래된 사용하는 오래된 MySQL의 INI 구성 파일이 있습니다하지 않는 기본 스토리지 엔진입니다 MYISAM의 아래와 같은 스토리지 엔진.

default-storage-engine=MYISAM

이 모든 문제가 발생하고 해결책은 임시 해킹을 수행하는 대신 Mysql의 ini 구성 파일 에서 default-storage-engine을 InnoDB 로 한 번 변경하는 것입니다.

default-storage-engine=InnoDB

그리고 MySql v5.5 이상을 사용하는 경우 InnoDB 가 기본 엔진이므로 위와 같이 명시 적으로 설정할 필요가 없으므로 파일 default-storage-engine=MYISAM에서 if가 있으면 제거하십시오 ini.


감사! 나는이 제안을 laravel 6 및 mysql 5.6에서 작동시키기 위해 문자열 길이, 문자 세트 및 데이터 정렬 변경과 함께 사용해야했습니다. 희망적으로 이것은 미래에 다른 사람들을 돕습니다.
캐스퍼 윌크스

@CasperWilkes는 문자열 길이, 문자 집합을 수행 할 필요가 없습니다. 이처럼 MySQL의 시스템 변수를 확인 show global variables like 'innodb_large_prefix';그것이 있어야 ON . 그것의 경우 OFF 당신은 확인할 수 있습니다 전원을 켜 방법에 대한 답을. 그리고 여기 dev.mysql.com의 innodb_large_prefix에 대한 자세한 정보가 있습니다.
Ali A. Dhillon

3

AppServiceProvider에서 변경하려면 마이그레이션에서 이메일 길이를 정의해야합니다. 첫 번째 코드 줄을 두 번째 줄로 바꿉니다.

create_users_table

$table->string('email')->unique();
$table->string('email', 50)->unique();

create_password_resets_table

$table->string('email')->index();
$table->string('email', 50)->index();

변경이 완료되면 마이그레이션을 실행할 수 있습니다.
참고 : 먼저 데이터베이스에서 users 테이블 , password_resets 테이블 을 삭제하고 마이그레이션 테이블에서 users 및 password_resets 항목을 삭제해야합니다.


3

Schema::defaultStringLength(191);기본적으로 모든 문자열의 길이를 정의하여 데이터베이스를 망칠 수 있습니다. 이런 식으로 가면 안됩니다.

데이터베이스 마이그레이션 클래스에서 특정 열의 길이를 정의하십시오. 예를 들어, CreateUsersTable클래스 에서 "name", "username"및 "email" 을 아래와 같이 정의하고 있습니다.

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

1
라 라벨 코어 코드를 수정하지 않기 때문에 이것은 나에게 가장 바람직합니다.
Okiemute Omuta

2

이것은 Laravel 5.4가 기본 데이터베이스 문자 세트를 utf8mb4로 변경했기 때문에 일반적입니다. 클래스 선언 앞에이 코드를 넣어 App \ Providers.php를 편집하십시오.

use Illuminate\Support\Facades\Schema;

또한 이것을 '부팅'기능에 추가하십시오 Schema::defaultStringLength(191);


2

데이터베이스에 이미 할당 된 데이터가없는 경우 다음을 수행하십시오.

  1. app / Providers / AppServiceProvide.php로 이동하여 추가하십시오

Illuminate \ Support \ ServiceProvider를 사용하십시오.

그리고 메소드 내부에서 boot ();

스키마 :: defaultStringLength (191);

  1. 이제 데이터베이스, 예를 들어 사용자 테이블의 레코드를 삭제하십시오.

  2. 다음을 실행

PHP 장인 구성 : 캐시

PHP 장인 이주


작동했지만 추가해야합니다 use Illuminate\Support\Facades\Schema; use Illuminate\Support\ServiceProvider;. 당신이 그것을 수정하기를 바랍니다
Jimish Gamit

2

마이그레이션 가이드에 설명 된대로이 문제를 해결하려면 AppServiceProvider.php 파일을 편집하고 부팅 방법 내에서 기본 문자열 길이를 설정하면됩니다.

//edit your AppServiceProvider.php file contains in providers folder
use Illuminate\Support\Facades\Schema;

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

이것이 당신을 도울 수 있기를 바랍니다.


2

방금 다음 줄 userspassword_resets마이그레이션 파일을 수정했습니다 .

낡은 : $table->string('email')->unique();

새로운 : $table->string('email', 128)->unique();



1

StringLenght를 191로 강제하는 것은 정말 나쁜 생각입니다. 그래서 나는 무슨 일이 일어나고 있는지 이해하기 위해 조사합니다.

이 메시지 오류가 나타났습니다.

SQLSTATE [42000] : 구문 오류 또는 액세스 위반 : 1071 지정된 키가 너무 깁니다. 최대 키 길이는 767 바이트입니다.

MySQL 버전을 업데이트 한 후 표시되기 시작했습니다. 그래서 PHPMyAdmin으로 테이블을 확인했으며 생성 된 모든 새 테이블이 이전 테이블에 대해 utf8_unicode_ci 대신 utf8mb4_unicode_ci 데이터 정렬을 사용하고 있음을 알았 습니다.

내 교리 구성 파일에서 charset이 utf8mb4로 설정되어 있음을 알았지 만 이전의 모든 테이블이 utf8에서 작성되었으므로 이것이 utf8mb4에서 작동하기 시작하는 업데이트 마법이라고 생각합니다.

이제 쉬운 수정은 ORM 구성 파일에서 행 문자 세트를 변경하는 것입니다. 그런 다음 dev 모드에 있으면 utf8mb4_unicode_ci를 사용하여 테이블을 삭제하거나 삭제할 수 없으면 문자 세트를 수정하십시오.

심포니 4

config / packages / doctrine.yaml 에서 charset : utf8mb4charset : utf8 로 변경

이제 내 교리 이주가 다시 잘 작동하고 있습니다.


1

권장되는 솔루션은 innodb_large_prefixMySQL 옵션 을 활성화 하여 후속 문제가 발생하지 않도록하는 것입니다. 그 방법은 다음과 같습니다.

my.iniMySQL 구성 파일을 열고 아래와 같이 아래 줄을 추가하십시오 [mysqld].

[mysqld]
innodb_file_format = Barracuda
innodb_large_prefix = 1
innodb_file_per_table = ON

그런 다음 변경 사항을 저장하고 MySQL 서비스를 다시 시작하십시오.

마이그레이션이 필요한 경우 롤백 한 후 마이그레이션을 다시 실행하십시오.


문제가 계속 발생하면 데이터베이스 구성 파일로 이동하여 설정하십시오.

'engine' => null,'engine' => 'innodb row_format=dynamic'

그것이 도움이되기를 바랍니다!


1

먼저 localhost에서 데이터베이스의 모든 테이블을 삭제하십시오.

config / database.php 파일에서 Laravel 기본 데이터베이스 (utf8mb4) 속성을 다음과 같이 변경하십시오.

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

그런 다음 로컬 데이터베이스 속성 utf8_unicode_ci를 변경하십시오. php artisan migrate 그것은 괜찮습니다.


0

이 문제가 발생할 수있는 다른 사람에게는 내 문제는 유형의 열 string을 만들고 ->unsigned()정수가 될 때 만들려고한다는 것 입니다.


0

여기에서 접근 한 접근 방식은 키 이름이있는 두 번째 매개 변수 (짧은 이름)를 전달하는 것입니다.

$table->string('my_field_name')->unique(null,'key_name');

0

난 이미 (실제로 한 경우에도이 오류가 발생하고 있기 때문에 나는 이미했다) 스키마 :: defaultStringLength (191); 내 AppServiceProvider.php 파일에 있습니다.

그 이유는 마이그레이션 중 하나에서 문자열 값을 191보다 큰 값으로 설정하려고했기 때문입니다.

Schema::create('order_items', function (Blueprint $table) {
    $table->primary(['order_id', 'product_id', 'attributes']);
    $table->unsignedBigInteger('order_id');
    $table->unsignedBigInteger('product_id');
    $table->string('attributes', 1000); // This line right here
    $table->timestamps();
});

1000을 제거하거나 191로 설정하면 문제가 해결되었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.