私はMySQLデータベースからいくつかのデータをエクスポートしようとしていますが、そのテーブルのユニコードに奇妙で素晴らしいことが起こっています。
左のスマートクォートの1つのキャラクターに焦点を当てます。
コンソールからSELECT
を使用すると、問題なく出力されます。
_mysql> SELECT text FROM posts;
+-------+
| text |
+-------+
| “foo” |
+-------+
_
これは、データがutf-8 [0](正しい)として端末に送信されていることを意味します。
ただし、_SELECT * FROM posts INTO OUTFILE '/tmp/x.csv' …;
_を使用すると、出力ファイルはnot正しくエンコードされます。
_$ cat /tmp/x.csv
“fooâ€
_
具体的には、_“
_は7(7!)バイトでエンコードされます:_\xc3\xa2\xe2\x82\xac\xc5\x93
_。
これはどのエンコーディングですか?または、どうすればMySQLに不合理なエンコーディングを使用するように指示できますか?
また、いくつかのその他の事実:
SELECT @@character_set_database
_は_latin1
_を返しますtext
列はVARCHAR(42)
:です_
mysql> DESCRIBE posts;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| text | varchar(42) | NO | MUL | | |
+-------+-------------+------+-----+---------+-------+
_
“
_ utf-8としてエンコードすると_\xe2\x80\x9c
_が得られます\xe2\x80\x9c
_は_latin1
_としてデコードされ、その後_utf-8
_として再エンコードされて_\xc3\xa2\xc2\x80\xc2\x9c
_(6バイト)が生成されます。…
_(utf-8:_\xe2\x80\xa6
_)は_\xc3\xa2\xe2\x82\xac\xc2\xa6
_にエンコードされます[0]:スマートクォートは8ビットエンコーディングに含まれておらず、私の端末はutf-8文字を正しくレンダリングします。
MySQLの新しいバージョンには、outfile句に文字セットを設定するオプションがあります。
SELECT col1,col2,col3
FROM table1
INTO OUTFILE '/tmp/out.txt'
CHARACTER SET utf8
FIELDS TERMINATED BY ','
これがうまくいくことがわかりました。
SELECT convert(col_name USING latin1) FROM posts INTO OUTFILE '/tmp/x.csv' …;
MySQLデータベースを見るとわかるように、latin1
およびシステムはutf-8
。
mysql> SHOW VARIABLES LIKE 'character\_set\_%';
+--------------------------+--------+
| Variable_name | Value |
+--------------------------+--------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
+--------------------------+--------+
7 rows in set (0.00 sec)
テーブルをエクスポートしようとするたびに、奇妙なエンコードされたCSVファイルを取得しました。だから、私は置きます:
mysql_query("SET NAMES CP1252");
header('Content-Type: text/csv; charset=cp1252');
header('Content-Disposition: attachment;filename=output.csv');
export script のように。
次に、純粋なUTF-8出力があります。
「これは何ですか?」という質問に具体的に答えるために、あなたは自分で答えました。
これは、「列の値がバイナリ文字セットを使用してダンプされるため」と思われます。実際には、文字セットの変換はありません。」 -dev.mysql.com/doc/refman/5.0/en/select-into.html
これは、MySQLがutf8
エンコードされたデータを内部的に保存する方法です。 Unicodeストレージの非常に非効率的なバリエーションであり、明らかにほとんどの文字に完全な3バイトを使用しており、4バイトのUTF-8シーケンスをサポートしていません。
INTO OUTFILE
...を使用して実際のUTF-8に変換する方法については、わかりません。ただし、他のmysqldump
メソッドを使用すると実行できます。
CLIツールを使用してMySQLクエリを実行し(CSVを出力する出力形式でも可能)、ファイルにリダイレクトできます。文字セットの変換を行いながら、結合などを行うためのアクセス権を与える必要があります。
SET CHARACTER SET <blah>
選択の前、<blah>=utf8
またはlatin1
etc ...参照: http://dev.mysql.com/doc/refman/5.6/en/charset-connection.html
またはSET NAMES utf8;
動作する可能性があります...
SELECT
を実行する前に、MySQLプロンプトでcharset utf8
を発行する必要があります。これは、結果の出力先をサーバーに指示します。