วิธีการจัดเก็บ Emoji Character ในฐานข้อมูล MySQL


172

ฉันกำลังใช้ตัวละคร Emoji ในโครงการของฉัน อักขระนั้นถูกบันทึกไว้ (??) ลงในฐานข้อมูล mysql ฉันใช้การเปรียบเทียบค่าเริ่มต้นในฐานข้อมูลutf8mb4_general_ciแล้ว มันแสดงให้เห็น

1366 ค่าสตริงที่ไม่ถูกต้อง: '\ xF0 \ x9F \ x98 \ x83 \ xF0 \ x9F ... ' สำหรับคอลัมน์ 'ความคิดเห็น' ที่แถว 1


1
คุณบันทึกข้อมูลของคุณอย่างไร คุณช่วยแสดงรหัสนั้นให้เราดูได้ไหม
Tomas Buteler

1
ขอบคุณสำหรับความคิดเห็นของคุณ ฉันมีวิธีแก้ปัญหาสำหรับการรวบรวมการเปลี่ยนแปลงฐานข้อมูลเริ่มต้นเป็น ** utf8mb4 ** และเปลี่ยนการเก็บตารางเป็น ** ชุดตัวอักษร UTF8mb4 COLLATE utf8mb4_bin ** ALTER TABLE Tablename CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin
Selvamani P

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

คำตอบ:


30

