MySQLデータベースに絵文字を保存する方法


172

プロジェクトで絵文字を使用しています。その文字はmysqlデータベースに保存(??)されます。でデータベースのデフォルト照合を使用していましたutf8mb4_general_ci。それは示す

1366文字列値が正しくありません:行1の列 'comment'の '\ xF0 \ x9F \ x98 \ x83 \ xF0 \ x9F ...'


1
データをどのように保存していますか?そのコードを見せていただけますか?
Tomas Buteler

1
コメントありがとうございます。この変更データベースのデフォルトのコレクションの解決策は** utf8mb4 **であり、変更テーブルのコレクションは** CHARACTER SET utf8mb4 COLLATE utf8mb4_bin **です。 ALTER TABLE Tablename CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin
Selvamani P 2016

1
コード:insert into tablename (column1,column2,column3,column4,column5,column6,column7) values ('273','3','Hdhdhdh😜😀😊😃hzhzhzzhjzj 我爱你 ❌',49,1,'2016-09-13 08:02:29','2016-09-13 08:02:29'データベース接続にutf8mb4を設定します: $database_connection = new mysqli($server, $user,$password,$database_name); $database_connection->set_charset("utf8mb4");
Selvamani P

回答:


29

ステップ1、データベースのデフォルトの文字セットを変更します。

ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

ステップ2、テーブルの作成時に文字セットを設定します。

CREATE TABLE IF NOT EXISTS table_name (
...
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;

またはテーブルを変更

ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE table_name modify name text charset utf8mb4;

これらのクエリに従い、mysqlサーバーを停止して再起動しましたが、テーブルに絵文字を挿入しようとすると、同じエラーが発生します。INSERTを除くすべてのコマンドが成功しました。INSERT INTO Entries(date、time、caption)VALUES(2018-05-20 '、'12:38:00'、 'Testing description with emoji:😊❤️'); 列の設定は、照合順序を以下のとおりです。utf8mb4_0900_ai_ci定義:説明テキスト

1
接続は、utf8ではなくutf8mb4である必要もあります。
Henrik Hansen

3
@ospider、ステップ2では、Unicodeの代わりにutfmb4_general_ciを使用します-理由は何ですか?
ウォーレン

263

1)データベース:データベースのデフォルトの照合をに変更しますutf8mb4

2)テーブル:テーブル照合をとして変更しますCHARACTER SET utf8mb4 COLLATE utf8mb4_bin

クエリ:

ALTER TABLE Tablename CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin

3)コード:

INSERT INTO tablename (column1, column2, column3, column4, column5, column6, column7)
VALUES ('273', '3', 'Hdhdhdh😜😀😊😃hzhzhzzhjzj 我爱你 ❌', 49, 1, '2016-09-13 08:02:29', '2016-09-13 08:02:29')

4)utf8mb4データベース接続で設定:

  $database_connection = new mysqli($server, $user, $password, $database_name); 
  $database_connection->set_charset('utf8mb4');

4
データベースのデフォルトのコレクションを変更せずに可能ですか?
AliN11 2016年

23
これは私のために働いていません。「???」が表示されます スマイリーの代わりに。"☺"だけがデータベースに安全に到達しました。
好奇心旺盛な開発者

10
テーブルをutf8mb4に更新するだけでなく、列自体も更新する必要がある場合があります。そうでない場合、列は?? 💙の代わりに。
Ael

2
私にとってはうまくいきましたが、MySQLを再起動することを忘れないでください。
Ravi Misra

8
SET NAMES utf8mb4;絵文字の保存を開始するには、実行する必要があります。そのコマンドの前にそれはそれらを次のように保存していました??
cubbuk 2018

18

データベースとテーブルの両方に文字セットutf8mb4と照合順序が必要utf8mb4_unicode_ciです。

新しいデータベースを作成するときは、以下を使用する必要があります。

CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

あなたは持っている場合は、既存のデータベースを、あなたはサポートを追加したいです:

ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

また、テーブルに正しい文字セットと照合順序設定する必要があります。

