Neden bir metin sütununda text_pattern_ops dizini ekleyesiniz?


18

Bugün Yedi Haftada Yedi Veritabanları beni operatör başına dizinlerle tanıştırdı.

text_pattern_opsDeğerler küçük harfle indekslendiği sürece, bir operatör sınıfı dizini oluşturarak önceki sorgularla eşleşen desen için dizeleri dizinleyebilirsiniz.

CREATE INDEX moves_title_pattern ON movies (
    (lower(title) text_pattern_ops);

text_pattern_opsBaşlığını metin türünde olduğu için kullandık . Endeksi varchars karakter veya isimler Sizin gerekiyorsa, ilgili op kullanın: varchar_pattern_ops, bpchar_pattern_opsve name_pattern_ops.

Örneği gerçekten kafa karıştırıcı buluyorum. Bunu yapmak neden yararlıdır?

Sütun metin türüyse, diğer türler (varchar, char, name) arama değeri olarak kullanılmadan önce metne çevrilmez mi?

Bu indeks, varsayılan operatörü kullanarak bir dizinden nasıl farklı davranır?

CREATE INDEX moves_title_pattern ON movies (lower(title));

1
Bu ilgili soru yardımcı olabilir: dba.stackexchange.com/questions/10694/…
Erwin Brandstetter

Teşekkürler Erwin. Bu soruya verdiğiniz yanıt , kitaptaki fikirleri araştırırken çok yardımcı oldu.
Iain Samuel McLean Elder

Yanıtlar:


20

Belgeler genellikle bu tür sorulara cevap verir. Olduğu gibi bu durumda da:

Operatör sınıfları text_pattern_ops, varchar_pattern_ops ve bpchar_pattern_ops sırasıyla text, varchar ve char türlerinde B-ağacı dizinlerini destekler. Varsayılan operatör sınıflarından fark, değerlerin, yerel ayara özgü harmanlama kurallarına göre değil, karakter karakter ile karşılaştırılmasıdır. Bu , veritabanı standart "C" yerel ayarını kullanmadığında, bu işleç sınıflarını kalıp eşleme ifadeleri (LIKE veya POSIX düzenli ifadeleri) içeren sorgular tarafından kullanıma uygun hale getirir . Örnek olarak, şöyle bir varchar sütununu dizine ekleyebilirsiniz:

CREATE INDEX test_index ON test_table (col varchar_pattern_ops);

Bir dizin kullanmak için normal <, <=,> veya> = karşılaştırmaları içeren sorguları istiyorsanız, varsayılan işleç sınıfıyla da bir dizin oluşturmanız gerektiğini unutmayın . Bu tür sorgular xxx_pattern_ops işleç sınıflarını kullanamaz . (Ancak, normal eşitlik karşılaştırmaları bu operatör sınıflarını kullanabilir.) Aynı sütun üzerinde farklı operatör sınıflarıyla birden çok dizin oluşturmak mümkündür.

Belgeler şunları söylüyor:

C yerel ayarını kullanırsanız, varsayılan yerel sınıflı bir dizin C yerel ayarındaki kalıp eşleme sorguları için kullanılabilir olduğundan xxx_pattern_ops işleç sınıflarına ihtiyacınız yoktur.

Yerel ayarınızı aşağıdaki gibi kontrol edebilirsiniz ("C" yerine UTF8 olması muhtemeldir):

postgres=> show lc_collate;
 lc_collate
-------------
 en_GB.UTF-8

Aha! Bunu okudum, ama takip etmek zor buldum, bu yüzden içeri almadı. Yerin yararlı yararlılığı text_pattern_opsyerel ayarlara bağlıdır söyleyebilir misiniz ? Yerel ayarım 'en_US.UTF-8' ('C' değil) olduğundan bana fayda sağlayacak gibi görünüyor, bu nedenle desen sorguları varsayılan dizini kullanamıyor.
Iain Samuel McLean Elder

Kesinlikle. Ben temel ASCII karakterleri içinde kalan veri ile varsayılan operatör sınıfı gibi iyi olduğunu (ancak bu sadece spekülasyon) eklemek istiyorum - en azından ben böyle dizinleri kullanarak 'bir şey%' LIKE ile sorguları görmek.
dezso

5
@dezso: LIKEDüz bir b-ağacı dizini kullanarak bir sorgu gördüyseniz , db Cyerel ayarı kullanıyor olmalıdır . Veya dizin COLLATE "POSIX"(veya COLLATE "C") ile tanımlanır ve sorgu bir eşleşme belirtir COLLATION. Başka bir harmanlamada, dizinin sırası yerel kurallarla eşleşmez ve bu nedenle kalıp eşleşmesi için kullanılamaz.
Erwin Brandstetter

1
@ErwinBrandstetter Onaylamak zorundayım, haklısın.
dezso

1
@StopHarmingMonica doğru yanıtı alırsınız (ve hiçbir hata), sadece sorgu muhtemelen yavaş olacak, dizini kullanmak mümkün değil.
dezso
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.