ขั้นตอนที่ 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 ผลงาน (วันที่, เวลา, คำบรรยายภาพ) ค่า (2018-05-20 ', '12: 38: 00', 'คำอธิบายการทดสอบด้วยอิโมจิ: 😊❤️'); การตั้งค่าคอลัมน์คือการเรียงหน้า: utf8mb4_0900_ai_ci คำจำกัดความ: ข้อความคำอธิบาย

1
การเชื่อมต่อของคุณจะต้องเป็น utf8mb4 ไม่ใช่ utf8 เพื่อให้สามารถใช้งานได้
Henrik Hansen

3
@ospider ในขั้นตอนที่ 2 คุณใช้ utfmb4_general_ci แทนที่จะเป็น unicode ไม่ว่าจะด้วยเหตุผลใด
Warren

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

23
มันไม่ทำงานสำหรับฉัน ฉันได้รับ "???" แทนรอยยิ้ม มีเพียง "☺" เท่านั้นที่ส่งไปยังฐานข้อมูลได้อย่างปลอดภัย
พัฒนาอยากรู้อยากเห็น

10
อาจจำเป็นต้องอัปเดตไม่เพียง แต่ตารางเป็น utf8mb4 แต่ยังคอลัมน์เหล่านั้นด้วยตัวเองมิฉะนั้นพวกเขายังสามารถปรากฏเป็น ?? แทน💙
Ael

2
ได้ผลสำหรับฉัน แต่อย่าลืมรีสตาร์ท MySQL
Ravi Misra

8
ฉันต้องวิ่งSET NAMES utf8mb4;เพื่อเริ่มบันทึกอีโมติคอน ก่อนที่คำสั่งนั้นจะช่วยพวกเขาเป็น??
cubbuk

18

ทั้งฐานข้อมูลและตารางควรมีชุดตัวอักษรและการเปรียบเทียบutf8mb4utf8mb4_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ไม่แนะนำวิธีปฏิบัติที่ดีที่สุดอีกต่อไป ดูคำถาม & คำตอบที่เกี่ยวข้อง:

ความแตกต่างระหว่าง utf8_general_ci และ utf8_unicode_ciบน Stack Overflow คืออะไร


ฉันมีฐานข้อมูลและตารางที่มี data.and เมื่อรันคำสั่งแก้ไขที่สองบอกว่า: ข้อผิดพลาด 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สำหรับคอลัมน์หรือไม่
Muhammad Omer Aslam

14

หากคุณใช้ Solr + Mysql + Java คุณสามารถใช้:

สิ่งนี้สามารถใช้:

  • case1: เมื่อคุณไม่ต้องการเปลี่ยน DB
  • case2: เมื่อคุณต้องนำเข้าอิโมติคอนจาก Mysql ของคุณไปยังแกน Solr

ในกรณีข้างต้นนี่เป็นวิธีแก้ไขปัญหาหนึ่งในการเก็บอิโมติคอนในระบบของคุณ

ขั้นตอนการใช้งาน:

ไลบรารีที่ใช้: import java.net.URLDecoder; นำเข้า java.net.URLEncoder;

  1. ใช้ urlEncoder เพื่อเข้ารหัสสตริงของคุณที่มีอิโมติคอน
  2. เก็บไว้ใน DB โดยไม่ต้องเปลี่ยน MysqlDB
  3. คุณสามารถเก็บมันไว้ในแกน solr (ถอดรหัส) ถ้าคุณต้องการหรือคุณสามารถเก็บฟอร์มที่เข้ารหัส
  4. เมื่อดึงอิโมติคอนเหล่านี้จากฐานข้อมูลหลักหรือ 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

1
ทำงานเหมือนมีเสน่ห์ฉันใช้มันในโมเดลดังนั้นฉันไม่จำเป็นต้องเปลี่ยนรหัสและฐานข้อมูลใด ๆ เพียงแค่ตัวแบบข้อมูลบน setter และ getter ของเนื้อหา
bowpunya

1
ฟังก์ชันการเข้ารหัส / ถอดรหัสมีแนวโน้มที่จะทำให้เกิดปัญหา แก้ไขการตั้งค่าชุดอักขระในที่ต่างๆแทน
Rick James

1
นี่ไม่ใช่การแก้ปัญหานี่คือการข้ามมัน และคุณจะพบปัญหามากมายเกี่ยวกับวิธีนี้ตัวอย่างเช่นคุณจะทำให้แอปพลิเคชันของคุณช้าลงเพราะคุณต้องถอดรหัสและเข้ารหัสทุกอย่าง นอกจากนี้หากคุณป้อนตัวอักษรการ%ถอดรหัสของคุณจะแตก
Jonathan Laliberte

14

ฉันมีการปรับปรุงฐานข้อมูลและตารางของฉันที่จะปรับรุ่นจากutf8เพื่อutf8mb4 แต่ไม่มีอะไรเหมาะกับฉัน จากนั้นฉันพยายามอัปเดตประเภทข้อมูลคอลัมน์เป็นหยดโชคดีที่มันใช้งานได้สำหรับฉันและข้อมูลได้รับการบันทึกแล้ว แม้แต่ฐานข้อมูลและตารางของฉันทั้งคู่ก็เป็นCHARACTER SET 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เป็นblobและคุณก็ทำเสร็จแล้ว ความบ้าคลั่งที่จะแปลงชุดอักขระและการเรียงหน้าในฐานข้อมูลทั้งหมดเพื่อที่จะ :)
464

9

คำตอบของฉันเพิ่มลงในคำตอบของ Selvamani P เท่านั้น

นอกจากนี้คุณยังอาจต้องเปลี่ยนแปลงใด ๆคำสั่งด้วยSET NAMES utf8 SET NAMES utf8mb4นั่นเป็นเคล็ดลับสำหรับฉัน

นอกจากนี้ยังเป็นบทความที่ยอดเยี่ยมในการย้ายเว็บไซต์ของคุณจาก utf8 ไปยัง utf8mb4 โดยเฉพาะอย่างยิ่งบทความทำให้ 2 คะแนนที่ดีในดัชนีและการซ่อมแซมตารางหลังจากแปลงเป็น utf8mb4:

ดัชนี