CREATE TABLE IF NOT EXISTS table_name (
    ...
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;

または、大量のデータを含む既存のテーブルがある場合は、次のように変更します。

ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

utf8_general_ci推奨されなくなったことに注意してください。関連するQ&Aを参照してください。

スタックオーバーフローでのutf8_general_ciとutf8_unicode_ciの違いは何ですか


二ALTERステートメントを実行するときに、私は、データベースとテーブル含むdata.andを持っている、と言うこと:ERROR 1833(HY000):できない変更欄「ID」:外部キー制約テーブルの「FK12njtf8e0jmyb45lqfpt6ad89」「lizbazi.post」で使用される
Seyyed Mahdiyar Zerehpoush

@SeyyedMahdiyarZerehpoush -あなたがここで説明するように、それを必要とする特定の列に、あなたの更新を制限して逃げることができるかもしれません: stackoverflow.com/a/15781925/1247581例えばALTER TABLE mytable MODIFY my_emoji_friendly_text_column VARCHAR(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
theartofrain

列にutf8mb4_binvs utf8mb4_unicode_ciを使用するときの違いはありますか?
ムハンマドオメルアスラム

14

Solr + Mysql + Javaを使用している場合は、以下を使用できます。

これは使用できます:

  • case1:DBを変更したくない場合。
  • case2:絵文字をMysqlからSolrコアにインポートする必要がある場合。

上記の場合、これはシステムに顔文字を保存するためのソリューションの1つです。

それを使用する手順:

使用するライブラリ:import java.net.URLDecoder; import java.net.URLEncoder;

  1. urlEncoderを使用して、絵文字を含む文字列をエンコードします。
  2. MysqlDBを変更せずにDBに保存します。
  3. 必要に応じて、solrコア(デコードされたフォーム)に保存するか、エンコードされたフォームを保存できます。
  4. これらの絵文字をDBまたはSolrコアからフェッチするときに、urlDecoderを使用してデコードできるようになりました。

コード例:

import java.net.URLDecoder;
import java.net.URLEncoder;

public static void main(String[] args) {
    //SpringApplication.run(ParticipantApplication.class, args);
    System.out.println(encodeStringUrl("🇺🇸🇨🇳🇯🇵🇩🇪🔳🔺🆔🆔🆑3⃣5⃣3⃣‼〽➗➗🎦🔆🎦🔆♋♍♋♍⬅⬆⬅⬅🛂🚹🛂🛄🚳🚬💊🔧💊🗿     "));
    System.out.println(decodeStringUrl("Hello+emoticons%2C%2C%F0%9F%98%80%F0%9F%98%81%F0%9F%98%8A%F0%9F%98%8B%F0%9F%98%8E%F0%9F%98%8A%F0%9F%98%8D%E2%98%BA%F0%9F%98%98%E2%98%BA%F0%9F%98%91%F0%9F%98%87%F0%9F%98%98%F0%9F%98%8B%F0%9F%90%84"));
}

public static String encodeStringUrl(String url) {
    String encodedUrl =null;
    try {
         encodedUrl = URLEncoder.encode(url, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        return encodedUrl;
    }
    return encodedUrl;
}

public static String decodeStringUrl(String encodedUrl) {
    String decodedUrl =null;
    try {
         decodedUrl = URLDecoder.decode(encodedUrl, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        return decodedUrl;
    }
    return decodedUrl;
}

このコードスニペットをありがとうございます。このコードスニペットは、限られた、即時の助けを提供する可能性があります。適切な説明は、なぜこれが問題の優れた解決策であるを示すことにより、長期的な価値を大幅に改善し、他の同様の質問を持つ将来の読者にとってより有用になります。答えを編集して、仮定を含めて説明を追加してください。
Toby Speight 2017年

1
私は実際にコンテンツのセッターとゲッターにコードとデータベースのみのデータモデルを変更する必要はありませんので、魅力のような仕事は、私は、モデルでそれを使用
bowpunya

1
エンコード/デコード関数呼び出しは問題を引き起こす傾向があります。代わりに、さまざまな場所で文字セット設定を修正してください。
リックジェームズ

1
これは問題を解決していない、これはそれを回避しています。また、この方法では多くの問題が発生します。たとえば、すべてをデコードおよびエンコードする必要があるため、アプリケーションの速度が低下します。また、文字を入力する%と、デコードが失敗します。
Jonathan Laliberte

14

データベースとテーブルをutf8からutf8mb4にアップグレードするように更新しました。しかし、私には何もうまくいきません。次に、列のデータ型をblobに更新しようとしましたが、幸いにもうまくいき、データは保存されました。私のデータベースとテーブルも文字セットですutf8 COLLATE utf8_unicode


13

列を変更するコマンドは次のとおりです。

ALTER TABLE TABLE_NAME MODIFY COLUMN_NAME TYPE;

そして、type =を使用する必要があります BLOB

変更する例は次のとおりです:-

ALTER TABLE messages MODIFY content BLOB;

最新のmySQLと他のデータベースが''table_name、column_nameなどのコマンドで使用する必要がないことを確認しました。

データのフェッチと保存: チャットコンテンツを列に直接保存してデータを取得し(byte[])、db列からバイト配列としてデータをフェッチして、stringたとえば(Javaコード)に変換します。

new String((byte[]) arr) 

2
はい。絵文字のようなユニコードを特定のフィールドに格納する必要があるだけの場合、受け入れられる答えはあまりにも煩わしいものです。単にtext/ varcharフィールドをaに変更blobすれば完了です。そのためにDB全体で文字セットと照合を変換する狂気:)
davidkonrad

9

私の回答はセルバマニPの回答に追加されます。

SET NAMES utf8クエリを変更する必要がある場合もありSET NAMES utf8mb4ます。それは私にとってはトリックでした。

また、これは Webサイトをutf8からutf8mb4に移植するための優れた記事です。特に、この記事では、インデックスとテーブルをutf8mb4に変換した後の修復について、2つの優れた点を示しています。

インデックス

utf8からutf8mb4に変換する場合、列またはインデックスキーの最大長はバイト単位で変更されません。したがって、文字の最大長が3バイトではなく4バイトになっているため、文字数の点でより小さくなっています。[...] InnoDBストレージエンジンの最大インデックス長は767バイトであるため、utf8またはutf8mb4列の場合、それぞれ最大255文字または191文字のインデックスを作成できます。現在、インデックスが191文字を超えるutf8列がある場合、utf8mb4を使用するときは、より少ない数の文字にインデックスを付ける必要があります。

テーブルの修理

MySQLサーバーをアップグレードし、上記で説明した必要な変更を行った後、必ずすべてのデータベースとテーブルを修復および最適化してください。アップグレード後すぐにこれを実行せず(一見すべてが正常に機能するように思われたため、必要だとは思いませんでした)、UPDATEステートメントが効果がないにも関わらず、奇妙なバグに遭遇しました。エラーがスローされました。

記事のテーブルを修復するクエリの詳細をご覧ください。


REPAIR TABLEそして、それOPTIMIZE TABLEは不必要なはずです- ALTERは、それらを実行する効果があります。
リックジェームス

5

上記の回答では、要点は言及されていません。

オプション"useUnicode=yes""characterEncoding=UTF-8"接続文字列でクエリ文字列を渡す必要があります

このようなもの

mysql://USERNAME:PASSWORD@HOSTNAME:PORT/DATABASE_NAME?useUnicode=yes&characterEncoding=UTF-8

5

まあ、DB全体の文字セットを変更する必要はありません。その代わりに、列をblob型に変更することでそれを行うことができます。

ALTER TABLEメッセージMODIFYコンテンツBLOB;


3

私はあなたの時間を節約する良い解決策を持っています。私も同じ問題を抱えていますが、最初の答えではこの問題を解決できませんでした。

デフォルトの文字はutf-8です。しかし、絵文字をサポートするには、utf8mb4が必要です。mysqlの構成ファイルを変更する権限がある場合は、この手順に従うことができます。

したがって、次の手順を実行して、文字セットをアップグレードします(utf-8からutf8mb4へ)。

手順1. mysqlのmy.cnfを開き、次の行をmy.cnfに追加します。

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
init_connect='SET NAMES utf8mb4'

[mysql]
default-character-set = utf8mb4


[client]
default-character-set = utf8mb4

ステップ2。mysqlサービスを停止し、mysqlサービスを開始します

mysql.server stop
mysql.server start

完成しました!次に、キャラクターがutf8mb4に変更されていることを確認できます。

mysql> SHOW VARIABLES LIKE 'character_set%';
+--------------------------+----------------------------------------------------------+
| Variable_name            | Value                                                    |
+--------------------------+----------------------------------------------------------+
| character_set_client     | utf8mb4                                                  |
| character_set_connection | utf8mb4                                                  |
| character_set_database   | utf8mb4                                                  |
| character_set_filesystem | binary                                                   |
| character_set_results    | utf8mb4                                                  |
| character_set_server     | utf8mb4                                                  |
| character_set_system     | utf8                                                     |
| character_sets_dir       | /usr/local/Cellar/mysql@5.7/5.7.29/share/mysql/charsets/ |
+--------------------------+----------------------------------------------------------+
8 rows in set (0.00 sec)

2

技術スタックを持つアプリケーションの絵文字サポート-mysql、java、springboot、hibernate

ユニコードをサポートするには、mysqlに以下の変更を適用します。

  1. ALTER DATABASE <database-name> CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
  2. ALTER TABLE <table-name> CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

DB接続-jdbc urlの変更:

jdbc:mysql://localhost:3306/<database-name>?useUnicode=yes&characterEncoding=UTF-8

注-上記の手順が機能しない場合は、mysql-connectorのバージョンを8.0.15に更新してください。(mysql 5.7はユニコードをサポートするためにコネクタバージョン8.0.15で動作します)


1

私にとって有効な最も簡単な解決策は、データをjson_encodeとして保存することです。

後で取得するときは、必ずjson_decodeしてください。

ここでは、データベースとテーブルの照合または文字セットを変更する必要はありません。


0

マネージドMySQLインスタンス(私の場合はAWS RDS)でこれを解決しようとしている人にとって、最も簡単な方法は、パラメーターグループ変更しサーバーの文字セットと照合順序をそれぞれutf8mb4とに設定することutf8mb4_binでした。サーバーを再起動した後、簡単なクエリでシステムデータベースと新しく作成されたデータベースの設定を確認します。

SELECT * FROM information_schema.SCHEMATA S;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.