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

mysql:13827

From: MORIYAMA Masayuki <MORIYAMA Masayuki <moriyama@xxxxxxxxxx>>
Date: Mon, 26 Mar 2007 17:03:47 +0900
Subject: [mysql 13827] Re: MySQLの現行UTF-8の問題とその対処方法について

森山です。

松信さん、詳しい解説ありがとうございます。

Yoshinori Matsunobu wrote:
> ●そもそもの問題
> Windows Vistaから標準でサポートされるJIS X 0213:2004には、
> UTF-8表現で4バイトとなる文字が存在します。
> このような文字はMySQLのcharset utf8で定義した文字列型の列には入れることがで
> きません。
> MySQLのutf8は3バイト文字までしか対応していないためです。
> 不正な文字として扱われ(その意味でCESU-8とは異なると私は理解しています)、
> 「その4バイトのUTF-8の文字以降の全ての文字列が削除された上で格納される」
> という動作をします。これは現時点の「仕様」と位置づけられています。

UTF-16 から UTF-8 への変換で UTF-8 の 3 バイトまでしかサポートせず、サロ
ゲートペアを意識せずに変換すると CESU-8 になるとの理解でいます。

# 以下、CESU-8 としている所は、3 バイトまでの対応の UTF-8 とお考えくださ
# い。

Unicodeスカラ値   UTF-16       UTF-8          CESU-8
---------------  ---------  -----------  -----------------
   U+10000       D800 DC00  F0 90 80 80  ED A0 80 ED B0 80

UTF-16 から UTF-8 への変換は、本来、UTF-16 のサロゲートペアをUnicodeスカ
ラ値(UTF-32) に変換してから、UTF-8 に変換するという事をしなければならな
いのですが、CESU-8 は、サロゲートペアを意識せずに単純変換して 3 バイト x
2 = 6 バイトに変換するようになっています。

ですので、MySQL の utf8 は、CESU-8 と言っていいと思います。

Unicode Technical Report #26
Compatibility Encoding Scheme for UTF-16: 8-Bit (CESU-8)
http://www.unicode.org/unicode/reports/tr26/

参考)
  XML文字メーリングリストでの CESU-8 のスレッド
  http://www2.xml.gr.jp/log.html?MLID=xmlmoji&TID=1145&F=0&L=10&R=0
  http://www2.xml.gr.jp/log.html?MLID=xmlmoji&TID=1175&F=0&L=10&R=0

> ●計画している対処案
> MySQL社内では、以下のような実装案を検討しています。
> 
> 1.現行エンコーディングutf8(3バイト)を4バイトに拡張する。(残るのは新utf8)

本来のあるべき姿と思います。

CESU-8 を前提としたアプリがあった場合に、このような変更は非互換を生む事
になりえるので慎重に検討する必要があるでしょう。

ただ、現実問題として、あまり使われることがない文字の対応の為にアプリケー
ション側で、UTF-8 <-> CESU-8 変換をして、データベースに格納するというよ
な処理をしているとも思えないので、非互換が問題になることは、ほとんどない
のではないかと思いますが…

> 2.現行エンコーディングutf8(3バイト)はそのまま残し、UTF-8 4バイト対応の新しい
> エンコーディングutf8_4を追加する。
> (残るのはutf8と新utf8_4)

MySQL の互換性維持を考えると、この案を検討する必要はあるでしょう。

しかし、他のソフトで正しく実装している UTF-8 とのデータ交換の際に、
utf8_4 を使うようにする必要があり、それが周知徹底できるか?
という問題があるように思います。

> 3.現行エンコーディングutf8(3バイト)の名称をutf8_oldに変更する。そして
> UTF-8 4バイト対応のエンコーディングutf8を追加する。(残るのはutf8_oldと新
> utf8)
> ステータス変数でどちらを使うかを切り替えられるようにし、同時に使えるのは片方
> のみ

個人的には、この案が現実的なのではないかと思います。

> 4.新しいエンコーディングutf16を導入する(残るのはutf8と新utf16)
> 
utf8 の問題は解決されないように思います。

> 森山さんご指摘のように、RFC3629ではUTF-8は4バイトまでで良くなっていることな
> どから、
> 6バイトでなく4バイトで良いと考えています。
> 
> 先日のOSCでは1と2について話をしましたが、実際には3と4も検討されています。
> 1が一番分かりやすいですが、既存環境との干渉が懸念されています。
> 2は、2つのUTF-8系エンコーディングが並立することになるので、
> クライアントアプリ等でどちらを使うかを意識しないといけないなどの課題がありま
> す。
> 吉岡さんのご指摘は、OSCでの私の説明を受けて、
> 2ではなく1を取るべき、とされたものです。
> 3は1と2の折衷案という位置づけです。

仕様変更に伴う非互換の問題を考えなくてよいのであれば、1 にするのが単純明
解で良いですね。

2 のような案が出てくるのは、仕様変更による非互換の問題を極力起こさせない
ように考慮する場合と理解しています。

スッキリとしない対応方法となってしまいますが、Oracle では UTF8 という名
前で CESU-8 が実装されていて、AL32UTF8 で 4 バイト対応の UTF-8 が実装さ
れている事を考えると、現実的な対応方法の 1 であろうとは思います。

MySQL の utf8 が仕様変更される事によるインパクトと、MySQL の utf8 が RFC
3629 の UTF-8 とは異なる事によるインパクトのどちらの方が大きいのかという
事も考えないといけませんね。

--
森山 将之 <moriyama@xxxxxxxxxx>

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

     13823 2007-03-26 07:21 ["Yoshinori Matsunobu] MySQLの現行UTF-8の問題とその対処方法について
     13826 2007-03-26 16:34 ┣[SUGAWARA Hajime <sug]                                       
->   13827 2007-03-26 17:03 ┗[MORIYAMA Masayuki <m]