MySQLにUTF-8を適切に処理させる方法


102

私が昨日尋ねた質問に対する回答の1つは、データベースがUTF-8文字を正しく処理できることを確認する必要があることを示唆しています。MySQLでこれを行うにはどうすればよいですか?


4
MySQLのさまざまなバージョン、非互換性などを網羅した包括的な回答が得られることを本当に望んでいます
Edward Z. Yang


1
@ EdwardZ.Yang-MySQL 4.1が導入されましたCHARACTER SETs。5.1.24は、ドイツ語のシャープ(s)の照合に混乱しました。これは、5.1.62に別の照合を追加することによって修正されました(おそらく事態を悪化させています)。5.5.3新しい文字セットutf8mb4でutf8を埋めた。
リックジェームズ

1
この質問はこの質問とまったく同じです。そのstackoverflow.com/questions/3513773/を
Nyein Aung

これらの回答のほとんどがまったく間違っていることを指摘する価値があります。使用しないでくださいutf8。最大3バイトの文字のみをサポートします。MySQLで使用する正しい文字セットはutf8mb4です。
ブレンダンバード

回答:


89

更新:

短い答え-ほとんどの場合、utf8mb4文字セットとutf8mb4_unicode_ci照合を使用する必要があります。

データベースを変更するには:

ALTER DATABASE dbname CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

見る:

元の答え:

MySQL 4.1以降のデフォルトの文字セットはUTF-8です。これをmy.cnfファイルで確認できます。必ずクライアントとサーバーの両方を設定してください(default-character-setおよびcharacter-set-server)。

UTF-8に変換する既存のデータがある場合は、データベースをダンプし、UTF-8としてインポートし直してください。

  • SET NAMES utf8データベースにクエリ/挿入する前に使用します
  • DEFAULT CHARSET=utf8新しいテーブルを作成するときに使用
  • この時点で、MySQLクライアントとサーバーはUTF-8である必要があります(を参照my.cnf)。使用する言語(PHPなど)もUTF-8でなければならないことに注意してください。PHPの一部のバージョンは、独自のMySQLクライアントライブラリを使用しますが、UTF-8に対応していない場合があります。

既存のデータを移行したい場合は、まずバックアップすることを忘れないでください!予定どおりに進まない場合、データの奇妙なチョッピングが大量に発生する可能性があります。

いくつかのリソース:


29
私の理解では、utf8MySQL内では完全なUnicodeの小さなサブセットしか参照されていません。utf8mb4代わりにを使用して、完全なサポートを強制する必要があります。mathiasbynens.be/notes/mysql-utf8mb4を参照してください 「長い間、データベース、テーブル、カラムにMySQLのutf8文字セットを使用ていましたが、上記のUTF-8エンコーディングにマッピングされていると想定しています。」
アーロンマクデイド2013

7
MySQLには、UTF-8のデフォルトの文字セットがありませんでした。4.1および5.xから最新の5.7まではlatin1、すべてlatin1_swedish_ciデフォルトの文字セットと照合順序で使用されます。MySQLマニュアルの「サーバーの文字セットと照合順序」ページで確認してください:dev.mysql.com/doc/refman/5.1/en/charset-server.html
Animism

2
@TimTisdall utf8mb4ほとんどのテキストがASCIIの場合、余分なストレージを取得する必要はありません。char文字列は事前に割り当てられていますが、varchar文字列は割り当てられていません。このドキュメントページの最後の数行を参照してください。たとえば、char(10)utf8mb4で悲観的に40バイトvarchar(10)を予約しますが、可変長エンコーディングに合わせてバイトを割り当てます。
Kevin A.Naudé2014年

1
@ケビン私はあなたがそれを誤解していると思います。行の最大長は64kだと思います。utf8mb4フィールドをその1/4しか作成できません。これは、その量のスペースを予約する必要があったためです。したがって、ASCIIであっても、16k文字しか挿入できません。
Tim Tisdall、2014年

1
@TimTisdallああ、あなたは上限について話している。はい、それらは低いです。幸い、MySQLの現在のバージョンは自動的にアップグレードされますvarchar(n)text、あなたが変更しようとした場合、データ型varchar(n)(警告を発行中)実現可能なバイトサイズよりも大きいにフィールドを。インデックスには、ワーストケースの上限が低くなるため、他の問題が発生する可能性があります。
Kevin A.Naudé2014年

44

これを「永続的」にするには、my.cnf次のようにします。

[client]
default-character-set=utf8
[mysqld]
character-set-server = utf8

確認するには、クライアントに移動していくつかの変数を表示します。

