Rails 7.1: 自動生成されるインデックス名の長さが上限を超えないようになった(翻訳)
データベースのインデックスは、クエリパフォーマンスの向上やデータ検索の高速化において重要な役割を担っています。従来のRailsでは、自動生成される複合インデックス名が長くなりすぎることがあり、Index name is too long
エラーの発生につながる可能性がありました。
この問題を克服するため、自動生成されるインデックス名を最大62バイトに制限する変更が導入されました(#47753)。インデックス名がこの上限を超えると、より短いインデックス名にフォールバックします。
以下のセクションでは、この変更内容と、従来バージョンではどのように処理されていたかを見ていきます。
🔗 改修前
従来のRailsでは、インデックス名がデータベースにおける上限を超えると、Index name is too long
エラーが発生する可能性がありました。これを具体的に説明するため、PostgreSQLをデータベースに使うRailsアプリを使います。
以下の画像では、students_registration
テーブルの生成と、first_name
フィールド、last_name
フィールド、registration_date
フィールドへの複合インデックス追加を行おうとしています。
すると、Railsはindex_students_registration_on_first_name_and_last_name_and_registration_date
という長大なインデックス名を生成し、PostgreSQLでサポートされている上限を超えてしまいます。
このエラーメッセージはコンソールで確認できます。
ArgumentError: Index name
'index_students_registration_on_first_name_and_last_name_and_registration_date' on table
'students_registration' is too long; the limit is 63 characters.
この問題を解決するには、add_index
メソッドにname
オプションを追加して、63文字以内に収まるカスタムインデックス名を指定します。
そこで、上限値に収まる名前をname
オプションで渡してみました。
今度のマイグレーションはスムーズに処理され、指定したカスタムインデックス名でテーブルの作成に成功しました。
🔗 改修後
Rails 7.1では、新たに62バイトの上限が導入されました。インデックス名がこの上限を超えると、名前を一意にするためのハッシュが末尾に追加された短縮形のインデックス名にフォールバックします。先ほどのマイグレーションを、name
オプションを指定せずにRails 7.1アプリで実行してみましょう。
このマイグレーションは成功し、idx_on_first_name_last_name_registration_date_dbcd383c83
というインデックス名が追加されました。
これを見ると、自動生成された場合のインデックス名との違いを確認できます。インデックス名は従来のRailsよりも短くなり、データベース内で一意にするためのハッシュdbcd383c83
が末尾に含まれていることがわかります。
概要
元サイトの許諾を得て翻訳・公開いたします。
参考: 週刊Railsウォッチ20230425: 自動生成されるインデックス名を上限で切り詰めるようになった
参考: Fix Rails generated index name being too long by mscoutermarsh · Pull Request #47753 · rails/rails