はい、その検証はその種のクエリを実行し、その種のクエリはテーブルスキャンを実行します。
ここには実際にいくつかの問題があります:
- ロジックが属するデータベースにロジックがないため、検証は競合状態の影響を受けます。データベースは、通常のRailsのイデオロギーに関係なく、すべてのデータ整合性の問題に責任を持つ必要があります。
- 検証によってテーブルスキャンがトリガーされ、テーブルスキャンを好む人は誰もいません。
1つのインデックスでこれらの問題の両方を解決できます。最初の問題は、データベース内の一意のインデックスを使用することで解決されます。 2番目の問題は、lower(username)の結果にインデックスを付けることで解決されます。 usernameではなく 。
AFAIK Railsはまだ式のインデックスを理解していないため、次の2つのことを行う必要があります。
-
schema.rbから切り替えますstructure.sqlへ Railsがインデックスを忘れないようにするためです。config/application.rb内 設定する必要があります:config.active_record.schema_format = :sqlまた、
db:structure:*の使用を開始する必要がありますdb:schema:*の代わりにタスクをレーキする タスク。structure.sqlに切り替えたら 、db/schema.rbを削除できます 更新も使用もされないため、db/structure.sqlの追跡も開始する必要があります リビジョン管理で。 -
移行時にSQLを少し記述して、手動でインデックスを作成します。これは簡単です:
def up connection.execute(%q{ create index idx_users_lower_username on users(lower(username)) }) end def down connection.execute(%q{ drop index idx_users_lower_username }) end
もちろん、これによりPostgreSQL固有のものが残りますが、ActiveRecordはとにかく有用な移植性を提供しないため、心配する必要はありません。