Uluslararası veritabanı için bir harmanlama nasıl seçilir?


22

Verileri farklı dillerde depolayacak bir veritabanı tasarlıyorum (UTF-8 kullanarak), bu nedenle sorgunun sonuçlarını görüntülemenin en iyi yolunun, sorgunun kendisi sırasında kullanıcının diline göre sipariş etmektir ( çünkü birden fazla olduğu için) Bunu yapmak için doğru yolları ), şöyle:

SELECT a < b COLLATE "de_DE" FROM test1;

Bunun, uluslararası verilerle çalışmanın doğru yol olduğunu varsayarsak, veritabanının kendisi için en iyi harmanlama hangisidir? PostgreSQL belgeleri diyor ki :

C ve POSIX harmanlamaları hem "A" - "Z" arasındaki yalnızca ASCII harflerinin harf olarak işlendiği ve sıralama kesinlikle karakter kodu bayt değerleriyle yapılır. "Geleneksel C" davranışını belirtir.

Sanırım bu, bu durumda en iyi seçenek, ya da yanlış mıyım?

(Bonus soru: Sorguda harmanlamayı seçmek çok mu yavaş?).


2
Acı çekeceğiniz en büyük acı noktası, çok dilli bir DB'de çok sayıda dizine ihtiyaç duymanızdır, çünkü kodlanabilir metin üzerindeki dizinler harmanlamaya özgüdür. Yalnızca bir parti harmanlama / dilinde arama yapma eğilimindeyseniz, dizin boyutunu kontrol altında tutmaya yardımcı olmak için kısmi dizinleri kullanabilirsiniz.
Craig Ringer,

2
Bir kaynaktan alıntı yaparken, bir bağlantı ekleyin.
Erwin Brandstetter

Yanıtlar:


27

CHarmanlama doğru seçimdir.

Yerel ayar olmadan her şey biraz daha hızlı. Hiçbir harmanlama doğru neyse olduğuna göre, veritabanı oluşturmak olmadan ile anlam harmanlama C.

Birçok operasyon için bir harmanlama sağlamak zorunda kalmak acı verici olabilir. Yine de, varsayılan harmanlama ve geçici bir harmanlama arasında hızda gözle görülür bir fark olmamalıdır. Sonuçta bu sadece sıralanmamış verilerdir ve sıralama yapılırken harmanlama kuralları uygulanır.

Postgres'in, temel işletim sistemi tarafından sağlanan yerel ayarlara dayandığını unutmayın; bu nedenle, kullanılacak her bir yerel ayar için yerel ayarlara sahip olmanız gerekir. SO burada ve burada ilgili cevabında daha fazla .

Bununla birlikte, @Craig'in daha önce de belirtildiği gibi , bu senaryoda endeksler darboğazdır. Dizinin harmanlanması, karakter verilerini içeren birçok durumda uygulanan operatörün harmanlaması ile eşleşmelidir.

Sen kullanabilirsiniz COLLATEeşleştirme endeksleri üretmek için dizinlerinde belirtici. Aynı tabloda verileri karıştırıyorsanız kısmi indeksler mükemmel seçim olabilir.

Örneğin, uluslararası karakterli bir tablo:

CREATE TABLE string (
   string_id serial
  ,lang_id   int NOT NULL
  ,string    text NOT NULL
);

Ve bir anda en çok bir dile ilgi duyuyorsun:

SELECT *
FROM   string
WHERE  lang_id = 5  -- 5 being German / Germany here
AND    string > 'foo' COLLATE "de_DE"
ORDER  BY string COLLATE "de_DE";

Sonra şöyle kısmi indeksler oluşturun:

CREATE INDEX string_string_lang_id_idx ON string (string COLLATE "de_DE")
WHERE lang_id = 5;

İhtiyacınız olan her dil için bir tane.

Aslında, kalıtım böyle bir tablo için üstün bir yaklaşım olabilir. Daha sonra, miras alınan her tabloda, yalnızca tek bir yerel ayar için yalnızca dizeler içeren düz bir dizin olabilir. Elbette, kalıtsal masalar için özel kurallar konusunda rahat olmanız gerekir.


1
Herhangi bir yeni veritabanı için varsayılan olarak C yerelini (veya 'yerel olmayan' yerel ayarı) kullanıyor musunuz?
Jack Douglas

1
@ JackDouglas: Hayır, bunu sadece özel durumlar için yapardım. Genelde, yerde genel olarak kullanılan yerel ayarlarla çalışmak çok daha pratiktir.
Erwin Brandstetter

13

Varsayılan Unicode sıralamasını sağlayan bir harmanlama seçmenizi öneririz. Bu şekilde, her sorgudaki harmanlamayı geçersiz kılmasanız bile aklı başında sonuçlar alırsınız. Ne yazık ki, çoğu (tümü?) İşletim sistemi basitçe "varsayılan Unicode" veya buna benzer bir şey adı verilen bir yerel ayar sağlamaz, bu nedenle iyi bir seçim tahmin etmeniz ve / veya araştırmanız gerekecektir. Örneğin, Linux / glibc'de de_DE.utf8 veya en_US.utf8 yerel ayarları varsayılan davranıştan geçer, bu yüzden ikisi de iyi seçimlerdir.

C yerel ayarını kullanmak iyi bir fikir değil, çünkü uygulamanızın varsayılan davranışı işe yaramaz. Büyük / küçük harf dönüştürme işlemlerinden uygun davranış alamayabilirsiniz.

(Bir sorguda harmanlamayı geçersiz kılmak fazla yüke sahip değildir. Bu sadece bir ayrıştırma işlemidir.)


Aklı başında bir
akılda kalmak

1
Şu anda bir test veritabanında es_CL.utf8 kullanıyorum, ancak cevabınız sayesinde biraz daha fazla baktım ve utf8_unicode_cibunun yolunu buldum .
Tae,

0

Dock kabında postgres kullanıyoruz, bu nedenle her zaman ICU'muz var ve und-x-icuvarsayılan olarak kullanıyoruz .

Bu bölüm 23.2.2.2.2'de belirtilmiştir . Postres belgelerinin YBÜ harmanlamaları şunları belirtmektedir:

und-x-icu (“tanımsız” için)
YBÜ “kök” harmanlaması. Makul bir dille agnostik sıralama düzeni almak için bunu kullanın.

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.