SQL'de Türkçe Karakter ve İ, ı Sorunu: Collation Ayarıyla Çözüm
Beceri rehberi

SQL'de Türkçe Karakter ve İ, ı Sorunu: Collation Ayarıyla Çözüm

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 6 dk okuma

Türkçe harfler doğru saklansa bile karşılaştırma ve sıralama yanlış çıkabilir. Bunun karakter kümesinden farkını, İ ve ı çiftlerini ve SQL Server, MySQL ve PostgreSQL'de collation ayarını gösterir.

Bir bakışta

  1. Kodlama ile collation farklı sorunlardır. Harf soru işaretine dönüşüyorsa sorun kodlamadadır; arama ve sıralama yanlışsa collation'dadır.
  2. Türkçede i iki ayrı çifttir: i ile İ, ı ile I. Dil bağımsız kurallar i ile I'yı eşler; bu Türkçede arama sonuçlarını eksiltir.
  3. SQL Server'da Turkish_CI_AS, MySQL'de utf8mb4_tr_0900_ai_ci kullanılır. Ad dil, büyük küçük harf ve aksan duyarlılığını taşır.
  4. Collation sunucu, veritabanı, sütun ve sorgu düzeyinde verilir. Sorunu en dar düzeyde çözmek en az risklidir.
  5. Tip değişirken COLLATE yazılmazsa sütun varsayılana döner. Değişiklikten sonra dört harfle sınama sorgusu çalıştırın.

İki ayrı sorun: karakter kodlaması ve collation

Türkçe karakter sorunları genellikle iki farklı kökten gelir ve ikisi karıştırıldığında çözüm uzar. Birincisi kodlamadır: Türkçe harfler veritabanına kaydedilirken soru işaretine ya da bozuk karakterlere dönüşüyorsa sorun, sütunun ya da bağlantının karakter kümesindedir. Bu durumda harf saklanamamıştır.

İkincisi collation sorunudur: harfler doğru saklanmıştır ama karşılaştırma ve sıralama beklediğiniz gibi çalışmaz. İstanbul aramasında İstanbul kaydı bulunurken istanbul bulunmaz, ISPARTA ile ısparta aynı kabul edilmez ya da sıralamada ç, ğ, ö, ş, ü harfleri alfabedeki yerinde durmaz.

Collation, bir sütundaki metinlerin nasıl karşılaştırılıp sıralanacağını belirleyen kural kümesidir; büyük ve küçük harf duyarlılığı, aksan duyarlılığı ve dile özgü sıralama bu kurallara dahildir. Karakter kümesi ise hangi harflerin saklanabileceğini söyler. Bu sayfa ikinci sorunu, özellikle i ve ı harflerinin çiftleşmesini ele alır.

Dört harf, iki çift: İ, i, I, ı

Türkçede i harfinin noktalı ve noktasız iki ayrı biçimi vardır ve her biri kendi büyük ya da küçük karşılığına sahiptir. Noktalı küçük i'nin büyük hâli noktalı İ'dir. Noktasız küçük ı'nın büyük hâli ise noktasız I'dır. Bu iki çift birbirine karışmaz.

Türkçe dışındaki çoğu dilin kurallarında ise küçük i'nin büyük hâli noktasız I'dır. Collation dili bu kurallara göre ayarlıysa i ile I eşit sayılır; Türkçe kurallı bir collation'da ise i ile İ, ı ile I eşit sayılır ve i ile I eşit olmaz. Sonuçta büyük harfe çevirme, büyük küçük harf duyarsız karşılaştırma ve LIKE aramaları collation'a göre farklı sonuç verir.

Bu fark pratikte şöyle görünür: Türkçe kuralları bilmeyen bir collation'la ISPARTA kaydı, ısparta aramasında bulunmayabilir; çünkü I harfi, kural gereği küçük i ile eşleştirilmiştir. Hata yok gibi görünür, sonuçlar sadece eksiktir.

Şekil 1

