"SET İSİMLERİ" kullanılıp kullanılmayacağı

3 Cevap php

O'Reilly "Yüksek performanslı MySQL" okurken ben şu tökezledi

Another common garbage query is SET NAMES UTF8, which is the wrong way to do things anyway (it does not change the client library's character set; it affects only the server).

Ben db benim sorguları kodlanmış utf8 olduğunu bildirmek için her komut dosyası üstüne "utf8 İSİMLERİ SET" koymak için kullanılır çünkü, biraz kafam karıştı.

Herkes Yukarıdaki alıntıya yorum yapabilirsiniz, veya, daha resmi koymak, önerileriniz / en iyi uygulamalar benim veritabanı iş akışı unicode-farkında olmasını sağlamak için ne.

Bu alakalı eğer benim hedef diller php ve python vardır.

3 Cevap

mysql_set_charset() would be an option - but an option limited to the ext/mysql . For ext/mysqli it is mysqli_set_charset and for PDO ::mysql, bir bağlantı parametresi belirtmeniz gerekir.

MySQL API çağrısı bu fonksiyon sonuçları kullanılarak olarak, bir sorgu veren çok daha hızlı olarak düşünülmelidir.

Performansı açısından sizin komut ve MySQL sunucusu arasında bir UTF-8 tabanlı communiction sağlamak için en hızlı yolu doğru MySQL sunucusunu kuruyor. SET NAMES x equivalent için olduğu gibi

SET character_set_client = x;
SET character_set_results = x;
SET character_set_connection = x;

oysa SET character_set_connection = x içten zamanda my.ini/cnf durağan these server variables SET collation_connection = <<default_collation_of_character_set_x>> siz de ayarlayabilirsiniz yürütür.

Diğer uygulamalar aynı MySQL sunucu örneği üzerinde çalışan ve bazı diğer karakter kümesi gerektiren olası sorunların farkında olun.

O kadar her yerde, çünkü bu cevap PHP'nin PDO kütüphane üzerine bir vurgu vardır.

Kısa bir hatırlatma - mysql istemci-sunucu mimarisi. Asıl veritabanı mysql sunucu değil, sadece orada, ama mysql sunucusu (bunlar ayrı kişiler konum) için görüşmeler şey ayrı mysql istemci sürücüsü de var çünkü bu önemlidir. Sen tür sorta mysql istemci ve pdo karıştırılır söyleyebiliriz.

Eğer kullandığınız zaman set names utf8, sen mysql standart bir sql sorgu vermek. Sql sorgu PDO geçmesine etmez ve ardından mysql istemci kitaplığı aracılığıyla, ve sonra nihayet mysql sunucuyu ulaşırken, SADECE mysql sunucu ayrıştırır ve bu sql sorgusu yorumlar. Bu mysql sunucunun bu yüzden karakter kümesi ve kodlama değişti bildirerek pdo veya mysql istemci geri herhangi bir mesaj göndermek, ve değil çünkü önemli pdo bu oldu aslında tamamen cahil.

Bu geçerli karakter kümesi farkında değilse istemci kütüphanesi düzgün dizeleri işleyemez, çünkü bunu yapmak için önemli değil. En yaygın operasyonlar doğru karakter setini bilmeden istemcisi olmadan düzgün çalışmaz, ama örneğin PDO::quote gibi dize kaçan olmaz biri. Bunun için varsayılan ayar oldu, çünkü mysql kullanıcılar farkında emulated prepared statements kullanın: Eğer hazırlanmış ifadeler kullanmak, ancak gerçeği PDO'nun büyük çoğunluğu olduğu için böyle manuel ilkel dize kaçan hakkında endişelenmenize gerek yok düşünüyorum PDO: artık çok uzun bir süre için mysql sürücüsü. Mysql API tarafından sağlanan bir taklit hazırlanmış deyimi gerçek yerli MySQL hazırlanmış deyimleri kullanmaz; Bunun yerine, php PDO::quote() tüm değerleri çağıran, ve sizin için kote değerleri ile tüm tutucular str_replacing'ing eşdeğer yapar.

Eğer kullandığınız set karakteri biliyorum sürece düzgün bir dize kaçmıyor beri set adları yoluyla belirli karakter setleri için değiştirdiyseniz, bu taklit hazırlanmış deyimleri SQL enjeksiyon açıktır. Eğer farklı bir karakter kümesine yönelik kaçan bir düzeni kullanmak olursa olsun sql enjeksiyon olasılığı, hala dizeleri zarar verebilir.

Bağladığınızda PDO MySQL sürücüsü için, specifying it in the DSN tarafından, karakter kümesi belirtebilirsiniz. Bunu eğer istemci kütüphanesi belirlenen karakterin farkında olacaktır.

$dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8';

Ama yanlış dize öncelemeli tek sorun değildir. Sütun adları dizeleri olarak belirtilen, ve böylece tekrar kodlama konular çünkü Örneğin, ayrıca PDO::bindColumn kullanarak sorunları olabilir. Bir örnek ütube (Umlaut'u not) adında bir sütun adı olabilir, ve size set adları yoluyla utf8 için latin geçiş, ve sonra deneyin { [(4)]} php dosyası utf8 kodlanmış olduğundan ütube bir utf8 kodlanmış bir dize olmak. Bu bir latin1 varyantı olarak dize kodlamak gerekir, işe yaramaz ... ve şimdi devam deli her türlü var.