さまざまなマルチバイト文字セットが広く使用されているため、ソフトウェア開発に携わる英語を話すプログラマーのかなりの割合がマルチバイト文字についてあまり知りません。これが、近年の多くの脆弱性がマルチバイト文字に起因する理由です。この記事の著者は、MySQL の文字セット アーキテクチャの役割について彼自身の見解を語ります。 ここ数か月間、MySQL を使用するたびに、ほぼ常に次のように考えています。MySQL の現在の階層文字セット アーキテクチャは本当に便利なのでしょうか?
MySQL 文字セットの処理
リクエストの送信
クライアント (character_set_client)=》データベース接続 (character_set_connection)=》ストレージ (テーブル、カラム)
返品リクエスト
ストレージ(テーブル、カラム)=》データベース接続(character_set_connection)=》クライアント(character_set_results)
先頭以外の各ノードで、前のノードから現在のノードまで文字セット変換操作が実行されます。たとえば、次の環境を考えてみましょう。
◆ 文字セット接続 utf-8
◆ 文字セット結果 gbk
◆ キャラクターセット_クライアント gb2312
◆ テーブル A があり、フィールドの文字セットはすべて BIG5 です
リクエストを送信すると、データはまず gbk から utf-8 に変換され、次に BIG5 に変換されてから保存されます。
リクエストを返すとき、データはまず BIG5 から utf-8 に変換され、次に gb2312 に変換されて、クライアントに送信されます。
建築の役割
1. 異なるクライアントに異なる文字セットを使用できるようにします。典型的な例は、UTF-8 クライアントの文字セットを持つクライアントである UTF-8 サイトを持っていることです。同時に、別のクライアントである gbk 端末でデータベースの読み取りと書き込みを行う必要がある場合がありますが、その文字セットは gbk です。
2. データベースを通じてファイル システムを操作する場合、ファイル パスをファイル システムの文字セットに変換する必要があります。たとえば、私のクライアントは gbk で、サーバーのファイル システムは utf-8 です。オペレーション「/Aスライス/Rina.rmvb」は、送信されたデータのうち、「スライス」のデータがサーバーとは異なります。現時点では、GBK の「スライス」を utf-8 に変換する方法が必要です。ここで、MySQL はこれを実現するために、character_filesystem と呼ばれるものを導入しています。
それ以外の用途は今のところ思いつきません。しかしよく考えてみてください、本当にこのような治療が必要なのでしょうか?多くの Web サイトは、データが自由に公開されることを望んでいます。ここにはさらに 2 つの状況があります。
1. データに基づいて並べ替えたり、同様の操作を実行できれば幸いです。まず並べ替えについて説明します。中国語を含むフィールドの場合、文字セットに基づいて並べ替えるという概念は役に立ちません。簡体字中国語を並べ替える場合、通常はピンインで並べ替えることができます。 MySQL での検証についてはよく理解していませんが、私が接したプログラムから判断すると、この種の並べ替えが必要な場合は、並べ替え用のピンインを保存するためのフィールドが特別に作成されます。ピンインには多声文字もあります。 UTF-8であれば、一定範囲の中国語が中国、日本、韓国で同時に共有される状況もあります。実装はそれほど簡単ではないため、GBK も MySQL の UTF-8 チェックセットもピンインを実装すべきではありません。あえて言えば、現在 MySQL を使用している中国のほとんどの Web サイトでは、単なるバイト ソートのチェック セットが使用されています。バイトソートを使用すると、文字セットを使用する必要がまったくありません。したがって、中国語サイトの場合、MySQL の文字検証はソートに意味を持ちません。
しかし、同様の操作という点では、少し意味があります。たとえば、「%a%」が好きであれば、ある部分に「a」を含む漢字を一致させることができます。もちろん、UTF-8 ではこの状況は発生しません。UTF-8 の記憶形式では、 a は a のみであり、マルチバイト文字の一部であることはできないためです。ただし、この問題は他の文字セットでも発生する可能性があります。結局、いいねは順番と同じになってしまい、検証の意味がなくなってしまいます。気が遠くなる。
2. Like や全文検索などデータを並べ替える必要がない場合は、char、varchar、text などの使用をやめてください。 binary、varbinary、BLOB が正しい選択です。 Binary などは格納時や取得時に文字セット変換を行いませんが、ソート時にはバイナリの内容に従ってソートされるだけなので、char、varchar、text に比べて効率が非常に高くなります。
この場合、文字セットは必要ありません。ただし、現在の MySQL アーキテクチャによれば、クライアントと接続の間の文字セット操作は、フィールド タイプを無視してこれら 2 つのノード間で引き続き実行されます。
PHPにおける文字セットの設定についても言及します。 mysql_query("set names utf8") のようなステートメントの使用はやめてください。 mysql_set_charset() は、最も完全な文字セット設定メソッドです。後者には前者よりも設定が 1 つ多くあり、それは struct MySQL の charset メンバーを設定することです。このメンバー変数は、特に文字の一部として「」を使用する GBK などのエンコード形式の場合、エスケープにおいて非常に重要な役割を果たします。 mysql_query("set names XXX") のみを使用する場合、一部の文字セットでは重大なセキュリティ ホールが発生し、mysql_real_escape_string がaddslashes と同じくらい安全でなくなります。
-