2017-09-06 16 views
0

私たちはEtherpad Liteを実行しており、MySQLからPostgreSQLにデータベースを移行しようとしています。Etherpad LiteデータベースのMySQL utf8mb4カラムの無効なデータをデバッグする方法

MySQLデータベースの 'value'列の形式はutf8mb4です。しかし、実際にはUTF-8の代わりにWindows-1252またはISO-8859-15でエンコードされた値をすべての行の約10%が含んでいます。これはどのように可能ですか? MySQLはUTF-8を列に入力する前に検証しませんか?

PostgreSQLは、データの検証やヒットなどの理由で、移行中に無効な値を受け入れることができません。生のバイト0xE4(ISO-8859-15:ä)は、UTF-8で0xC3 0xA4のバイトシーケンスとしてエンコードされる必要があります。

これはMySQLの「機能」として知られていますか? utf8mb4列から実際のUTF-8を取得する方法はありますか?

答えて

0

あなたはクライアントはあなたが進E4を提供latin1(など)を使用して、そして

  • あなたはは、UTF8(またはutf8mb4)であると言う、そして
  • されると言う

    • 場合

    すべてが順調です。 E4INSERTの間にC3A4に変換され、それが保存されます。確認するにはSELECT HEX(...) ...してください。

    • 場合はクライアントは、UTF8(またはutf8mb4)を使用していると言う、そして
    • あなたは は、UTF8(またはutf8mb4)であると言う、そして
    • あなたは六角C3A4を提供します

    また、すべて正常です。 C3A4はテーブルに直接入ります。

    ここで厄介なケースです:あなたはクライアントはあなたがは、UTF8(またはutf8mb4)であると言うlatin1、および

  • を使用して、そして
  • されると言う

    • 場合

    • しかし、あなたは16進数を指定します。C3A4

    次に、の2つの文字(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

    私はUTF-8文字列では普通の '0xE4'は現れないはずだと同意します。しかし、Etherpad Lite(node.jsで動作)は、UTF-8文字列の途中で生のWindows-1252文字を出力することがあります(これはnode.jsやEtherpad Liteのバグだと思います)。 MyISAMテーブルMySQLがこのような無効な文字列を受け入れる代わりに例外をスローした場合、私はこの質問をしません。 –

    関連する問題