เมื่อแปลงจาก utf8 เป็น utf8mb4 ความยาวสูงสุดของคอลัมน์หรือคีย์ดัชนีจะไม่เปลี่ยนแปลงในรูปแบบไบต์ ดังนั้นจึงมีขนาดเล็กลงในรูปของอักขระเนื่องจากความยาวสูงสุดของอักขระคือสี่ไบต์แทนที่จะเป็นสาม [... ] เครื่องมือจัดเก็บข้อมูล InnoDB มีความยาวดัชนีสูงสุด 767 ไบต์ดังนั้นสำหรับคอลัมน์ utf8 หรือ utf8mb4 คุณสามารถสร้างดัชนีได้สูงสุด 255 หรือ 191 ตัวอักษรตามลำดับ หากคุณมีคอลัมน์ utf8 ที่มีดัชนียาวกว่า 191 ตัวอักษรคุณจะต้องสร้างดัชนีจำนวนอักขระที่น้อยลงเมื่อใช้ utf8mb4

ตารางการซ่อม

หลังจากอัปเกรดเซิร์ฟเวอร์ MySQL และทำการเปลี่ยนแปลงที่จำเป็นตามที่อธิบายไว้ข้างต้นตรวจสอบให้แน่ใจว่าได้ซ่อมแซมและเพิ่มประสิทธิภาพฐานข้อมูลและตารางทั้งหมดแล้ว ฉันไม่ได้ทำสิ่งนี้ทันทีหลังจากอัปเกรด (ฉันไม่คิดว่ามันจำเป็นเพราะทุกอย่างดูเหมือนจะทำงานได้อย่างรวดเร็วในตอนแรก) และพบข้อผิดพลาดแปลก ๆ ที่คำสั่ง UPDATE ไม่มีผลใด ๆ แม้ว่าจะไม่มี เกิดข้อผิดพลาด

อ่านเพิ่มเติมเกี่ยวกับแบบสอบถามเพื่อซ่อมแซมตารางในบทความ


REPAIR TABLEและOPTIMIZE TABLEควรไม่จำเป็น - ALTERมีผลต่อการทำ
Rick James

5

ประเด็นหลักยังไม่ได้รับการกล่าวถึงในคำตอบข้างต้นว่า

เราจำเป็นต้องส่งสตริงการสืบค้นด้วยตัวเลือก"useUnicode=yes"และ"characterEncoding=UTF-8"ในสตริงการเชื่อมต่อ

บางสิ่งเช่นนี้

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

5

คุณไม่จำเป็นต้องเปลี่ยนทั้ง DB Charset แทนที่จะทำเช่นนั้นคุณสามารถทำได้โดยเปลี่ยนคอลัมน์เป็นชนิดหยด

แก้ไขตารางข้อความแก้ไขเนื้อหา BLOB;


3

ฉันมีทางออกที่ดีในการประหยัดเวลาของคุณ ฉันเจอปัญหาเดียวกัน แต่ฉันไม่สามารถแก้ปัญหานี้ได้ด้วยคำตอบแรก

อักขระค่าเริ่มต้นของคุณคือ utf-8 แต่อีโมจิต้องการ utf8mb4 เพื่อสนับสนุน หากคุณได้รับอนุญาตให้แก้ไขไฟล์กำหนดค่าของ mysql คุณสามารถทำตามขั้นตอนนี้

ดังนั้นทำตามขั้นตอนต่อไปนี้เพื่ออัพเกรดชุดอักขระของคุณ (จาก utf-8 เป็น utf8mb4)

ขั้นตอนที่ 1. เปิด my.cnf สำหรับ mysql เพิ่มบรรทัดต่อไปนี้ใน 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

การสนับสนุน Emoji สำหรับแอปพลิเคชันที่มีเทคโนโลยีกองซ้อน - mysql, java, springboot, hibernate

ใช้การเปลี่ยนแปลงด้านล่างใน mysql เพื่อรองรับ Unicode

  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;

การเชื่อมต่อฐานข้อมูล - การเปลี่ยนแปลง URL ของ jdbc:

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

หมายเหตุ - หากขั้นตอนข้างต้นใช้งานไม่ได้โปรดอัปเดตเวอร์ชันตัวเชื่อมต่อ mysql เป็น 8.0.15 (mysql 5.7 ทำงานร่วมกับตัวเชื่อมต่อเวอร์ชัน 8.0.15 สำหรับการรองรับ Unicode)


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.