2017-09-06 17 views
0

우리는 Etherpad Lite를 실행 중이며 MySQL에서 PostgreSQL으로 데이터베이스를 마이그레이션하려고합니다.Etherpad Lite 데이터베이스의 MySQL utf8mb4 열에서 잘못된 데이터를 디버깅하는 방법

MySQL 데이터베이스 '값'열은 utf8mb4 유형입니다. 그러나 모든 열의 약 10 %에는 실제로 UTF-8 대신 Windows-1252 또는 ISO-8859-15로 인코딩 된 값이 들어 있습니다. 이것이 어떻게 가능한지? MySQL이 UTF-8을 컬럼에 입력하기 전에 유효성을 검사하지 않습니까?

PostgreSQL은 데이터 유효성 검사 및 히트 등의 이유로 마이그레이션 중에 잘못된 값을 허용 할 수 없습니다. 원시 바이트 0xE4 (ISO-8859-15 : ä)는 UTF-8에서 바이트 시퀀스 0xC3 0xA4로 인코딩되어야합니다.

MySQL의 알려진 "기능"입니까? utf8mb4 열에서 항상 실제 UTF-8을 얻을 수있는 방법이 있습니까?

답변

0

  • 경우에 당신은 (등) 클라이언트latin1을 사용하는 말과
  • 당신은 이 UTF8 (또는 utf8mb4)라고하고,
  • 당신은 진수 E4
  • 을 제공

그러면 모두 정상입니다. E4INSERT 동안 C3A4으로 변환되며 저장된 내용입니다. 확인하려면 SELECT HEX(...) ...을 수행하십시오.

  • 경우에 당신은 클라이언트가 UTF8 (또는 utf8mb4)를 사용하여 말하는, 그리고
  • 당신은 이 UTF8 (또는 utf8mb4)라고하고,
  • 당신은 진수 C3A4을 제공

역시 모두 정상입니다. C3A4은 테이블로 직접갑니다. 여기

가 지저분한 경우 : 당신이이 latin1를 사용하는 클라이언트를 말할

  • 경우와
  • 당신은 이 UTF8 (또는 utf8mb4)라고하고,
  • 그러나 너는 16 진수를 제공합니다. C3A4

그런 다음 MySQL은 두 개의 문자 (C3 및 A4)를 utf8로 변환하여 C383C2A4을 생성해야합니다. 나는 이것을 "이중 인코딩"이라고 부른다.

Trouble with UTF-8 characters; what I see is not what I stored의 모범 사례를 따르고 제안 된 방법으로 데이터를 테스트하십시오. 그런 다음 자세한 내용을 확인하십시오.

데이터의 10 %를 잘못 해석하는 유일한 방법은 데이터의 10 %를 다르게 인코딩하는 것입니다. 따라서 10 % 예와 90 % 예를 들어 16 진수를 입력하십시오. 그리고 삽입하기 전에 클라이언트의 헥스와 삽입 된 테이블에 헥스를 제공하십시오.

+0

클라이언트가'set names utf8'이고 데이터베이스 열의 형식이'utf8mb4'이고'SELECT'가'ä' 또는 U + 00E4 대신 원시 바이트'\ xE4'를 포함하는 문자열을 반환하는 경우가 있습니다. UTF-8은 그 문자를'\ xC3 \ xA4'로 인코딩해야합니다. 데이터는 문제가 발생한 경우 node.js 서비스에서 원래 입력합니다. –

+0

그러면 utf8 인 바이트에 대해 "거짓말"합니다. 16 진수'E4'는 latin1입니다. 'U + 00E4'도 비슷하게 보일지 모르지만 latin1이나 utf8이 아닌 _unicode_입니다. 'set names utf8'은 _client_가'ä'에 대해'C3A4'라는 16 진수를 가질 것이라고 말합니다. –

+0

일반'0xE4'는 UTF-8 문자열에 나타나서는 안된다는 것에 동의합니다. 그러나 Etherpad Lite (node.js에서 실행 중)는 때때로 UTF-8 문자열 중간에 원시 Windows-1252 문자를 방출합니다. (이것이 node.js 또는 Etherpad Lite의 버그라고 생각합니다.) MySQL은 행복하게 이러한 문자열을 저장합니다. MyISAM 테이블. MySQL이 그러한 잘못된 문자열을 받아들이는 대신 예외를 던진 경우이 질문을하지 않을 것입니다. –