Türkçede i harfi iki ayrı çifttir, ikisi karışmaz

Dört harf

NoktasızNoktalı
İNoktalı büyük harf; küçük karşılığı i.
iNoktalı küçük harf; büyük karşılığı İ.
INoktasız büyük harf; küçük karşılığı ı.
ıNoktasız küçük harf; büyük karşılığı I.
Büyük harfKüçük harf
Kaynak: Türk alfabesi; sayfa içeriğiMindset Institute

Collation adlarını okumak

Collation adları çoğunlukla dil, duyarlılık ve kodlama bilgisini taşır. SQL Server'da Türkçe için Turkish_CI_AS adı kullanılır; belgeler bunu Türkçe (Türkiye) yerel ayarına karşılık gelen collation olarak listeler. CI büyük küçük harf duyarsız, CS duyarlı demektir. Adın CI_AS gibi son bölümü aksan duyarlılığını da gösterir: AS aksanlı ve aksansız harfi farklı sayar, öteki seçenek aynı sayar. BIN ile biten adlar ikili sıralamadır; harf kodlarına göre karşılaştırır, büyük harf duyarlıdır. UTF8 son eki ise char ve varchar sütunların UTF-8 kodlamayla Unicode saklamasını sağlar.

MySQL'de adlar karakter kümesiyle başlar ve son eklerle devam eder: _ci büyük küçük harf duyarsız, _cs duyarlı, _ai aksan duyarsız, _as aksan duyarlı, _bin ikilidir. Belgeler Türkçe kurallı iki örnek verir: utf8mb4_tr_0900_ai_ci ve daha eski bir Unicode sürümüne dayanan utf8mb4_turkish_ci. Ad, hangi karakter kümesinde çalıştığını da gösterir.

PostgreSQL'de collation bir sütuna ya da ifadeye atanır. ICU sağlayıcısıyla derlenmişse collation adları dil etiketine -x-icu eklenerek yazılır, örneğin belgedeki de-x-icu; Türkçe için tr ile başlayan bir ad aranır. Hangi collation'ların kurulu olduğunu sisteminizin katalogunda kontrol edin.

Mevcut collation'ı görmek ve düzeyleri anlamak

Önce neyle çalıştığınızı öğrenin. SQL Server'da sunucu collation'ı şöyle sorgulanır:

SELECT CONVERT(NVARCHAR(128), SERVERPROPERTY('collation'));

Veritabanının collation'ı için:

SELECT CONVERT(NVARCHAR(128), DATABASEPROPERTYEX('veritabani_adi', 'collation'));

Bu iki sorgu belgelerde verilen kalıptır. Sütun düzeyinde collation farklı olabilir; bir sütun veritabanından farklı bir collation taşıyorsa karşılaştırma sonuçlarını belirleyen o olur. Bu yüzden sorun yaşayan sütunun kendi collation'ına ayrıca bakın.

SQL Server'da varsayılan sunucu collation'ı kurulum sırasında işletim sisteminin yerel ayarına göre belirlenir. Belgeler, bunun her zaman önerilen collation olmadığını, uyumluluk nedeniyle her yerel ayar için en eski sürümün seçildiğini belirtir. Yeni bir kurulumda collation'ı varsayılana bırakmak yerine bilinçli seçin.

Collation dört düzeyde belirlenebilir ve en içteki, yani en özel olan geçerlidir. Sunucu düzeyi varsayılanları belirler. Veritabanı düzeyi, o veritabanında yeni oluşturulan sütunların varsayılanıdır. Sütun düzeyi tek bir sütunu etkiler. En içte ise sorgu ifadesindeki COLLATE ifadesi o işlem için diğerlerini geçersiz kılar.

Sorunu en dar düzeyde çözmek genellikle en az riskli yoldur. Tek bir aramada sorun varsa sorguya COLLATE yazın; belirli bir sütun yanlışsa sütunu değiştirin; ancak tüm veritabanı yanlışsa veritabanı düzeyine çıkın.

Şekil 2