SHOW VARIABLES LIKE 'character_set%';

MySQLインストールのどこかを指すとutf8を除いて..._filesystem、すべてであることを確認します。binary..._dir


私の場合はうまくいきませんでしたが、とにかく与えられた内容で/ etcにファイルmy.cfを作成しました。私が使用しましたcreate table my_name(field_name varchar(25) character set utf8);
Marek Bar

"SHOW VARIABLES LIKE 'character_set%';" コマンドで、接続に問題があることがわかりました。ありがとう!
javsmo 2015

1
これは正しくありません。MySQLが呼び出すものutf8は「完全な」UTF-8ではありません。
TWR Cole

32

MySQL 4.1以降には、デフォルトの文字セットが呼び出されますutf8が、実際にはUTF-8のサブセットのみです(3バイト以下の文字しか許可されていません)。

utf8mb4「完全な」UTF-8が必要な場合は、文字セットとして使用してください。


5
間違いなく同意する、これが唯一の正しい答えです。utf8絵文字のような文字は含まれません。utf8mb4します。更新方法の詳細については、これを確認してください:mathiasbynens.be/notes/mysql-utf8mb4
jibai31

@Basti-ほとんど正しい(latin1は最近までデフォルトだった)、完全ではない(utf8でエンコードされたデータの正しい挿入/選択、またはhtmlでの表示については説明していません)。
リックジェームズ

敬具、@ RickJames、バスティは「これまでのところ」と言った-私がこれを投稿したときにあなたの答えを見たことを覚えていない。
TWR Cole

悲しいかな、utf8の問題には5つのはっきりと異なる症状があり、プログラマーが問題を引き起こすために間違っていることは4つあります。ほとんどの回答は、修正が必要な可能性があることを1つだけ指摘しています。元の質問は幅広い質問だったので、答えは4つすべて必要でした。おそらくバスティは、あなたの1つの側面が解決策であった1 つの症状をよく知っていました。
リックジェームズ

8
余談ですが、少し間を置いて、MySQLチームに非常に優れたハードな凝視を提供したいと思います。o_o WTF皆さんは考えていましたか?実際にUTF-8ではない "utf8"と呼ばれるコードページをプログラムに作成することで、どれほどの混乱が生じたかを理解していますか?いまいましいろくでなし。</ rant>
TWR Cole

20

短い答え:utf8mb44つの場所で使用します。

  • クライアントのバイト数は、latin1 / cp1251 / etcではなく、utf8です。
  • SET NAMES utf8mb4 またはMySQLへのクライアントの接続を確立するときに同等のもの
  • CHARACTER SET utf8mb4 すべてのテーブル/列-厳密にascii / hex / country_code / zip_code / etcの列を除く。
  • <meta charset charset=UTF-8>HTMLに出力する場合。(はい、ここではスペルが異なります。)

詳細 ;
ずっとUTF8

上記のリンクは、「すべての懸念に対処するには詳細な標準的な回答が必要です」を提供します。-このフォーラムにはスペースの制限があります。

編集する

CHARACTER SET utf8mb4「すべて」の世界の文字が含まれていることに加えて、「オールCOLLATION utf8mb4_unicode_520_ciラウンドな」最高の照合順序を使用することもできます。(これらの言語でニュアンスを求めている人のために、トルコ語、スペイン語などの照合もあります。)


あなたが得る出力からutf8問題をデバッグする方法に関する私の新しいリンク
リックジェームズ

なぜunicode_520_ciが一番良くないのか:stackoverflow.com/a/49982378/62202
Louis

@Louis-そして、私がスペイン語とトルコ語(そしてポーランド語)を暗示するように、ユーザーは満足しないかもしれません。「最高のオールラウンド」は、みんなを傷つける傾向があります。MySQL 8.0にはさらに新しい「最良の」照合があります:utf8mb4_0900_ai_ci。悲しいかな、再びL =Ł。
リックジェームズ

4

文字セットは、データベース(デフォルト)とテーブルのプロパティです。あなたは見ることができます(MySQLコマンド):

show create database foo; 
> CREATE DATABASE  `foo`.`foo` /*!40100 DEFAULT CHARACTER SET latin1 */

show create table foo.bar;
> lots of stuff ending with
> ) ENGINE=InnoDB AUTO_INCREMENT=252 DEFAULT CHARSET=latin1

言い換えると; データベースの文字セットを確認したり変更したりするのは非常に簡単です。

ALTER TABLE `foo`.`bar` CHARACTER SET utf8;

1
これは正しくありません。MySQLが呼び出すものutf8は「完全な」UTF-8ではありません。
TWR Cole


