Pivot tabloda
user_id ve
promosyon_kod_id alanlarının birlikte PRIMARY KEY olması
composite key (çoklu sütun indeksi) şeklinde isimlendirilir. Kayıtlar bu şekilde indekslendiği için sorgular çok daha hızlı çalışacaktır, özellikle kayıt sayısı arttıkça aradaki fark hissedilir. Şu an sizde indeks yoksa sorgu yaptığınızda veritabanı tüm tabloyu baştan sona tarıyor. Elbette birkaç bin kayıt olan tablolarda pek bir yavaşlama hissetmezsiniz fakat birkaç milyon kayıt olan tablolarda indeks/composite key kullanılmasının sorguyu 25 saniyeden 200 ms kadar düşürdüğünü zamanında tecrübe ettim.
İndeks konusunun özüne gelince (doğruyu öğrenmeniz adına, umarım ben de doğru biliyorumdur);
Tabloda indekslenmiş alan olması sorgu sırasında o indeksin kullanıldığı anlamına gelmez. Rastgele, örneklerde var diye şuursuzca indeks vermek yanlış yapmanıza ya da farkında olmadan yavaş sorgular almanıza sebep olabilir. Kısaca anlatmaya çalışayım, zaten sabah olmak üzere, bugün zorlu bir mesai olacak
(✓) id PRIMARY KEY olmak üzere; SELECT * FROM users WHERE id = 1;
Burada indeks kullanılır. Yıldırım hızıyla sonucu alırsınız.
(x) id PRIMARY KEY olmak üzere; SELECT * FROM users WHERE name = "Kevin-Mitnick";
name alanı indeks değilse burada indeks kullanılmaz. Tüm tablo taranır.
(✓) (user_id, promosyon_kod_id) composite key olmak üzere; SELECT * FROM kullanilan_promosyon_kodlari WHERE user_id = 2;
Burada indeks kullanılır.
(✓) (user_id, promosyon_kod_id) composite key olmak üzere; SELECT * FROM kullanilan_promosyon_kodlari WHERE user_id = 2 AND promosyon_kod_id=5;
Burada indeks kullanılır.
(x) (user_id, promosyon_kod_id) composite key olmak üzere; SELECT * FROM kullanilan_promosyon_kodlari WHERE promosyon_kod_id=5;
Her ne kadar promosyon_kod_id composite key'in içinde olsa da burada indeks kullanılmaz. Bu kuraldır, soldan itibaren alanların sırayla sorguda kullanılması lazım. Ya user_id ya da user_id AND promosyon_kod_id olacak
(x) (user_id, promosyon_kod_id) composite key olmak üzere; SELECT * FROM kullanilan_promosyon_kodlari WHERE promosyon_kod_id=5 AND user_id = 2;
Her ne kadar promosyon_kod_id ve user_id composite key'in içinde olsa da burada indeks kullanılmaz. Bu kuraldır, soldan itibaren alanların sırayla sorguda kullanılması lazım. composite key indeksi ayrıca dahil edilen alanlarına sırasına göre oluşuyor.
Bu durumda eğer siz
WHERE promosyon_kod_id=5 ya da
WHERE promosyon_kod_id=5 AND user_id = 2 gibi tersten de sorgu yapacaksanız ayrıca
->index(['promosyon_kod_id', 'user_id']); şeklinde bir indeks oluşturmanız gerekiyor. (Eğer PRIMARY olan
->primary(['user_id', 'promosyon_kod_id']); şeklindeyse tabi)
SELECT * FROM kullanilan_promosyon_kodlari WHERE user_id = 2 AND promosyon_kod_id=5
Bu şekilde bir sorgu, (user_id, promosyon_kod_id) composite key olmak üzere, indeksi kullanır ve tabloyu taramaz, direk kaydı getirir.
Umarım anlatabilmişimdir.
Pivot alanlara ulaşmak için ise;
$prokods->pivot->user_id;
Bunlar ilişki kurulan model alanları oldukları için pivot objesine otomatik eklenir ama bunların dışında ekstra alan varsa aşağıdaki gibi pivot objesine dahil edebilirsiniz:
return $this->belongsToMany(...)->withPivot('ekstra_alan_adi', 'diger_alan');