Nucleus(JP)フォーラム

NucleusCMS日本語版ユーザーのためのサポートフォーラムです。疑問が生じたらまずは記事検索をご利用ください。

ログインしていません。

#1 2011-04-16 23:10:58

Mocchi
メンバー
登録日: 2006-11-19
投稿: 438

Re: マルチバイト処理の概念図

本家の開発者に話を通すために概念図としてまとめたものを添付します。私が理解しているところのものを図にしただけですので、間違いなども含まれていると思います。よりよい議論のために、ここに公開します。

[attachment=0:x0xv5y87]<!-- ia0 -->multibyte_processing.png<!-- ia0 -->[/attachment:x0xv5y87]

9.4. 接続のキャラクタセットおよび照合順序 @ dev.mysql.com

クエリ「SET NAMES $charset;」は図中の「character_set_client」、「character_set_results」、「character_set_connection」を設定。

クエリ「SET CHARACTER SET $charset;」は図中の「character_set_client」、「character_set_results」、「collation_connection」を設定。この際、「collation_connection」はデータベースの「collation_database」と同じ値に設定され、それに従い「character_set_connection」も「character_set_database」と同じ値に設定される。

クエリ「SET NAMES $charset;」ではデータベースの照合順序「collation_database」と接続の照合順序「collation_connection」を同期させないため、誤変換をする可能性が高い。なお、この2つの同期と「character_set_database」と「character_set_connection」の同期は連動する。

データベースと接続する際、「character_set_database」と「collation_database」がセットされる。この場合の優先順位は以下となる。

  • 接続クエリで指定された文字符号化方式と照合順序

  • データベース作成時に指定した文字符号化方式と照合順序

  • デフォルト値「character_set_server」、「collation_server」

マルチバイト文字の処理に関しては、mbstring拡張の他に、iconv拡張もあります。後者はPHP5では標準的に利用できます。mbstring拡張のように文字符号化方式の検出機能とは用意されていませんが、それ以外はメール送信に至るまで遜色なく行うことができるようになっています。

マルチバイト文字列 @ php.net
iconv @ php.net


Attachments:
png multibyte_processing.png, Size: 132.34 KiB, Downloads: 2,069

オフライン

#2 2011-06-10 16:20:51

Mocchi
メンバー
登録日: 2006-11-19
投稿: 438

Re: マルチバイト処理の概念図

本家開発者と議論するために用意した資料です。ここに追加しておきます。


Attachments:
png byte-order.png, Size: 86.98 KiB, Downloads: 1,522

オフライン

#3 2011-07-12 03:21:48

Mocchi
メンバー
登録日: 2006-11-19
投稿: 438

Re: マルチバイト処理の概念図

本家開発者との議論で判明したことなのですが、MySQLのコネクション周りに関して、以下のルールがあることがわかりました。ひととおり整理して箇条書きにしてみます

なお、nuc-jp-dev 494 と同一の内容となります。

◎照合順序に関して
1. MySQLというシステムは、文字符号化方式(charset)を照合順序(collation)という値で扱う
2. 照合順序に関する設定は、各フィールド、各テーブル、各データベース、MySQLサーバーの4者が持つ
3. (重要)その4者は別々な設定を持つことができる

◎MySQLコネクションに関して
4. MySQLはサーバー・クライアント間で通信を行うが、その経路をコネクションという形で抽象化する
5. PHPはMySQLのクライアントである(正確には、PHPのMySQL拡張やPDO拡張がクライアント)
6. コネクションにおける文字符号化方式の設定は以下がある
character_set_client
character_set_connection
character_set_results
7. (重要)MySQLはcharacter_set_clientとcharacter_set_connectionの間、
character_set_resultsとcharacter_set_clientの間で、文字符号化方式の変換を行う


◎文字符号化方式を設定するクエリについて

8. クエリ「SET NAMES utf8;」は以下のように働く。
以下すべてをutf8に設定する。
character_set_client
character_set_connection
character_set_results

9. クエリ「SET CHARACTER SET utf8;」は以下のように働く。
以下すべてをutf8に設定する。
character_set_client
character_set_results

collation_connectionは接続しているデータベースの照合順序設定に同期する
character_set_connectionはそのcollation_connectionから導いた文字符号化方
式となる

◎問題の発生する類型

10. クエリ「SET NAMES utf8;」はデータベースやテーブル、フィールドにどんな照合順序が設定されていようがそれを無視して設定する。そのため、さまざまな文字符号化方式のデータベースを適切に利用できない可能性がある。

[PHPのC言語としての側面およびMySQL C APIの話] しかしマニュアルによるとmysql->charsetを設定することによってmysql_real_escape_stringが適切に動作するようになると言う。が、引数としての文字列の文字符号化方式と、character_set_clientが一致していれば動作に支障がないことが確認できるため、この作用は評価しなくてもよいのではないだろうか。
→mysql->charsetの本来の役割は?

11. クエリ「SET CHARACTER SET utf8;」はデータベースの照合順序は考慮するものの、データベースとフィールドの照合順序が食い違った場合に問題を発生する

◎発生する具体的な問題
12. MySQLの文字符号化方式の自動変換において、目的となる文字符号化方式(例えばlatin1=ISO-8859-1)にない文字(例えば日本語)がクエリ文字列に含まれていた場合、それは「?」に変換されて処理される
13. フィールドに設定されている照合順序の属する文字符号化方式にない文字列がそのフィールドに保存される場合、それはたしかに保存される(MySQLはキャラクターではなくバイナリーを保存するため)。しかし、フィールドの照合順序にはない文字種であるため、他のクライアント(例えばPHPMyAdmin、ターミナル)で見た場合に文字化けする。(Nucleus CMS 3.4系までの正常状態)

◎"SET CHARACTER SET xxx;"を使う理由
Nucleus CMSのインストールは、本家だと大抵がlatin1ベースのデータベースを作成。日本語版だと3.4系までlatin1ベース、3.5系以降はUTF-8ベース。インストールの過程で、各フィールド・各テーブル・データベースがそれぞれに異なる照合順序が設定されることはかなり稀な類型。

後方互換のため、データベースの照合順序をコネクションの設定に取り入れるのが無難と私は考えた。これに関しては、インストーラーやユーザーが行うデータベース設計のさまざまな類型を考慮する必要があるので、議論を継続する必要がある。

◎参考文献
MySQL5のサーバーとクライアントのコネクションにおける照合順序および文字符号化方式について
9.4. 接続のキャラクタセットおよび照合順序

MySQL5 APIのC言語用バインディングのマニュアル(PHP5はC言語で書かれている)
23.2.3.53. mysql_real_escape_string()
23.2.3.61. mysql_set_character_set()

PHP5マニュアル
mysql_real_escape_string
mysql_set_charset

文字符号化方式 (MySQLでの呼び名)
ISO-8859-1 (latin1)
UTF-8 (utf8)
ISO-2022-JP (unknown)
Shift_JIS (sjis or cp932?)
EUC-JP (ujis)

符号化文字集合
ASCII
国際符号化文字集合(UCS) (JIS X 0221:2007)
7ビットおよび8ビットの2倍と情報交換用符号化漢字集合(JIS X 0208: 1978)
7ビットおよび8ビットの2倍と情報交換用符号化拡張漢字集合(JIS X 0213: 2004)

オフライン

Board footer