0

何万ものスナップショットレコードを持つアプリケーションがあります。これらの「スナップショット」のごく少数(たとえば1000分の1)は、:has_manyアソシエーションを介して1つ以上の「位置」を持ちます。

スナップショットごとにアクティブレコードクエリを実行せずに、スナップショットに位置があるかどうかを効率的に検出するにはどうすればよいですか?私の現在の解決策は、スナップショットにブールフィールドを追加することです。スナップショットに位置がある場合、「has_position」はtrueに設定されます。ポジションを作成するたびに関連するスナップショットを変更する必要があるため、これは少し面倒に思えます。このシナリオを処理するためのよりクリーンな方法はありますか?

create_table "snapshots", :force => true do |t|
  t.datetime "created_at",                       
  t.datetime "updated_at",    
  t.boolean  "has_position",   
end

create_table "positions", :force => true do |t|
  t.integer  "snapshot_id"
  t.datetime "created_at",  
  t.datetime "updated_at",  
end
4

1 に答える 1

0

positionsを参照して移行を生成するとどうなりますかsnapshots。移行ファイルは、を使用して生成されます。

add_index :positions, :snapshot_id

その最後に追加されます。

DBにインデックスがsnapshot_idある場合、log(n)クエリを使用して、位置に少なくとも1つの関連レコードがあるかどうかを判断します。ブール値の一定時間ほど良くはありませんが、レコードが数万に過ぎないので、それほど長くはかからないはずです(これを非常に頻繁に行っている場合を除く)。

さらに、単純なhas_positionブール値は、インデックスなしで維持するのがあなたが考えるより難しいかもしれません。true関連付けられた位置の作成時に設定できますが、別の位置が存在する可能性があるため、削除時に設定することはできません。falseまた、テーブルスキャンを再度実行する必要があります。

何らかの理由でインデックスを使用することが望ましくない場合(または本当に一定時間のルックアップが必要な場合)、:counter_cache列を使用することをお勧めします。

于 2013-01-27T15:15:06.060 に答える