mysql:10204
From: "Zen Kishimoto" <"Zen Kishimoto" <zen@xxxxxxxxxx>>
Date: Tue, 21 Sep 2004 12:18:55 -0700
Subject: [mysql 10204] Unicodeの話の翻訳
皆様、 時々、www.mysql.com の中から記事を選んで 翻訳して来ましたが、マーケティングの記事だけでなく 技術的なものもやったらどうかというご指摘がありました。 技術バックグランドがあるとはいえ、どうもボロがでそうです。 また現在のアレンジメントでは質より量ですので、怪しげ な日本語や誤った変換はご了承ください。 それで、 http://dev.mysql.com/tech-resources/articles/ の最初の記事 を選んでみました。 http://dev.mysql.com/tech-resources/articles/4.1/unicode.html 特にどれとかご希望があれば、それを優先的にします。ところで、 この記事のなかで日本語の全文検索はできてないと明示してあります。 岸本 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー Jim Winstead MySQL 4.1 の新しい機能の1つはUnicode へのサポートで、これは多くの異なったレベルで文字セットを指定できます。この機能であなたが使うアプリケーションで様々な言語のサポートを簡便にします。そして、初めの頃のMySQLではサポートされていなかった複数バイトの言語をサポートすることができます。 文字エンコーディングとUnicode 文字エンコーディングは文字(例えばA)を文字セットの整数にマップする方法です。この場合AはUS-ASCII セットでは65にマップされます。US-ASCII の文字セットは(米国文字セッ トは英語のアルファベット大文字・小文字の26字の他、数字0から9とその他句読点)、1バイトの言語には十分です。しかし、ドイツ語、スエーデン語、ハンガリー語や日本語用の文字セットをサポートしようとして、2つの言語を同時に表示しようとすると8ビット・バイトの壁にぶつかります。日本語などの言語にいたっては1つの言語でも表示できません。 コンピューティングの歴史を通じて、文字を整数に変換する幾つものエンコーディングの方法が開発されました。1バイトでおさまらない文字のセット用には2バイト文字セットが開発されました。また1バイトと2バイトのエンコーディングを切り替える特殊文字を使用する複数バイト文字セットも開発されました。 Unicodeコンソーシアムは全ての言語をカバーする文字エンコーディングの仕様を開発しました。それが、Unicode 文字セットと幾つかのエンコーディングです。そのうち一番良く使用さ れる2つ(MySQLはどちらもサポート)は全てを2バイトにマップするUCS-2とUS-ASCIIを拡張する複数バイト・エンコーディングのUTF-8です。 ISO-8859-1は西洋言語で一番良く使われる文字セットで、Windows-1252 文字セットはそれを更に拡張してユーロ(?)やトレードマーク(?)のような文字を含みます。Windows-1252 はISO-8859-1を含むので、この文字セットは ,MySQL ではlatin1として知られています。この2つはウエブのアプリケーションでは同等に取り扱われています。 それならどうして全てに関してUCS-2 か UTF-8を使用しないのでしょうか。既にある特定のエンコーディングでのデータをたくさん持っていたとします、例えばBig-5(中国語によく使用されます)。そうであれば、Big-5でデータを格納した方がUTF-8に変換してまた戻すという手間が省けます。UTF-8 エンコーディングは他の特定のエンコーディングよりもバイト数を食い ます。それはASCII の範囲外の文字は最低2バイトを食うからです。"deja vu"というストリングは ISO-8859-1では7バイトですがUTF-8では9バイトです。中国語、日本語、 朝鮮語では3バイトを必要とします。しかし、Big-5などの特定のエンコーディングでは2バイトで済みます。 照合順序 並び順番の例 言語 スエーデン語 z < o ドイツ語 o < z 使用 (ドイツ語) 辞書: of < of 電話: of < of 照合順序(Collation) テキスト情報のユニットを並べるプロセス。照合は特定の言語に特有 ? Unicode 語彙 ストリングをソートすることはよく必要とされます。しかし、全員が同じ文字のセットを使用していないことに加えて皆が同様に同じ文字列をソートしません。照合順序は文字列ソートする方法を定義しますが、たいていの場合は言語に依存します。スエーデン語とドイツ語は通常ISO-8859-1エンコーディング(latin1)を使用しますが、この2つの言語には異なってソートされる文字があります。(実はドイツ語のなかにも2種類のソートの仕方があります。)例のテーブルをみてください。 Unicode照合順序アルゴリズム(UCA)はUnicodeのストリングをソートする一般アルゴリズムです。そのほかにもDefault Unicode Collation Element Table (DUCET)があります。これは全て のUnicode の文字の並ぶ順序を規定しています。 MySQL 4.1 はこのアルゴリズムを実装します。この方が特別な照合順序を実現するのに工数が少なくて済むからです。例えば、ucs2_lithuanian_ci 照合順序 (MySQL 4.1のソースからのstrings/ctype-uca.c) の仕様があります。 static const char lithuanian[]= "& C << ch <<< Ch <<< CH< \\u010D <<< \\u010C" "& E << \\u0119 <<< \\u0118 << \\u0117 <<< \\u0116" "& I << y <<< Y" "& S < \\u0161 <<< \\u0160" "& Z < \\u017E <<< \\u017D";4.0での対応 MySQL 4.0 (とそれよりも古い版では)幾つかの文字セットといくらかのレベルで指定される1バイト文字エンコーディングのみをサポートしました。デフォルトはlatin1でしたが,それはMySQL 4.1ではlatin1の文字セットと latin1_swedish_ci の照合順序に対応します。 テーブルには文字セットおよび照合順序の情報は含まれません。またMySQL 4.0 では文字セット間の変換へのサポートはありません。他のデータに変換するためにはサーバーの文字セットを変換して新たなツールを使用する必要がありました。 MySQL 4.0 を使用するアプリで複数バイト・エンコーディング(例えばUTF-8)を使用するデータを扱う際のやり方はデータをVARCHAR フィールド (またはTEXT, CHAR, など)に格納することでし た。アプリケーションでサーバがあると思って実は文字セットにないストリングを誤ってソートすることを無視するか、アプリ内でソートするしかありません。この方法はうまく行きましたが、全てのエンコーディングをアプリ内で処理する必要がありました。またこのため、MySQL の全文検索の機能を使うことができませんでした。 4.1での対応 MySQL 4.1 は多くの文字セットと照合順列のサポートを提供します。カラムのレベルからサーバのデフォルトまでサポートします。それぞれの接続毎にデータ転送の際の文字セットも指定できます。 マニュアルの"Determining the Default Character Set and Collation" の章に文字セットと照合順列の指定の方法がそれぞれのレベルで(server, database, table, column, connection, string literal)説明されています。 一番簡単な方法はサーバーにどの文字セットを接続の際に使用するかをSET NAMES で指定してください。その際、サーバが使うアプリに対して一番良い文字セットにコンフィギュアーされているかを確認してください。(もちろんデータベース毎に異なったデフォルトが必要かも知れません。) アプリがMySQL 4.0 (またはそれより古い版) のクライアントのライブラリーでビルドされていても、MySQL 4.1でサポートされている新しい文字セットを利用できます。前の版では サーバーとクライアント間で交換されるデータのエンコーディングに関しては関知しないので、接続をUTF-8 に設定するかUTF-8 string literalをサーバにデータを転送する際に指定 します。(1バイトでUS-ASCII のスーパーセットの文字セットを利用している場合は、そのまま使用できます。) 4.0から4.1へのマイグレーション MySQL 4.0を使ってきて、デフォルトのサーバの文字セットに関係なく、UTF-8データをストリングのコラムに格納している場合、MySQL 4.1にマイグレートした後、サーバーにこのコラムの本当の 文字セットを通知しておいた方がよいです。しかし、ALTER TABLE myTable MODIFY myColumn VARCHAR(255) CHARACTER SET utf8とやるとサーバは, myColumn にあるデータをサーバのデフォルトからUTF-8に変換しようとします。これを避けるために次の2つのステップを踏んでください。 ALTER TABLE myTable MODIFY myColumn BINARY(255); ALTER TABLE myTable MODIFY myColumn VARCHAR(255) CHARACTER SET utf8;同じテーブル内に複数のコラムがある場合、全てのコラムに関して同時に同じステップを繰り返す必要があります。これはそれぞれのコラムを変更するステップ毎に全部のテーブルが再構築されるのを防ぐためです。"Converting 4.0 Character Columns to 4.1 Format" の章に例が載っています。 すでにMySQL 4.0で特定のサーバで特定の文字セットを使っているのであれば、どのように文字セットが新しい文字セットや照合順列にMySQL 4.1でマップするかはマニュアルの"4.0 Character Sets and Corresponding 4.1 Character Set/Collation Pairs" の章を参照してください。 ウエブでUTF-8 を使う 古い版のブラウザーは無視するとして、ウエブ上でUTF-8 のデータを扱うのは容易です。ドキュメントのヘッダーか本文に文字セットを指定するだけです。例えば以下のPHPのスクリプト見てください。 <?php header("Content-type: text/html; charset=utf-8");?><html> <head> <meta http-equiv="Content-type" value="text/html; charset=utf-8"> ...もしHTMLのページにフォームがあればブラウザーはページで指定された文字セットで結果を返還します。UTF-8で送れば、UTF-8で結果が返ってきます。HTMLドキュメントのデフォルトのエンコーディングはISO-8859-1です。それでデフォルトでフォームのデータのエンコーディングはISO-8859-1となりますが、これには例外があります。あるブラウザー(Microsoft の インターネット・エクスプロラーとアプルのサファリ) はデータをWindows-1252のエンコードで送ります。このエンコードはISO-8859-1の拡張版でユーロ (?) やクオート(“”)を含みます。 古いブラウザーの場合いろいろと問題が生じます。ひとつの方法はhidden field をクライアントが文字セットは正しくセットしないとデータがコラプトしそうなフォームに組み込むことです。 <input type="hidden" name="charset_check" value="a?R">W3Cが発表している正規表現で内容がUTF-8に準拠しているか確認してください。 もしデータがUTF-8に準拠していないかまたは, UTF-8に返還したい他の文字セットのデータを扱っていると分かっているときは、 PHPを使って変換することができます ・ mbstring extension: mb_convert_encoding(string, to, from) a.. iconv extension: iconv(from, to, string) b.. recode extension: recode_string(request, string) c.. built-in function: utf8_encode(string) (converts from ISO-8859-1 to UTF-8) 入力の処理はこんな感じになります。 <?php$test = $_REQUEST['charset_check']; /* our test field */$field = $_REQUEST['field']; /* the data field */ if (bin2hex($test) == "c3a4e284a2c2ae") { /* UTF-8 for "a?R" */ /* Nothing to do: it's UTF-8! */} elseif (bin2hex($test) == "e499ae") { /* Windows-1252 */ $field = iconv("windows-1252", "utf-8", $field);} else { die("Sorry, I didn't understand the character set of the data you sent!");} mysql_query("INSERT INTO table SET field = _utf8'" . addslashes($field) . "'") or die("INSERT failed: " . mysql_error());これから ここまでに、いかにデータをMySQLに格納するかを示しました。後はマニュアルの"Character Set Support" の章を読んで文字セットの研究をしてください。文字セットへと国際化されたデータへのサポートは将来のMySQL の版で更に増強されます。例えば、さらに多くの照合順列(例 えばペルシア語 (ucs2_persian_ci) はMySQL 4.1.5から), 日本語のような言語でどのようにして単語を理解して全文検索を可能にするか、そしてもっと多くの言語のサポートです。 Metadataに関して MySQL 4.1版からサーバはメタデータをUTF-8エンコーディングで処理します。CURRENT_USER()のような関数はデフォルトでUTF-8の文字セットを使用します。これが意味することはユーザ、テーブル、データベースをつくる際にUnicode で定義される文字を 使用できることです。もっとも、ファイルシステムがファイル名を処理する際に生ずるミスマッチのためにエラーが生じるかも知れませんが --------------------- Zen Kishimoto zen@xxxxxxxxxx IP Devices, Inc. (408) 567-9391 2175 De La Cruz Blvd., Suite 10 (801) 720-8847 (FAX) Santa Clara, CA 95050