- 環境: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 協議》,轉載必須註明作者和本文連結