3

これは奇妙なパズルです。私の知る限り、utf8_bin は、すべてのアクセントがデータベースに適切に格納されることを保証する必要があります。つまり、ASCII への奇妙な変換は行われません。だから私はそのようなテーブルを持っています:

DEFAULT CHARSET=utf8 COLLATE=utf8_bin

それでも、MySQL によると、「Kr​​ąków」と「Kraków」などのエントリを比較/クエリ/何でもしようとすると、これは同じ文字列です。

好奇心から私は utf8_polish も試しました。

では、アクセントなどを失うことなく、ユニコード文字列を安全に保存できるように、MySQL テーブルをセットアップする方法は?

サーバー: MySQL 5.5 + openSUSE 11.4、クライアント: Windows 7 + MySQL Workbench 5.2。

更新 -- テーブルの作成

CREATE TABLE `Cities` (
  `city_Name` VARCHAR(145) CHARACTER SET utf8 NOT NULL,
  PRIMARY KEY (`city_Name`)
) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

テーブル全体が utf8_bin であるため、列に別のutf8_bin を設定できないことに注意してください。したがって、実際には、列の照合はデフォルトにリセットされます。

4

2 に答える 2

2

ソリューションのすべてのクレジットはbobinceに送られるので、私の質問に対する彼のコメントに賛成票を投じてください。

この問題の解決策はやや奇妙で、MySQL はこの点で壊れていると言う危険があります。

ですから、utf8 でテーブルを作成し、列に対して何もしなかったとしましょう。後で文字を厳密に比較する必要があることに気がついたので、テーブル AND カラムの照合を utf8_bin に変更します。解決しましたか?

いいえ、MySQL はこれを認識します。テーブルは確かに utf8_bin ですが、列も utf8_bin です。これは、列がテーブルの DEFAULT 照合を使用することを意味します。ただし、MySQL は以前のデフォルトが現在のデフォルトと同じではないことを認識していません。したがって、比較はまだ機能しません。

したがって、列のデフォルトを、照合「ファミリ」の範囲外のエイリアン値に振り替える必要があります(「utf8xxx」の場合、他の「utf8xxx」は意味しません)。それが振り落とされ、列の照合で「デフォルト」と表示されていないエントリが表示されると、utf8_bin を設定できます。これは現在、デフォルトとして評価されますが、デフォルト以外の照合から来ているため、すべてが期待どおりに開始されます。

各ステップで変更を適用することを忘れないでください。

于 2013-02-17T21:11:18.543 に答える
0

テーブルの作成時に、MySQL のデフォルトの文字セットと照合順序 (サーバー全体に適用されますが、接続ごとに変更できます) が適用されます。テーブルの作成後にデフォルトを変更しても、既存のテーブルには影響しません。

文字セットと照合順序は、個々の列の属性です。これらはテーブル全体のデフォルトから設定できますが、列に属しています。

すべてのヨーロッパ言語を正しく表現するには、utf8 の文字セットで十分です。"a" と "ą" を 2 つの異なる文字として確実に格納できるはずです。

utf8-bin の照合では、大文字と小文字およびアクセント付き文字を区別する照合が行われます。

テキスト値と照合動作の違いの例をいくつか示します。'abcd'、'ĄBCD'、'ąbcd' の 3 つのサンプル文字列を使用しています。最後の 2 つは A-ogonek 文字を持っています。

この最初の例は、utf8 文字表現と utf8_general_ci 照合では、3 つの文字列がそれぞれユーザーの指定どおりに表示されますが、比較すると等しいことを示しています。これは、a と ± を区別しない照合では当然のことです。これは、大文字と小文字を区別しない典型的な照合であり、すべてのバリアント文字が分音記号のない文字と同じように並べ替えられます。

SET NAMES 'utf8' COLLATE 'utf8_general_ci';
SELECT 'abcd', 'ąbcd' , 'abcd' < 'ąbcd',  'abcd' = 'ąbcd';
                               false            true  

この次の例は、大文字と小文字を区別しないポーランド語の照合順序で、a が ± の前に来ることを示しています。ポーランド語はわかりませんが、ポーランドの電話帳では As と Ą が分かれているのではないかと思います。

SET NAMES 'utf8' COLLATE 'utf8_polish_ci';
SELECT 'abcd', 'ĄBCD' , 'ąbcd', 'abcd' < 'ĄBCD', 'abcd' < 'ąbcd' , 'ąbcd' = 'ĄBCD' 
                                      true             true              true

この次の例は、utf8_bin 照合で何が起こるかを示しています。

SET NAMES 'utf8' COLLATE 'utf8_bin';
SELECT 'abcd', 'ĄBCD' , 'ąbcd', 'abcd' < 'ĄBCD', 'abcd' < 'ąbcd' , 'ąbcd' = 'ĄBCD' 
                                      true           true               false

この場合、直観的でないことに注意してください。'abcd' < 'ĄBCD' は真です (ピュア ASCII の 'abcd' < 'ABCD' は偽)。言語学的に考えれば、これは奇妙な結果です。これは、両方の A-ogonek 文字が、すべての abc および ABC 文字よりも高い utf8 のバイナリ値を持っているためです。したがって、ORDER BY 操作に utf8-bin 照合を使用すると、言語的に奇妙な結果が得られます。

あなたは、'Krąków' と 'Kraków' は同等であり、それに当惑していると言っています。使用中の照合が utf8_general_ci の場合、それらは同等に比較されます。しかし、utf8_bin や utf8_polish_ci ではそうではありません。MySQL のポーランド語サポートによると、都市名のこれら 2 つのスペルは異なります。

アプリケーションを設計するときは、これらすべてを言語的にどのように機能させるかを整理する必要があります。「Króków」と「Kraków」は同じ場所ですか? 「イアロン」と「アーロン」は同一人物ですか?もしそうなら、utf8_general_ci が必要です。

表示したテーブルを次のように変更することを検討できます。

  ALTER TABLE Cities
MODIFY COLUMN city_Name 
              VARCHAR(145)
              CHARACTER SET utf8 
              COLLATE utf8_general_ci

これにより、テーブルの列が希望どおりに設定されます。

于 2013-02-17T15:13:27.153 に答える