programing

"SET NAMS" 사용 여부

prostudy 2022. 9. 12. 11:10
반응형

"SET NAMS" 사용 여부

O'Reilly의 "High Performance MySQL"을 읽다가 우연히 다음과 같은 사실을 알게 되었습니다.

또 다른 일반적인 가비지 쿼리는 SET NAMES UTF8입니다. 이는 잘못된 작업 방식입니다(클라이언트 라이브러리의 문자 집합은 변경되지 않으며 서버에만 영향을 미칩니다).

예전에는 모든 스크립트의 맨 위에 "SET NAMES utf8"을 표시하여 쿼리가 utf8로 인코딩되었음을 DB에 알렸기 때문에 조금 혼란스럽습니다.

위의 인용문에 대해 코멘트해 주실 수 있는 분, 또는 좀 더 정식으로 말하면, 데이터베이스 워크플로우가 Unicode를 인식할 수 있도록 하기 위한 제안/베스트 프랙티스는 무엇입니까?

만약 이것이 관련이 있다면 나의 타겟 언어는 php와 python입니다.

mysql_set_charset() 옵션입니다.단, 으로 한정되는 옵션입니다.그것은 및 그 대상입니다.::mysql연결 매개 변수를 지정해야 합니다.

이 함수를 사용하면 MySQL API 호출이 발생하므로 쿼리 발행보다 훨씬 빠른 것으로 간주해야 합니다.

성능과 관련하여 스크립트와 MySQL 서버 간의 UTF-8 기반 통신을 보장하는 가장 빠른 방법은 MySQL 서버를 올바르게 설정하는 것입니다.~로SET NAMES x 동등하다

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

, 「」입니다.SET character_set_connection = x에서는 내부적으로도 실행이 됩니다.SET collation_connection = <<default_collation_of_character_set_x>>또한 이러한 서버 변수를 정적으로 설정할 수 있습니다.my.ini/cnf.

동일한 MySQL 서버 인스턴스에서 실행되고 다른 문자 집합이 필요한 다른 응용 프로그램에서 발생할 수 있는 문제에 유의하십시오.

TLDR

// The key is the "charset=utf8" part.
$dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8';
$dbh = new PDO($dsn, 'user', 'pass');

이 답변은 php의 pdo 라이브러리에 중점을 두고 있습니다.왜냐하면 php는 어디에나 있기 때문입니다.

간단한 리마인더 - mysql은 클라이언트와 서버의 아키텍처입니다.이는 실제 데이터베이스가 있는 mysql 서버뿐만 아니라 mysql 서버와 통신하는 별도의 mysql 클라이언트 드라이버도 존재하기 때문에 중요합니다.mysql 클라이언트와 pdo가 섞여있다고 보시면 됩니다.

「 」를 사용하는 set names utf8 SQL 쿼리를mysql.mysql SQL에 서버에 query.sql pdo를 합니다.이는 mysql 서버가 pdo 또는 mysql 클라이언트에 메시지를 반환하지 않고 문자 집합과 인코딩이 변경되었음을 알리기 때문에 mysql 클라이언트와 pdo 모두 발생 사실을 전혀 알지 못하기 때문에 중요합니다.

클라이언트 라이브러리가 현재 문자 집합을 인식하지 못하면 문자열을 제대로 처리할 수 없으므로 이 작업을 수행하지 않는 것이 중요합니다.대부분의 일반적인 조작은 클라이언트가 올바른 문자 집합을 인식하지 않아도 올바르게 동작하지만 PDO::quote와 같은 문자열 이스케이프입니다.pdo:mysql 사용자는 pdo:mysql 드라이버의 디폴트 설정이 되어 있기 때문에 pdo:mysql 사용자가 모르는 사이에 에뮬레이트된 prepared 문을 사용하는 경우가 많습니다.에뮬레이트된 준비문은 mysql api에 의해 제공되는 실제 네이티브 mysql 준비문을 사용하지 않습니다.대신 php는 호출과 동등합니다.PDO::quote()모든 플레이스 홀더에 견적된 값을 부여합니다.

사용하고 있는 문자 세트를 모르면 문자열을 올바르게 이스케이프 할 수 없기 때문에, 이러한 에뮬레이트된 준비 문장은, 다음의 순서로 특정 문자 세트로 변경했을 경우, SQL 주입에 취약합니다.set names주입의 수 있습니다 SQL 주입의 가능성에 관계없이 다른 문자 집합의 이스케이프 스킴을 사용하면 문자열이 끊어질 수 있습니다.

pdo mysql 드라이버의 경우 DSN에서 문자 집합을 지정하여 연결할 때 문자 집합을 지정할 수 있습니다.이렇게 하면 클라이언트 라이브러리와 서버 모두 문자 집합을 인식하므로 작업이 정상적으로 수행됩니다.

// The key is the "charset=utf8" part.
$dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8';
$dbh = new PDO($dsn, 'user', 'pass');

하지만 부적절한 문자열 탈출만이 문제가 아닙니다.예를 들어 열 이름이 문자열로 지정되고 인코딩이 중요하기 때문에 PDO::bind Column 사용에 문제가 발생할 수도 있습니다.예를 들어 다음과 같은 열 이름을 사용할 수 있습니다.ütube), (umlaut)에서 합니다.latin로로 합니다.utf8하여 「」를 합니다.$stmt->bindColumn('ütube', $var);ütubephp 파일이 utf8로 인코딩되어 있기 때문에 utf8로 인코딩된 문자열이 됩니다.작동하지 않습니다. 의 latin1의 의 latin1의 의 latin1의 latin1의 latin1의 latin1의 젠젠온온온온온다다다다다다다다다다다다다

py에 대해서는 확실하지 않지만 php에서는 "mysql_query()를 사용하여 SET NAMES를 실행하는 것은 권장되지 않습니다."라고 기술되어 있습니다.참고로 이 기능은 MySQL 5.0.7용으로 도입되었기 때문에 이전 버전에서는 동작하지 않습니다.

mysql_set_charset('utf8', $link);

는 "$link"로 작성된 입니다.mysql_connect

언급URL : https://stackoverflow.com/questions/1650591/whether-to-use-set-names

반응형