web-dev-qa-db-ja.com

MySQLの照合/文字セットのレベルが異なるのはなぜですか?

MySQLサーバー変数を見ると、サーバーとデータベースの照合順序はlatin1_swedish_ciに設定されていますが、collaction_connectionはutf8_general_ciです。さらに、照合/文字セットは、サーバー、データベース、テーブル、列など、多くのレベルで設定されます。 PHP MySQL接続の文字セットも考慮する必要があります。

私の質問は4つあります。

  1. MySQL照合/文字セットのレベルが異なるのはなぜですか?これは、ニーズに合わせて文字セットを混合できるようにするためですか?私が間違っているが、utf8が一般的な使用に最適な文字セットであるように思われる場合、修正してください。

  2. PHP接続が作業中のデータベースの文字セットと一致することを常に確認する必要がありますか?

  3. 異なる文字セットを使用する異なるテーブルを使用できる場合、SET NAMESまたはmysql(i)_set_charsetを使用して切り替えますか?

  4. 複数の文字セットを持つテーブルがある場合、接続は一度に1つの文字セットしか使用できないので、それをどのように管理しますか?

どうもありがとう。

編集:

コメントについて:

「いずれかを使用できます。前者は結果の文字セットを設定するためにのみ使用し、後者はmysqli_real_escape_stringと結果のエンコーディングで使用するPHP内部エンコーディングを設定するために使用します。」

Real_escape_stringとSET NAMESを一緒に使用するつもりはないと思いました。参照: http://www.php.net/manual/en/mysqlinfo.concepts.charset.php

6
texelate

質問1

MySQL照合/文字セットのレベルが異なるのはなぜですか?

質問#1への回答

異なる文字セットと照合順序には2つの理由があります

理由#1:ディスク容量

このクエリを実行すると

SELECT
    maxlen,
    GROUP_CONCAT(CHARACTER_SET_NAME) CharSets,
    COUNT(1) CharSetCount
FROM information_schema.character_sets
GROUP BY maxlen\G

あなたはこれを手に入れます:

mysql> SELECT
    ->     maxlen,
    ->     GROUP_CONCAT(CHARACTER_SET_NAME) CharSets,
    ->     COUNT(1) CharSetCount
    -> FROM information_schema.character_sets
    -> GROUP BY maxlen\G
*************************** 1. row ***************************
      maxlen: 1
    CharSets: cp1257,cp850,binary,koi8r,latin2,ascii,tis620,koi8u,greek,armscii8,keybcs2,macroman,latin7,cp1251,cp1256,dec8,hp8,geostd8,latin1,swe7,hebrew,cp1250,latin5,cp866,macce,cp852
CharSetCount: 26
*************************** 2. row ***************************
      maxlen: 2
    CharSets: big5,cp932,sjis,gbk,ucs2,euckr,gb2312
CharSetCount: 7
*************************** 3. row ***************************
      maxlen: 3
    CharSets: eucjpms,ujis,utf8
CharSetCount: 3
*************************** 4. row ***************************
      maxlen: 4
    CharSets: utf16,utf32,utf8mb4
CharSetCount: 3
4 rows in set (0.00 sec)

mysql>

一部の文字セットは、文字を表すために最大長が1バイトです。他はもっと必要です。この情報を提供すると、VARCHARおよびTEXTデータがディスク上のスペースを節約できるように、eucjpms、ujis、utf8、utf16、utf32、utf8mb4文字セットの使用を控えることができます。

理由#2:国際化

文字セットには、さまざまな言語に対応するための1つ以上の照合順序が付属しています

このクエリを実行すると

SELECT
    A.CHARACTER_SET_NAME,
    GROUP_CONCAT(COLLATION_NAME) Collations,
    COUNT(1) CollationCount
FROM
    information_schema.character_sets A
    INNER JOIN information_schema.collations B
    USING (CHARACTER_SET_NAME)
