MySQL Incorrect string value hatası: utf8mb4 ile doğru çözüm
MySQL karakter hatasında bağlantı ve kolon kodlamasını birlikte kontrol edin; utf8mb4 dönüşümünü yedek, collation ve indeks kontrolleriyle planlayın.
MySQL'de metin eklerken görülen Incorrect string value hatası, gönderilen karakterlerin hedef kolonun veya bağlantının karakter kümesiyle temsil edilemediğini gösterebilir. Özellikle emoji içeren metinlerde eski utf8mb3 kolonları sık karşılaşılan bir kaynaktır.
Çözüm, verinin geçtiği yolu birlikte kontrol etmektir: uygulamanın ürettiği metin, sürücünün bağlantı kodlaması ve hedef kolon. Yalnızca veritabanının varsayılanını utf8mb4 yapmak mevcut kolonları dönüştürmez.
utf8 ve utf8mb4 arasındaki fark
MySQL'in tarihsel utf8 adı birçok sürümde utf8mb3 ile ilişkilidir. Bu karakter kümesi karakter başına en çok üç bayt kullanır. utf8mb4 ise dört bayt gerektiren Unicode karakterlerini de temsil edebilir. Bütün emojiler aynı uzunlukta değildir; sorun özellikle ek Unicode düzlemlerindeki karakterlerde ortaya çıkar.
Türkçe harfler için dört bayt şart değildir. Türkçe metin de bozuluyorsa yanlış bağlantı kodlaması, yanlış kaynak decode işlemi veya hatalı verinin tekrar kaydedilmesi gibi nedenleri araştırın. utf8mb4 dönüşümü, daha önce bozulmuş metni kendiliğinden onarmaz.
1. Hedef kolon ve bağlantıyı inceleyin
Aşağıdaki tablo ve veritabanı adları örnektir; gerçek şemanızla değiştirin:
SELECT VERSION();
SHOW CREATE TABLE app_db.messages;
SHOW FULL COLUMNS FROM app_db.messages;
SHOW VARIABLES LIKE 'character_set_%';
SHOW VARIABLES LIKE 'collation_%';
Özellikle metin kolonunun karakter kümesine ve character_set_client, character_set_connection, character_set_results değerlerine bakın. Bu değişkenleri mümkünse uygulamanın kullandığı bağlantı üzerinden sorgulayın. Yönetim aracının bağlantısı uygulamadan farklı ayarlanmış olabilir.
2. Dönüşümü test veritabanında hazırlayın
Şema değişikliğinden önce yedek alın ve geri yüklemeyi test edin. Dönüşüm tabloyu yeniden oluşturabilir, kilit veya ek disk alanı gerektirebilir. Büyük tablolar için bakım süresi ve sürümünüzün DDL davranışını planlayın.
Aşağıdaki örnek utf8mb4_unicode_ci collation'ını kullanır. Bu, her proje için tek doğru seçim değildir. Büyük/küçük harf ve aksan karşılaştırmaları, sıralama, UNIQUE indeksler ve yabancı anahtarla bağlı metin kolonları açısından mevcut davranışı inceleyin. Farklı karşılaştırma kuralları yeni çakışmalar doğurabilir.
ALTER DATABASE app_db
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE app_db.messages
CONVERT TO CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
İlk komut veritabanı varsayılanını, ikinci komut ilgili tablonun metin kolonlarını değiştirir. Bütün veritabanındaki tabloları otomatik değiştirmez. Tek kolon dönüştürecekseniz MODIFY ile gerçek kolon tanımını; uzunluk, null/default ve diğer özellikleri koruyarak yazın.
Tablo dönüşümü bazı metin tiplerini daha geniş tipe değiştirebilir. Eski sürüm ve indeks boyutu kısıtları da etkili olabilir. Bu yüzden SHOW CREATE TABLE çıktısını dönüşümden önce ve sonra karşılaştırın. Yanlış kodlamayla saklanmış baytları normal charset dönüşümüne sokmak, bozuk metni farklı bir bozuk metne çevirebilir.
3. Uygulama bağlantısını da utf8mb4 yapın
Örneğin PyMySQL kullanan Python uygulamasında bağlantı yapılandırmasının ilgili alanı:
connection = pymysql.connect(
host=db_host,
user=db_user,
password=db_password,
database="app_db",
charset="utf8mb4"
)
db_host, db_user ve db_password uygulamanın kendi yapılandırmasından gelmelidir. Başka bir dil veya sürücü kullanıyorsanız onun charset seçeneğini kullanın. Bağlantı havuzları eski oturumları tutabilir; güncellenen ayarla yeni bağlantı oluşturulduğunu doğrulayın.
SET NAMES utf8mb4 belirli bir SQL oturumunun karakter ayarlarını değiştirir. Uygulama başka bir bağlantı açınca bu ayar taşınmaz. Sürücü seviyesinde doğru tanımlama yapmak, el ile bir yönetim oturumuna komut vermekten daha tutarlı bir yaklaşımdır.
4. Kayıt ve geri okuma kontrolü yapın
Aynı uygulama bağlantısıyla bir test tablosuna parametreli sorgu üzerinden İstanbul, şeker, çığ, 😀 gibi bir değer yazın ve geri okuyun. Emojiyi tek başına kabul etmek yeterli değildir; Türkçe harflerin de korunduğunu kontrol edin.
CHAR_LENGTH karakter, LENGTH bayt sayısını verir. SQL istemciniz de UTF-8/utf8mb4 kullandığında test değerini inceleyebilirsiniz. Sonuç hâlâ bozuksa uygulamada verinin daha önce yanlış decode edilip edilmediğini araştırın. SQL strict mode'u kapatmak veya emojileri silmek, kodlama yolundaki hatayı çözmez.
Kısa rehber
Sık yapılan hata
Veritabanı varsayılanını değiştirdikten sonra mevcut kolonların da dönüştüğünü varsaymak. Hedef kolon ve uygulama bağlantısı ayrı ayrı doğrulanmalıdır.