2

ハビエルのソリューションに従いましたが、my.cnfにいくつかの異なる行を追加しました。

[myslqd]
skip-character-set-client-handshake
collation_server=utf8_unicode_ci
character_set_server=utf8 

私はこのアイデアをここに見つけました:http : //dev.mysql.com/doc/refman/5.0/en/charset-server.htmlページの一番下の最初の/唯一のユーザーコメント。彼は、スキップ文字セットクライアントハンドシェイクがいくつかの重要性を持っていると述べています


この愛されないゼロ投票の答えが私を助けた唯一のものでした!だから、私の投票を得る、それは確かに確かです。 skip-character-set-client-handshake鍵でした
マーカス



-1

あなたの答えは、MySQL設定で構成できます。私の答えでは、文脈から外れたものがあるかもしれませんが、これはあなたのための助けであることもわかっています。
設定方法Character SetCollation

デフォルトのMySQL文字セットと照合(latin1, latin1_swedish_ci)を使用してデータを保存するアプリケーションの場合、特別な設定は必要ありません。アプリケーションで別の文字セットまたは照合順序を使用したデータストレージが必要な場合は、いくつかの方法で文字セット情報を構成できます。

  • データベースごとに文字設定を指定します。たとえばutf8、あるデータベースを使用するアプリケーションにはが必要な場合がありますが、別のデータベースを使用するアプリケーションにはsjisが必要な場合があります。
  • サーバー起動時に文字設定を指定します。これにより、サーバーは、他の調整を行わないすべてのアプリケーションに対して指定された設定を使用します。
  • ソースからMySQLをビルドする場合は、構成時に文字設定を指定します。これにより、サーバーはすべてのアプリケーションに対して指定された設定を使用します。サーバーの起動時にそれらを指定する必要はありません。

utf8文字セットを設定するための質問の例を次に示します。ここでも照合を設定して、より役立つ(utf8_general_cicollat​​ion`)ようにしています。

データベースごとに文字設定を指定する

  CREATE DATABASE new_db
  DEFAULT CHARACTER SET utf8
  DEFAULT COLLATE utf8_general_ci;

サーバー起動時に文字設定を指定する

[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci

MySQL構成時に文字設定を指定する

shell> cmake . -DDEFAULT_CHARSET=utf8 \
           -DDEFAULT_COLLATION=utf8_general_ci

接続に適用される文字セットと照合システム変数の値を表示するには、次のステートメントを使用します。

SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';

これは長い答えかもしれませんが、すべての方法があり、使用できます。私の答えがあなたに役立つことを願っています。詳細については、http://dev.mysql.com/doc/refman/5.7/en/charset-applications.html


-2

SET NAMES UTF8

これはトリックです


2
SET NAMES UTF8(またはUTF8mb4)の使用は正しいですが、それが何をするか(この接続に使用される文字セット)については説明しません。「これでうまくいく」とは問題を解決するようです(MySQLがUTF-8を適切に処理するようにします)が、多くのMySQLデータベースはデフォルトでlatin1に設定されているため、適切な解決策にはなりません。私は考えデフォルトの文字セット変更 utf8mb4に、テーブルの文字セットを。本当に、この回答はかなり不完全なので、私は反対に投票しました。
基本

-2

UTF-8へのデータベース接続

$connect = mysql_connect('$localhost','$username','$password') or die(mysql_error());
mysql_set_charset('utf8',$connect);
mysql_select_db('$database_name','$connect') or die(mysql_error());

-3

データベース接続をUTF8に設定します。

  if($handle = @mysql_connect(DB_HOST, DB_USER, DB_PASS)){          
         //set to utf8 encoding
         mysql_set_charset('utf8',$handle);
  }

PHPを実行している場合は、非推奨のmysql_*インターフェースを使用しないでください。mysqli_*またはに切り替えますPDO
リックジェームズ

-3

解決策を見つけることができました。http://technoguider.com/2015/05/utf8-set-up-in-mysql/で指定されているように、以下を実行しました

SET NAMES UTF8;
set collation_server = utf8_general_ci;
set default-character-set = utf8;
set init_connect = SET NAMES utf8′;
set character_set_server = utf8;
set character_set_client = utf8;

最初のものは、すでにそれらの含まれているので、最後の2行は、冗長である:dev.mysql.com/doc/refman/5.0/en/charset-connection.html
DanielM

また、完全なソリューションでもありません。列にはが必要CHARACTER SET utf8です。 root重要なすべてを実行しませんinit_connect
リックジェームズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.