GROUP BY A.CHARACTER_SET_NAME\G

一部の文字セットには、ヨーロッパのさまざまな地域の複数の照合順序があることがわかります。中国語、日本語、ギリシャ語、アジアの一部、スカンジナビアもご利用いただけます。

質問2

PHP接続が作業中のデータベースの文字セットと一致することを常に確認する必要がありますか?

質問#2への回答

[〜#〜]シナリオ[〜#〜]

午前3時に運転しています。あなたは道を行く唯一の運転手です。あなたは交差点に来ます。あなたは赤い光を持っています。

質問:停止するか、赤信号を通過しますか?

Answer:近隣に依存

  • 安全な近所?
    • 一部は法律を遵守し、赤で停止し、緑を待ちます。
    • いくつかのチャンスそれを通過します
  • 悪い近所や地域に新しいですか?
    • 法律を順守し、赤で停止し、緑を待つATカージャックのリスク
    • チャンスを逃して、回避するOR改ざんのリスクを軽減する
    • 最悪の場合を想定して別のルートを見つける

これはどのように適用されますか?

注意を怠らないようにしてください。近隣(クライアントプログラム、インターネットブラウザー)が分からないため、常に事前に文字セットを確認する必要がありますPHP接続が開始され、カージャックの危険がある場合(無効なデータをデータベース、検索するには多すぎるデータを要求)。

質問#3

異なる文字セットを使用する異なるテーブルを使用できる場合、SET NAMESまたはmysql(i)_set_charsetを使用して切り替えますか?

質問#3への回答

ぜひ

質問#4

複数の文字セットを持つテーブルがある場合、接続は一度に1つの文字セットしか使用できないので、それをどのように管理しますか?

質問#4への回答

DBセッションで文字セットをシフトする必要がある場合があります。セッションレベルで変更できる設定は次のとおりです。

データベースを読み書きする前に、これらを注意深く設定してください。また、アクセスするのと同じテーブルに文字セット名と照合順序を保存するのも賢明です。

2
RolandoMySQLDBA

実際には、接続文字セットは必ずしもテーブル文字セットと同じである必要はありません。 MySQLは自動的にデータをテーブル文字セットから接続文字セットに変換します。

したがって、UTF-8への接続文字セットを確立する場合、テーブルにある文字セットが何であれ、MySQLから正しいデータを取得する必要があります。

ただし、たとえば、latin1からUTF-8への変換は、UTF-8からlatin1への変換と同じではないことに注意してください。最後のケースでは、latin1に対応する値がない一部の文字を失う可能性があります。

そのため、どこでもUTF-8を使用することは間違いなく最良の選択です。

1
claustrofob

私は最後の3つだけを持っています。
そして、それは答えよりもむしろ明確化でしょう

2。PHP接続が作業中のデータベースの文字セットと一致していることを常に確認する必要がありますか?

場合によります。実際にPHP接続文字セットを設定する必要があるのは、GBKのようないくつかの限界エンコーディングを使用している場合のみです。UTF-8を使用すると、デフォルトとして設定できますlatin1問題ありません。
しかし、あなたが本当に義務的に設定する必要があるのはresults charsetです。作成しているHTMLページの文字セットと一致する必要があります。

。異なる文字セットを使用する異なるテーブルを使用できる場合、SET NAMESまたはmysql(i)_set_charsetを使用して切り替えますか?

Mysqlは前述の結果文字セットに設定したエンコーディングにすべてのテーブル文字セットを再コード化するため、異なるテーブル文字セットがあるかどうかは実際には問題になりません。
どちらを使用してもかまいません。前者は結果の文字セットを設定するためにのみ使用し、後者はmysqli_real_escape_stringおよび結果のエンコーディングで使用するためのPHP内部エンコーディングを設定するために使用します。

4。複数の文字セットを含むテーブルがある場合、接続は一度に1つの文字セットしか使用できないため、それをどのように管理しますか?

同上。

0