解決遷移資料庫錯誤,索引長度過長

嘉寶君發表於2020-07-11
  • 環境:phpstudy(apache2.4.39,mysql5.7.26,php7.3.4)

在使用laravel自帶的遷移資料庫的命令時報錯:

  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_e
mail_unique`(`email`))

網上有很多文章的解決方案是手動配置遷移生成的預設字串長度
修改 /app/Providers/AppServiceProvider.php 中的 Schema::defaultStringLength 方法來配置它

use Illuminate\Support\Facades\Schema;

/**
 * 引導任何應用程式服務。
 *
 * @return void
 */
public function boot()
{
 Schema::defaultStringLength(191);
}

但這個方案比較適合使用較老版本的mysql或者MariaDB

透過檢視遷移的資料表使用的引擎發現是使用的myisam

myisam 儲存引擎在建立索引的時候,索引鍵長度是有一個較為嚴格的長度限制的,所有索引鍵最大長度總和不能超過1000,而且不是實際資料長度的總和,而是索引鍵欄位定義長度的總和。

編碼 大小 字元
latin1 1 byte 1 character
gbk 2 byte 1 character
uft8 3 byte 1 character
uft8mb4 4 byte 1 character

根據這一發現我們可以選擇另一種方案修改資料庫使用引擎來解決,config/database.php配置資料庫預設的引擎。

#引數改為InnoDB,也可以新增引數預設設定為 InnoDB ROW_FORMAT=DYNAMIC
return [
...
'mysql' => [
    ...
  'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',
],
...
];

注意:mysql的版本的預設配置不同也會造成建立表時的ROW_FORMAT的預設值不同或innodb_large_prefix配置不同,當innodb_large_prefix為OFF的最大值為 767 bytes,當為ON時最大值為 3072bytes

總結:

查詢資料,找到了幾種方法,包括調整編碼也可以在某些環境解決問題,應該根據自己的開發/生產環境以及自己的需求來作為解決方案,我個人偏向開啟開啟innodb_large_prefix後,修改預設引擎設定動態表來解決該問題,但不適合所有人特別是資料量大的資料庫,根據自己的業務需要了解引擎特性和靜態表和動態表之間的區別。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章