# PostgreSQL’de Bir Sütunun Birden Çok Değere Benzememesi Nasıl Sağlanır?
PostgreSQL veritabanınızda, belirli bir sütunun birden çok değere benzemeyen satırları seçmeniz gerektiğini hayal edin. Örneğin, bir e-ticaret platformunda, “ürün_adı” sütununda “indirimli”, “kampanya” veya “özel” kelimelerini *içermeyen* ürünleri listelemek isteyebilirsiniz. Bu makale, PostgreSQL’de NOT LIKE operatörünü birden fazla değerle nasıl etkili bir şekilde kullanacağınızı, performans optimizasyonunu ve olası senaryoları adım adım açıklayacaktır. Veritabanı sorgulamalarınızda performansı artırmak ve karmaşık koşulları yönetmek için farklı yöntemleri öğreneceksiniz.
PostgreSQL’de LIKE ve NOT LIKE Operatörleri: Temel Kavramlar
PostgreSQL’de LIKE operatörü, bir dize değerin belirli bir kalıpla eşleşip eşleşmediğini kontrol eder. % karakteri, sıfır veya daha fazla karakteri temsil ederken, _ karakteri tek bir karakteri temsil eder. NOT LIKE, LIKE‘ın tam tersidir; kalıpla eşleşmeyen değerleri seçer. Örneğin, urun_adi LIKE '%indirimli%', “indirimli” kelimesini içeren tüm ürün adlarını seçer. urun_adi NOT LIKE '%indirimli%' ise “indirimli” kelimesini içermeyenleri seçer.
Birden Çok Değere Karşı NOT LIKE Kullanımı: Basit Yöntemler
Yeni başlayanlar için, birden fazla NOT LIKE koşulunu AND operatörüyle birleştirerek basit bir çözüm elde edebiliriz.
Öğrenme Yol Haritası:
Yeni Başlayan:
Adım 1: Basit bir tablo oluşturalım:
CREATE TABLE urunler (
urun_id SERIAL PRIMARY KEY,
urun_adi VARCHAR(255)
);
INSERT INTO urunler (urun_adi) VALUES
('Elma'),
('İndirimli Armut'),
('Kampanya Fiyatlı Portakal'),
('Özel Üretim Çilek'),
('Muz'),
('Ananas');
Adım 2: AND operatörüyle birden çok NOT LIKE koşulu kullanalım:
SELECT * FROM urunler
WHERE urun_adi NOT LIKE '%indirimli%'
AND urun_adi NOT LIKE '%kampanya%'
AND urun_adi NOT LIKE '%özel%';
Bu sorgu, “indirimli”, “kampanya” ve “özel” kelimelerini içermeyen ürünlerin listesini döndürür. Bu yöntem, az sayıda değere karşı kullanıldığında oldukça anlaşılır ve basittir.
Orta Seviye:
Gerçek Hayat Örneği: Bir e-ticaret sitesindeki ürün arama özelliğinde, kullanıcı belirli kelimeleri içermeyen ürünleri filtrelemek isteyebilir. Örneğin, kullanıcı “araba” kelimesini içermeyen, fakat “otomobil” kelimesini içeren ürünleri aramak isteyebilir. Bu durumda, yukarıdaki yöntemle birlikte LIKE koşullarını da kullanabiliriz.
SELECT * FROM urunler
WHERE urun_adi NOT LIKE '%araba%'
AND urun_adi LIKE '%otomobil%';
Optimizasyon İpuçları: Çok sayıda NOT LIKE koşulu kullanmak sorgunun performansını olumsuz etkileyebilir. Bu yüzden, mümkün olduğunca az sayıda koşul kullanmaya çalışın ve indeksleri doğru şekilde kullanın. urun_adi sütununa bir indeks eklemek performansı artırabilir:
CREATE INDEX idx_urun_adi ON urunler (urun_adi);
İleri Düzey:
Performans Analizi: Çok sayıda NOT LIKE koşulu içeren sorguların performansını analiz etmek için EXPLAIN komutunu kullanın. EXPLAIN komutu, sorgunun yürütülme planını gösterir ve performans darboğazlarını belirlemenize yardımcı olur.
EXPLAIN SELECT * FROM urunler
WHERE urun_adi NOT LIKE '%indirimli%'
AND urun_adi NOT LIKE '%kampanya%'
AND urun_adi NOT LIKE '%özel%';
Edge Case’ler: LIKE ve NOT LIKE operatörleri büyük/küçük harf duyarlıdır. Büyük/küçük harf duyarlılığını ortadan kaldırmak için ILIKE ve NOT ILIKE operatörlerini kullanın.
SELECT * FROM urunler
WHERE urun_adi NOT ILIKE '%İNDİRİMLİ%';
NOT IN Operatörü ile Daha Etkin Çözümler
Çok sayıda değere karşı NOT LIKE kullanmak performans sorunlarına yol açabilir. Bu durumda, NOT IN operatörü daha etkili bir çözüm sunar. Ancak, NOT IN operatörü, boş bir küme ile karşılaştırıldığında beklenmedik sonuçlar üretebilir. Bu nedenle, dikkatli kullanılmalıdır.
SELECT * FROM urunler
WHERE urun_adi NOT IN ('İndirimli Armut', 'Kampanya Fiyatlı Portakal', 'Özel Üretim Çilek');
Bu sorgu, listedeki ürün adlarını içermeyen ürünleri seçer. NOT IN operatörü, NOT LIKE operatörüne göre daha hızlı olabilir, özellikle de karşılaştırılacak değer sayısı fazlaysa.
RegEx Kullanımı: Karmaşık Kalıp Eşleştirme
Daha karmaşık kalıp eşleştirmeleri için PostgreSQL’in yerleşik düzenli ifade (regular expression) fonksiyonlarını kullanabilirsiniz. ~ operatörü, düzenli ifadelerle eşleşmeyi kontrol ederken, !~ operatörü, eşleşmeyenleri seçer.
SELECT * FROM urunler
WHERE urun_adi !~ '^(indirimli|kampanya|özel).*';
Bu sorgu, ürün adının başında “indirimli”, “kampanya” veya “özel” kelimelerinden birini içeren ürünleri seçer. ^ karakteri satır başını, | karakteri “veya” işlemini, .* ise sıfır veya daha fazla karakteri temsil eder. RegEx kullanımı, karmaşık kalıp eşleştirmeleri için güçlü bir araçtır, ancak performans açısından dikkatli kullanılmalıdır. Yanlış yazılmış bir RegEx ifadesi sorgunun performansını önemli ölçüde düşürebilir.
Array Kullanımı: Daha Okunabilir ve Esnek Çözümler
PostgreSQL’de array’ler kullanarak, NOT LIKE koşullarını daha okunabilir ve esnek bir şekilde yazabiliriz. Öncelikle, aranan kelimeleri bir array olarak tanımlarız. Daha sonra ANY operatörü ile bu array’deki hiçbir kelimeyi içermeyen satırları seçeriz.
SELECT * FROM urunler
WHERE urun_adi NOT LIKE ANY (ARRAY['%indirimli%', '%kampanya%', '%özel%']);
Bu yöntem, birçok NOT LIKE koşulunu tek bir satıra indirgeyerek kodun okunabilirliğini artırır ve aynı zamanda esneklik sağlar. Yeni kelimeler eklemek veya çıkarmak oldukça kolaydır.
PostgreSQL Performans Optimizasyonu ve İndeksleme
Performansı artırmak için uygun indeksler oluşturmak çok önemlidir. urun_adi sütununa bir B-tree indeksi oluşturmak sorguların daha hızlı çalışmasına yardımcı olabilir. Ancak, indekslerin her zaman performansı artıracağı garanti edilemez. Bazı durumlarda, indeksler sorguların çalışma süresini artırabilir. Bu nedenle, indeksleme stratejinizi dikkatlice planlamanız ve farklı indeksleme seçeneklerini test etmeniz gerekir. EXPLAIN komutunu kullanarak farklı indeksleme stratejilerinin performansını karşılaştırabilirsiniz. [Fatih Soysal’ın PostgreSQL performans optimizasyonu hakkındaki yazıları](https://fatihsoysal.com) bu konuda daha detaylı bilgi sağlayabilir.
Sonuç
PostgreSQL’de bir sütunun birden çok değere benzemeyen satırları seçmek için farklı yöntemler mevcuttur. NOT LIKE operatörünü AND ile birleştirmek, NOT IN operatörünü kullanmak, düzenli ifadeler ve array’ler kullanmak gibi yöntemler farklı senaryolarda daha uygun olabilir. Performans optimizasyonu için indeksleme ve EXPLAIN komutunu kullanmak önemlidir. Seçtiğiniz yönteme bağlı olarak, sorgularınızın performansını dikkatlice izleyerek en uygun çözümü belirlemelisiniz.
Sıkça Sorulan Sorular:
1. NOT LIKE operatörü büyük/küçük harf duyarlı mıdır? Evet, varsayılan olarak büyük/küçük harf duyarlıdır. Büyük/küçük harf duyarlılığını kaldırmak için ILIKE operatörünü kullanın.
2. Çok sayıda NOT LIKE koşulu kullanmanın performans üzerindeki etkisi nedir? Çok sayıda koşul, sorgunun performansını olumsuz etkileyebilir. NOT IN veya array yöntemleri daha verimli olabilir.
3. NOT IN operatörü boş bir kümeyle karşılaştırıldığında ne olur? Boş bir kümeyle karşılaştırıldığında, NOT IN operatörü beklenmedik sonuçlar üretebilir (her zaman TRUE döndürür). Bu durumu kontrol etmeniz gerekir.
4. Düzenli ifadeler kullanmanın avantajları ve dezavantajları nelerdir? Avantajı karmaşık kalıp eşleştirmeleri yapmaktır. Dezavantajı ise performans açısından dikkatli kullanılması gerektiğidir. Yanlış yazılmış bir düzenli ifade sorgunun performansını ciddi şekilde düşürebilir.
5. PostgreSQL’de performansı nasıl optimize edebilirim? Uygun indeksleri oluşturarak, sorguları optimize ederek ve EXPLAIN komutunu kullanarak performans analizi yaparak.
Yazar: Fatih Soysal
