Ruby on Rails'de birden çok sütun indeksi


98

Bir kullanıcının hangi makaleleri okuduğunu izlemek için işlevsellik uyguluyorum.

  create_table "article", :force => true do |t|
    t.string   "title"
    t.text     "content"
  end

Şu ana kadarki göçüm:

create_table :user_views do |t|
  t.integer :user_id
  t.integer :article_id
end

User_views tablosu her zaman her iki sütunu aramak için sorgulanır, yalnızca bir sütun değil. Sorum, indeksimin nasıl görünmesi gerektiğidir. Bu tabloların sıralamasında bir fark var mı, biraz daha fazla seçenek mi yoksa her neyse. Hedef DB'm Postgres.

add_index(:user_views, [:article_id, :user_id])

Teşekkürler.

GÜNCELLEME:
Her iki sütunda da aynı değerleri içeren yalnızca bir satır mevcut olabileceğinden (çünkü user_id'nin makale_kimliğini okuyup okumadığını bildiğim için), şu seçeneği dikkate almalı mıyım? Yanılmıyorsam bu, kendi başıma herhangi bir kontrol yapmam ve bir kullanıcı bir makaleyi her ziyaret ettiğinde bir ekleme yapmam gerektiği anlamına gelir.


"User_views tablosu her zaman her iki sütunu aramak için sorgulanır, hiçbir zaman yalnızca bir sütun bulunmaz." - "Bu kullanıcının görüntülediği tüm makaleleri bul" veya "bu makaleyi görüntüleyen tüm kullanıcıları bul" sorgusu asla olmayacak mı? Bunu şaşırtıcı buluyorum.
David Aldridge

Yanıtlar:


219

Dizine eklemede sıra önemlidir.

  1. En seçici alanı, yani satır sayısını en hızlı şekilde daraltan alanı ilk sıraya koyun.
  2. Dizin, yalnızca sütunlarını baştan başlayarak sırayla kullandığınız sürece kullanılacaktır . yani üzerinde indekslerseniz [:user_id, :article_id], user_idveya üzerinde hızlı bir sorgu gerçekleştirebilirsiniz user_id AND article_id, ancak üzerinde DEĞİLDİR article_id.

Geçiş add_indexhattınız aşağıdaki gibi görünmelidir:

add_index :user_views, [:user_id, :article_id]

'Benzersiz' seçeneğe ilişkin soru

Bunu Rails'de yapmanın kolay bir yolu validates, modelinizde uniquenessaşağıdaki gibi kapsamlı kullanmaktır ( dokümantasyon ):

validates :user, uniqueness: { scope: :article }

7
Sıra, endekslemede çok önemlidir. Where cümlelerini sola yerleştirin ve dizini sağdaki sıralama sütunlarıyla tamamlayın. stackoverflow.com/questions/6098616/dos-and-donts-for-indexes
Denis de Bernardy

1
Not validates_uniqueness_of(ve onun kuzeni validates uniqueness:) yarış koşullarına yatkındır
Ben Aubin

1
Yukarıdaki yorumlarda ve stackoverflow.com/a/1449466/5157706 ve stackoverflow.com/a/22816105/5157706 yorumlarında belirtildiği gibi, veritabanına benzersiz dizin eklemeyi de düşünün.
Akash Agarwal

25

Doğrulama zamanında ve indekste benzersizliği kontrol etme hakkında bir uyarı: ikincisi, model tarafından primer yapılırken veritabanı tarafından yapılır. Aynı anda çalışan bir modelin birden fazla eşzamanlı örneği olabileceğinden, doğrulama yarış koşullarına tabidir, bu da bazı durumlarda kopyaları tespit edemeyebileceği anlamına gelir (örneğin, aynı anda aynı formu iki kez gönderin).


Yani, hangisi daha iyi? Veritabanı tarafı mı yoksa validates_uniqueness_of?
WM

9
Her ikisi de. validates_uniqueness_of, örneğin bir form kaydedildiğinde uygulamada bir hata mesajını incelikle görüntülemek için kullanılabilir. Veritabanı kısıtlaması, modelde doğrulama belirlediğinizi bilseniz bile yinelenen kayıtlarla sonuçlanmamanızı sağlar. Artı, ActiveRecord istisnasını kurtarabilir ve ayrıca kullanıcıya güzel bir mesaj gösterebilirsiniz.
Uģis Ozols

5
@WM Birini seçmeniz gerekiyorsa, veritabanı kısıtlamasına gidin. Bu, farklı, RoR dışı uygulamalar verilerinizle etkileşime girse bile çalışır ve uzun vadede tutarlılık sağlar.
2016
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.