En özel düzey, daha genel düzeylerin kuralını geçersiz kılar

Collation düzeyleri

  1. Sorgu ifadesiCOLLATE ile tek işlem için geçerli.
  2. SütunTek bir sütunun karşılaştırma kuralı.
  3. VeritabanıYeni sütunların varsayılanı.
  4. SunucuKurulumdan gelen genel varsayılan.
Kaynak: Microsoft ve PostgreSQL collation belgeleri; sayfa içeriğiMindset Institute

Çözüm yolları: sorgu, sütun, veritabanı

Sorgu düzeyinde COLLATE, tek bir karşılaştırmayı Türkçe kurallara çevirir:

SELECT * FROM sehir WHERE ad = N'ısparta' COLLATE Turkish_CI_AS; SELECT ad FROM sehir ORDER BY ad COLLATE Turkish_CI_AS;

Sütun düzeyinde ALTER TABLE ile collation değiştirilir. Belgelerdeki kalıp şöyledir:

ALTER TABLE sehir ALTER COLUMN ad NVARCHAR(100) COLLATE Turkish_CI_AS;

Burada dikkat edilecek ayrıntı vardır: Microsoft belgesine göre COLLATE yazmadan veri tipini değiştirirseniz sütun veritabanının varsayılan collation'ına döner. Tip değiştirirken collation'ı da açıkça yazın.

Veritabanı düzeyinde ALTER DATABASE kullanılır:

ALTER DATABASE veritabani_adi COLLATE Turkish_CI_AS;

Bu işlem veritabanı varsayılanını değiştirir; mevcut sütunların collation'ını ayrıca kontrol edin ve gerekiyorsa tek tek güncelleyin. Belge ayrıca bir uyarı verir: veritabanı collation'ı değiştiğinde geçici tablolar sunucu collation'ıyla çalışan tempdb içinde durduğundan, kullanıcı veritabanıyla geçici tablo arasındaki karşılaştırmalar collation çakışması hatası verebilir. Çözüm, sorguda COLLATE yazmaktır.

MySQL'de sütun ya da tablo tanımında karakter kümesi ve Türkçe kurallı collation seçilir; söz dizimi için MySQL belgesine bakın. Değişiklikten önce yedek alın ve indeks davranışını test edin.

PostgreSQL'de büyük küçük harf duyarsız karşılaştırma

PostgreSQL'de sütuna ya da ifadeye COLLATE verebilirsiniz. İki sütunun collation'ları çakışıyorsa sistem hata verir, çözüm ifadeye açıkça COLLATE yazmaktır. Büyük küçük harf duyarsız karşılaştırma için belgeler ICU tabanlı, belirleyici olmayan bir collation tanımlamayı gösterir:

CREATE COLLATION case_insensitive (provider = icu, locale = 'und-u-ks-level2', deterministic = false);

Bu örnek belgeden alınmıştır ve dil bağımsız kök kuralı kullanır; Türkçe i ve ı çiftleri için dil etiketini Türkçe olarak değiştirip sonucu sınamanız gerekir. Belirleyici olmayan collation'ların bedeli de vardır: performans düşebilir, B-tree indekslerinde yineleme azaltma kullanılamaz ve bazı örüntü eşleştirme işlemleri yapılamaz. Büyük tablolarda indeks ve arama davranışını ölçün.

Ayrıca ICU collation'larının sürüme bağlı olduğunu unutmayın; belgeye göre standart unicode collation'ın davranışı, PostgreSQL farklı bir ICU sürümüyle derlendiğinde değişebilir.

Sınama sorgusu ve sık hatalar

Ayarın doğru çalıştığını bir sınamayla doğrulayın. Dört harfi içeren küçük bir tablo kurun ve her çifti karşılaştırın:

SELECT CASE WHEN N'ı' = N'I' COLLATE Turkish_CI_AS THEN 'eşit' ELSE 'eşit değil' END; SELECT CASE WHEN N'i' = N'İ' COLLATE Turkish_CI_AS THEN 'eşit' ELSE 'eşit değil' END; SELECT CASE WHEN N'i' = N'I' COLLATE Turkish_CI_AS THEN 'eşit' ELSE 'eşit değil' END;

Türkçe kuralları uygulayan bir collation'da ilk iki sorgunun eşit, üçüncünün eşit değil dönmesi beklenir. Sonuç farklıysa collation, sütun ya da bağlantı yanlış ayarlanmıştır.

Sık hatalar şunlardır. Büyük harfe çevirme işlevini Türkçe kuralları bilmeyen bir ortamda kullanıp i harfini yanlış çevirmek. Sütunu Türkçe collation'a alıp veritabanı varsayılanını unutmak, bu yüzden yeni sütunlar eski kuralla gelir. Farklı collation'lı iki veritabanını birleştirirken çakışma hatası almak. Uygulama kodunda ayrıca küçük harfe çevirip karşılaştırmak; bu, veritabanındaki kuralla çelişebilir. Karakter kümesi sorununu collation sorunu sanmak da sık görülür: harfler bozuk kaydediliyorsa collation değiştirmek çözmez.

Bu beceriyi Mindset programlarında nerede çalışırsınız

Karakter ve collation ayarı, veritabanı yöneticisinin ve SQL geliştiricisinin kurulum ve geçiş çalışmalarında karşılaştığı bir konudur. SQL ile Programlama Eğitimi veritabanları oluşturma ve tablolarla çalışma modüllerini, Veritabanı Yönetim Sistemleri ve Uygulamaları programı ise veritabanı yönetimi ve optimizasyon başlığını içerir; ikisi de bu ayarların etkisini görebileceğiniz çalışma alanlarıdır.

İlgili Mindset programı

SQL ile Programlama Eğitimi

Sık sorulanlar

Sık sorulan sorular

Türkçe karakterler soru işaretine dönüşüyorsa collation mı değiştirmeliyim?

Hayır. Soru işareti, karakterin saklanamadığını gösterir ve sorun karakter kümesi ya da bağlantı kodlamasıdır. Collation, saklanmış metnin karşılaştırılması ve sıralanması içindir. Önce sütunun Unicode destekleyen bir tipte ya da kodlamada olduğundan emin olun.

Büyük küçük harf duyarsız (CI) collation i ve ı sorununu çözer mi?

Kendi başına çözmez. CI yalnız harf büyüklüğünü yok sayar; hangi harflerin çift sayılacağını dil kuralı belirler. Türkçe kurallı bir collation i ile İ, ı ile I eşleştirir. Dil bağımsız ya da İngilizce kurallı bir CI collation ise i ile I eşit sayar.

Veritabanı collation'ını değiştirmek mevcut sütunları da değiştirir mi?

Veritabanı varsayılanını değiştirir; mevcut sütunların collation'ını ayrıca kontrol etmeniz ve gerekiyorsa güncellemeniz gerekir. Değişiklikten sonra sunucu collation'ıyla çalışan geçici tablolarda çakışma hatası alabilirsiniz. Önce test ortamında deneyin, çözüm olarak sorguda COLLATE kullanın.

Tip değiştirirken collation neden bozuldu?

Microsoft belgesine göre ALTER COLUMN ile veri tipini COLLATE yazmadan değiştirirseniz sütun veritabanının varsayılan collation'ına döner. Sütunun özel bir collation'ı varsa tip değiştirirken onu yeniden açıkça yazmanız gerekir.

Uygulama tarafında küçük harfe çevirip karşılaştırmak yeterli mi?

Güvenilir değildir. Programlama dilindeki küçük harfe çevirme Türkçe i kurallarını bilmeyebilir ve veritabanındaki karşılaştırma kuralıyla çelişebilir. Karşılaştırmayı veritabanında doğru collation ile yapmak, tutarlı ve indeksten yararlanan sonuç verir.

SQL Collation ve Türkçe Karakter Sorunu: İ ve ı