Treasure Data - Support Engineering Team blog

トレジャーデータのサポートエンジニアリングチームのブログです。

文字コードについて

こんにちは、Treasure Data(TD) サポートの伊藤です。

今回はTDを利用する上で気にすることがあるであろう、文字コードについて取り上げたいと思います。

文字コードとは

Wikipedia曰く、下記説明があります。

文字コード(もじコード)は、コンピュータ上で文字(キャラクタ)を利用する目的で各文字に割り当てられるバイト表現。もしくは、バイト表現と文字の対応関係(文字コード体系)のことを指して「文字コード」と呼ぶことも多い。本記事では主に後者について記述する。

TDを利用する部分に限れば、私達が目にする文字を内部ではどのように表現しているのか、そのマッピング表だと思えば十分でしょう。

具体的には、UTF-8S-JISEUCなどを目にしたことがあるかと思います。UTF-8S-JIS を利用しているという方が多いと思いますので、本記事では他の文字コードについては触れないことはご容赦ください。

ASCII(シングルバイト文字)

良く目にする文字コードとして UTF-8S-JIS が挙げられるかと思いますが、どちらの文字コードも ASCII という文字コードを拡張したものです。

ではその ASCII とは何かと言いますと、簡単に言ってしまえば 半角の英数字(記号を含む) を 1Bytes(8bit)で表現した文字の集合体です。 そのため、ASCII を拡張した UTF-8S-JIS は半角英数のみを見ると同じ表現となっています。

文字 ASCII UTF-8 S-JIS
A 0x41 0x41 0x41

※ 0x は16進数を表すための接頭辞です

UTF-8S-JIS(マルチバイト文字)

日本語には良くも悪くも、ひらがな、カタカナ、漢字といった種類の文字があります。半角英数字に加えてこれらの表現するには1バイトだけ利用する ASCII だけでは足りなかったため、2バイト以上の領域を用いて表現する文字コードが必要でした。

そこで生み出された文字コードが下記になります。1バイトの ASCII コードで表現される文字を シングルバイト文字、2バイト以上必要な下記文字コード達で表現される文字を マルチバイト文字 と呼ぶこともあるでしょう。

これらの違いとして、S-JISは2バイト文字、UTF-8は3バイト以上の文字で表現することが挙げられます。下記で言えば、「あ」という文字を S-JIS では 32、A0という2バイトで表現しますが、 UTF-8 は E3、81、82という3バイトで表現します。

文字 UTF-8 S-JIS
0xE38182 0x82A0

また、S-JISは日本語を表現するための文字コードである一方、UTF-8は日本語以外の文字も表現可能です。グローバル化が珍しくない近年では UTF-8 を採用しているシステムが多いかと思います。

TDを取り扱う上での文字コード

TDを利用する上で意識するのは下記3種類かと思います。

f:id:td-support:20201214184550j:plain
文字コードを考える上でTDに関連する箇所

  1. TDに格納されているときの文字コード
  2. インポート対象の文字コード
  3. エクスポート先の文字コード

もしサポート問い合わせされる際は、どの部分を気にしているのかを明確にしていただけると認識の齟齬が発生しづらく良いかと思います。 ではそれぞれ細かく見ていきましょう。

TDに格納されている際の文字コード

TDに格納されているデータは UTF-8 で保持されています。 インポート元の文字コードが何であれ UTF-8 です。そのため後述しますが、インポート時に UTF-8 に変換されるという仕組みになっています。

インポート対象の文字コード

TDへインポートする際に、インポート元の文字コードを指定することで UTF-8 に正しく変換することができます。

f:id:td-support:20201214184825p:plain
インポート時に文字コードを設定する

正しい文字コードを指定しない場合は、間違った文字コードで変換してしまい文字化けしてしまいます。例えば UTF-8csvファイルを S-JIS としてインポートすると テスト という文字列が文字化けしていることからわかるかと思います。

f:id:td-support:20201214185231p:plain
意図的に文字コードを間違えてみた結果

一度文字化けしてしまうと、UTF-8で想定していない文字になってしまっているので、TD上で元に戻すことはできません。意図しない結果を防ぐためにも、マルチバイト文字を含むデータを初めてインポートした際は文字化けしていないか確認すると良いでしょう。

エクスポート時の文字コード

エクスポート先の文字コードUTF-8 のみサポートされています。

エクスポート時の例外

TDコンソールにて実行したクエリ(Hive/Presto)の結果をダウンロードするときのみ S-JIS としてダウンロードすることが可能です。

f:id:td-support:20201214185305p:plain
クエリ結果をダウンロードするときに文字コードを指定する

文字コードTips

エクスポート先の文字コードを確認したら UTF-8 じゃないんだけど!?

「エクスポートしたときに S-JIS となっているので、明示的に UTF-8 としてエクスポートしたい」という問い合わせをよく頂戴しますが、UTF-8 以外の文字コードでエクスポートすることができないため、勘違い・認識違いのはずです。

原因として、おそらくエクスポートするデータが半角英数字のみなのではないかと考えられます。 先述した通りTDは UTF-8 としてエクスポートしますが、含まれる文字が全て半角英数字なのであれば ASCII の範囲になるため S-JIS としても解釈できます。

エクスポートしたファイルをテキストエディタ(秀丸サクラエディタなど)で開くと文字コードS-JIS と表示されることがあり、 一見UTF-8 ではないように見えるかもしれません。その場合、文字コードUTF-8 として対象ファイルを開き直してみてください。文字化けなどせず同じデータが表示されるはずです。

また、csvファイルを確認する際にExcelを利用される方も多いかと思います。 その際、ファイルにマルチバイト文字が含まれるのであれば、下記スクリーンショットのようにして文字コードを明示的に指定して開くことをお勧めします。

f:id:td-support:20201222095307p:plain
Excel文字コードを指定してファイルを開く

TDコンソールで□□□と表示されるんだけど!?

珍しい事象ではありますが、下記のように□□□□□□と表示されてしまうケースがあります。

f:id:td-support:20201214185419p:plain
□□□と表示される

これはTDコンソール上正しく表示できていないだけで、正しく格納されている(□という文字として格納されているわけではない)ことが期待されます。エクスポートすると期待した文字が出力されていると思います。

最後に

長々と説明してきましたが、TDを利用する上で下記2点を意識いただくだけで十分かと思います。 文字コードについて悩んでいた方のお力になれたら嬉しいと思います。