[前][次][番号順一覧][スレッド一覧]

mysql:10205

From: "Zen Kishimoto" <"Zen Kishimoto" <zen@xxxxxxxxxx>>
Date: Tue, 21 Sep 2004 16:06:57 -0700
Subject: [mysql 10205] unicodeの翻訳再ポスト

皆様

質はともかくと言いましたが、あまり前の投稿が
ひどかったので、再ポストします。やはり最近セットした
Linuxで初めからやるべきでした。

岸本
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

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)
・ iconv extension: iconv(from, to, string)
・ recode extension: recode_string(request, string)
・ 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 



[前][次][番号順一覧][スレッド一覧]