はい、その検証はその種のクエリを実行し、その種のクエリはテーブルスキャンを実行します。
ここには実際にいくつかの問題があります:
- ロジックが属するデータベースにロジックがないため、検証は競合状態の影響を受けます。データベースは、通常の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はとにかく有用な移植性を提供しないため、心配する必要はありません。