laravel「Specified key was too long」の治し方

製作

最終更新日:2023/02/17

ラムネグから一言:寝る前に読むとくだらなすぎて逆に寝れると好評なすごい適当なブログをこっちではじめてます.

Specified key was too long; max key length is 767 bytes

laravelでstring型(sqlだとvarchar型ですね)にインデックスを設定しようとしたら、上記のエラーが。エラーって怖いですよね。ドキッとするというか。

今回はこの「Specified key was too long; max key length is 767 bytes」の治し方を書きたいと思います。

このstringのサイズを小さくしたらいい

いきなり解決方法ですが、マイグレーションファイルで、「>string("name")->index()」とかしてるのを、

>string("name", "50")->index()

みたいな感じでインデックスを張ろうとしているstring型のサイズをこっちでちっちゃくしてやればOK。これでエラーが出なくなります。

原因は「MySQLはインデックスは767バイトまでしかダメ!ってしてるから」

んでこの「Specified key was too long; max key length is 767 bytes」の原因なんですが、これはMySQLがインデックスを設定するのは767バイト以内にしてよね!という自分ルールを持ってるため。

んで、laravelのstring型は、結局MySQLのデータ型でいうとvarchar(255)に変換される。さらにこのvarchar型の”255″っていうのはバイト数じゃなくて文字数、なんですよね。255文字まで格納できるよ!っていう。

utf8mb4をたぶん最近はデータベースの文字コードとして使ってると思うんで、これだと1文字4バイト。そうなると「255×4」で1020バイト。

そうなんです。そうなるとvarchar(255)はMySQLの決めてる自分ルールである「インデックスは767バイト以内」っていうルールを破っちゃうんですよね。まるでおやつは300円以内みたいな変な縛りですよね。でも、だからエラーが出る、と。

なのでvarcharのサイズを小さくしてやればいい、っていうのが上記の解決方法。

実際、インデックスを張りたいようなカラムにそんな長い文字入れるでしょうか。私は入れないです。なので例では50にしましたが、例えば50文字以上入れるかもなー、って人は「767÷4」の191文字までは設定できるんでそれでもいいと思います。

「191」といえばlaravelは、というよりMySQL?のバージョンが古い場合の問題で、ntf8mb4が4バイトだからvarchar型に191文字しか設定できない、っていう別の問題もあった気がします。

たぶん私が開発環境で使ってるMySQLのバージョンが5.6かそんな古いバージョンなので、今回のトラブルが発生したんだろうなー。

まとめ

今回はlaravelでstring型にインデックスを張った際に出てくるエラー「Specified key was too long; max key length is 767 bytes」の解決方法を書きました。

まとめるとインデックスに使えるサイズが767バイトまでっていう自分ルールをMySQL(古いバージョンだけ?)は持ってるんで、string型(MySQL上はvarchar型)のサイズを191以下にすればOK!という感じ。実際インデックスを張るカラムに191文字なんて入れないんで実運用上問題ないと思います。長くて30文字とか、じゃないでしょうか。インデックス対象にしたいvarchar型なんて。

参考にしてみてくださいね。

【おしらせ、というか完全なる宣伝】

文体がもうぜんぜん適当すぎてあれだけどものすごい自由に書いてるブログ「檸檬だくだく」もよろしく.寝る前に読める恐ろしくくだらないやつです.

こんなにも一ミリも目を引かれないタイトルを取り扱ってます: ココア20g / ハイチュウとかってさ / なぜ米と小麦を食べようと思ったのかの謎 /