Cách lưu trữ Ký tự Emoji trong Cơ sở dữ liệu MySQL


172

Tôi đang sử dụng nhân vật Emoji trong dự án của mình. Các ký tự đó được lưu (??) vào cơ sở dữ liệu mysql. Tôi đã sử dụng cơ sở dữ liệu Đối chiếu mặc định trong utf8mb4_general_ci. Nó cho thấy

1366 Giá trị chuỗi không chính xác: '\ xF0 \ x9F \ x98 \ x83 \ xF0 \ x9F ...' cho cột 'nhận xét' ở hàng 1


1
Làm thế nào là bạn lưu dữ liệu của bạn? Bạn có thể chỉ cho chúng tôi mã đó?
Tomas Buteler

1
Cám ơn bạn đã góp ý. Tôi đã tìm giải pháp cho bộ sưu tập mặc định Cơ sở dữ liệu thay đổi này là ** utf8mb4 ** và cũng thay đổi bộ sưu tập Bảng dưới dạng ** CHARACTER SET utf8mb4 COLLATE utf8mb4_bin **. ALTER TABLE Tablename CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin
Selvamani P

1
Mã: 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'Đặt utf8mb4 trong kết nối cơ sở dữ liệu: $database_connection = new mysqli($server, $user,$password,$database_name); $database_connection->set_charset("utf8mb4");
Selvamani P

Câu trả lời:


29

Bước 1, thay đổi bộ ký tự mặc định của cơ sở dữ liệu của bạn:

ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

Bước 2, đặt bộ ký tự khi tạo bảng:

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

hoặc thay đổi bảng

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

Tôi đã làm theo các truy vấn này và dừng và khởi động lại máy chủ mysql, nhưng khi tôi cố gắng chèn biểu tượng cảm xúc vào bảng của mình, tôi vẫn gặp lỗi tương tự. Tất cả các lệnh được thông qua thành công ngoại trừ INSERT. XÁC NHẬN VÀO mục nhập (ngày, giờ, chú thích) GIÁ TRỊ (2018-05-20 ', '12: 38: 00', 'Mô tả thử nghiệm với biểu tượng cảm xúc:'); Các cài đặt cột là Collation: utf8mb4_0900_ai_ci Định nghĩa: văn bản mô tả

1
Kết nối của bạn cũng cần phải là utf8mb4 chứ không phải utf8 để nó hoạt động.
Henrik Hansen

3
@ospider, ở bước 2 bạn sử dụng utfmb4_general_ci thay vì unicode - lý do nào?
Warren

263

1) Cơ sở dữ liệu: Thay đổi đối chiếu cơ sở dữ liệu mặc định là utf8mb4.

2) Bảng: Thay đổi đối chiếu bảng như CHARACTER SET utf8mb4 COLLATE utf8mb4_bin.

Truy vấn:

ALTER TABLE Tablename CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin

3) Mã:

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) Đặt utf8mb4trong kết nối cơ sở dữ liệu:

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

4
Có thể mà không thay đổi bộ sưu tập mặc định cơ sở dữ liệu?
AliN11

23
Điều này không làm việc cho tôi. Tôi đang nhận được "???" thay vì mặt cười chỉ "☺" này mượt mà đưa nó vào cơ sở dữ liệu một cách an toàn.
Nhà phát triển tò mò

10
Có thể cần cập nhật không chỉ bảng thành utf8mb4, mà C ALNG chính các cột, nếu không chúng vẫn có thể xuất hiện dưới dạng ?? thay vì.
Ael

2
Làm việc cho tôi, nhưng đừng quên khởi động lại MySQL.
Ravi Misra

8
Tôi cần phải chạy SET NAMES utf8mb4;để bắt đầu lưu biểu tượng cảm xúc; trước lệnh đó, nó đã cứu họ như??
cubbuk

18

Cả cơ sở dữ liệu và bảng nên có bộ ký tự utf8mb4và đối chiếu utf8mb4_unicode_ci.

Khi tạo cơ sở dữ liệu mới, bạn nên sử dụng:

CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Nếu bạn có một cơ sở dữ liệu hiện có và bạn muốn thêm hỗ trợ:

ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

Bạn cũng cần đặt bộ ký tự và đối chiếu chính xác cho các bảng của mình:

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

hoặc thay đổi nó nếu bạn có các bảng hiện có nhiều dữ liệu:

ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Lưu ý rằng utf8_general_cikhông còn được khuyến nghị thực hành tốt nhất. Xem phần hỏi đáp liên quan:

Sự khác biệt giữa utf8_general_ci và utf8_unicode_ci trên Stack Overflow.


tôi có một cơ sở dữ liệu và bảng chứa data.and khi thực hiện câu lệnh ALTER thứ hai, nói rằng: ERROR 1833 (HY000): Không thể thay đổi cột 'id': được sử dụng trong một ràng buộc khoá ngoại 'FK12njtf8e0jmyb45lqfpt6ad89' của bảng 'lizbazi.post'
Seyyed Mahdiyar Zerehpoush

@SeyyedMahdiyarZerehpoush - bạn có thể thoát khỏi việc giới hạn cập nhật của mình cho các cột cụ thể yêu cầu nó, như được mô tả ở đây: stackoverflow.com/a/15781925/1247581, vdALTER TABLE mytable MODIFY my_emoji_friendly_text_column VARCHAR(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
theartofrain

Bất kỳ khác biệt khi sử dụng utf8mb4_binvs utf8mb4_unicode_cicho các cột?
Muhammad Omer Aslam

14

Nếu bạn đang sử dụng Solr + Mysql + Java, bạn có thể sử dụng:

Điều này có thể được sử dụng:

  • case1: Khi bạn không muốn thay đổi DB.
  • case2: khi bạn phải nhập biểu tượng cảm xúc từ lõi Mysql của mình vào lõi Solr.

Trong trường hợp trên, đây là một trong những giải pháp lưu trữ biểu tượng cảm xúc trong hệ thống của bạn.

Các bước để sử dụng nó:

Thư viện được sử dụng: nhập java.net.URLDecoder; nhập java.net.URLEncoder;

  1. Sử dụng urlEncoder để mã hóa Chuỗi của bạn có biểu tượng cảm xúc.
  2. Lưu trữ nó trong DB mà không thay đổi MysqlDB.
  3. Bạn có thể lưu trữ nó trong lõi solr (dạng được giải mã) nếu bạn muốn hoặc bạn có thể lưu trữ dạng được mã hóa.
  4. Khi tìm nạp các biểu tượng cảm xúc này từ lõi DB hoặc Solr, giờ đây bạn có thể giải mã nó bằng urlDecoder.

Mã ví dụ:

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;
}

Cảm ơn bạn vì đoạn mã này, có thể cung cấp một số trợ giúp hạn chế, ngay lập tức. Một lời giải thích phù hợp sẽ cải thiện đáng kể giá trị lâu dài của nó bằng cách chỉ ra lý do tại sao đây là một giải pháp tốt cho vấn đề và sẽ giúp nó hữu ích hơn cho những người đọc tương lai với những câu hỏi tương tự khác. Vui lòng chỉnh sửa câu trả lời của bạn để thêm một số giải thích, bao gồm các giả định bạn đã thực hiện.
Toby Speight

1
hoạt động như một bùa mê, tôi đã sử dụng nó trong mô hình, vì vậy tôi thực sự không cần thay đổi bất kỳ mã và cơ sở dữ liệu nào chỉ là mô hình dữ liệu trên setter và getter của nội dung
Bowastya

1
Mã hóa / giải mã các cuộc gọi chức năng có xu hướng gây rắc rối. Thay vào đó, sửa các cài đặt bộ ký tự ở những nơi khác nhau.
Rick James

1
Điều này không giải quyết được vấn đề, đây là bỏ qua nó. Và bạn sẽ gặp phải một loạt vấn đề với phương pháp này, ví dụ bạn sẽ làm chậm ứng dụng của mình vì bạn phải giải mã và mã hóa mọi thứ. Ngoài ra nếu bạn nhập ký tự %, giải mã của bạn sẽ bị hỏng.
Jonathan Laliberte

14

Tôi đã cập nhật cơ sở dữ liệu và bảng để nâng cấp từ utf8 lên utf8mb4 . Nhưng không có gì làm việc cho tôi. Sau đó, tôi đã cố cập nhật kiểu dữ liệu cột lên blob , may mắn là nó hoạt động với tôi và dữ liệu đã được lưu. Ngay cả cơ sở dữ liệu và bảng của tôi đều là CHARACTER SET utf8 COLLATE utf8_unicode


13

Lệnh sửa đổi cột là:

ALTER TABLE TABLE_NAME MODIFY COLUMN_NAME TYPE;

Và chúng ta cần sử dụng loại = BLOB

Ví dụ để sửa đổi như dưới đây: -

ALTER TABLE messages MODIFY content BLOB;

Tôi đã kiểm tra rằng myQuery mới nhất và các cơ sở dữ liệu khác không cần ''sử dụng lệnh trên tên_bảng, tên_bảng, v.v.

Tìm nạp và lưu dữ liệu: Lưu trực tiếp nội dung trò chuyện vào cột và để truy xuất dữ liệu, tìm nạp dữ liệu dưới dạng mảng byte (byte[])từ cột db và sau đó chuyển đổi thành stringví dụ (mã Java)

new String((byte[]) arr) 

2
Đúng. Nếu bạn chỉ cần lưu trữ unicode như biểu tượng cảm xúc trong một trường nhất định, câu trả lời được chấp nhận là quá khó, Chỉ cần thay đổi trường text/ varcharthành a blobvà bạn đã hoàn thành. Sự điên rồ khi chuyển đổi bộ ký tự và đối chiếu trên toàn bộ DB chỉ vì điều đó :)
davidkonrad

9

Câu trả lời của tôi chỉ thêm vào câu trả lời của Selvamani P.

Bạn cũng có thể cần phải thay đổi bất kỳ SET NAMES utf8truy vấn nào SET NAMES utf8mb4. Điều đó đã đánh lừa tôi.

Ngoài ra, đây là một bài viết tuyệt vời để chuyển trang web của bạn từ utf8 sang utf8mb4. Cụ thể, bài viết làm cho 2 điểm tốt về chỉ mục và sửa chữa bảng sau khi chuyển đổi chúng thành utf8mb4:

CHỈ SỐ

Khi chuyển đổi từ utf8 sang utf8mb4, độ dài tối đa của cột hoặc khóa chỉ mục không thay đổi về mặt byte. Do đó, nó nhỏ hơn về các ký tự, bởi vì độ dài tối đa của một ký tự bây giờ là bốn byte thay vì ba. [...] Công cụ lưu trữ InnoDB có độ dài chỉ mục tối đa là 767 byte, do đó, đối với các cột utf8 hoặc utf8mb4, bạn có thể lập chỉ mục tối đa tương ứng 255 hoặc 191 ký tự. Nếu bạn hiện có các cột utf8 với các chỉ mục dài hơn 191 ký tự, bạn sẽ cần lập chỉ mục một số lượng ký tự nhỏ hơn khi sử dụng utf8mb4.

SỬA CHỮA BẢNG

Sau khi nâng cấp máy chủ MySQL và thực hiện các thay đổi cần thiết được giải thích ở trên, hãy đảm bảo sửa chữa và tối ưu hóa tất cả các cơ sở dữ liệu và bảng. Tôi đã không làm điều này ngay sau khi nâng cấp (tôi không nghĩ là cần thiết, vì thoạt nhìn mọi thứ đều hoạt động tốt) và gặp phải một số lỗi kỳ lạ trong đó các câu lệnh CẬP NHẬT không có tác dụng gì, mặc dù không lỗi đã được ném.

Đọc thêm về các truy vấn để sửa chữa các bảng trên bài viết.


REPAIR TABLEOPTIMIZE TABLEkhông cần thiết - ALTERcó tác dụng làm chúng.
Rick James

5

Điểm chính chưa được đề cập trong các câu trả lời ở trên rằng,

Chúng ta cần truyền chuỗi truy vấn với các tùy chọn "useUnicode=yes""characterEncoding=UTF-8"trong chuỗi kết nối

Một cái gì đó như thế này

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

5

Chà, bạn không cần phải thay đổi Toàn bộ Bộ ký tự DB. Thay vì điều đó bạn có thể làm điều đó bằng cách thay đổi cột thành loại blob .

ALTER TABLE tin nhắn MODIFY nội dung BLOB;


3

Tôi có một giải pháp tốt để tiết kiệm thời gian của bạn. Tôi cũng gặp vấn đề tương tự nhưng tôi không thể giải quyết vấn đề này bằng câu trả lời đầu tiên.

Nhân vật defualt của bạn là utf-8. Nhưng biểu tượng cảm xúc cần utf8mb4 để hỗ trợ nó. Nếu bạn có quyền sửa lại tệp cấu hình của mysql, bạn có thể làm theo bước này.

Do đó, hãy thực hiện bước sau để nâng cấp bộ ký tự của bạn (từ utf-8 lên utf8mb4).

Bước 1. mở my.cnf của bạn cho mysql, thêm các dòng sau vào my.cnf của bạn.

[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

bước 2. dừng dịch vụ mysql của bạn và bắt đầu dịch vụ mysql

mysql.server stop
mysql.server start

Đã kết thúc! Sau đó, bạn có thể kiểm tra nhân vật của mình được thay đổi thành 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

Hỗ trợ biểu tượng cảm xúc cho ứng dụng có ngăn xếp công nghệ - mysql, java, springboot, ngủ đông

Áp dụng các thay đổi dưới đây trong mysql để được hỗ trợ 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;

Kết nối DB - thay đổi url jdbc:

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

Lưu ý - Nếu bước trên không hoạt động, vui lòng cập nhật phiên bản kết nối mysql lên 8.0.15. (mysql 5.7 hoạt động với phiên bản kết nối 8.0.15 để hỗ trợ unicode)


1

Giải pháp đơn giản nhất cho tôi là lưu trữ dữ liệu dưới dạng json_encode .

sau này khi bạn truy xuất chỉ cần đảm bảo rằng bạn json_decode nó.

Ở đây bạn không phải thay đổi đối chiếu hoặc bộ ký tự của cơ sở dữ liệu và bảng.


0

Đối với bất cứ ai cố gắng để giải quyết việc này trên một trường hợp MySQL quản lý (trong trường hợp của tôi trên AWS RDS), cách dễ nhất là để sửa đổi các nhóm thông số và thiết lập các bộ ký tự máy chủ và đối chiếu được utf8mb4utf8mb4_bin, tương ứng. Sau khi khởi động lại máy chủ, một truy vấn nhanh sẽ xác minh cài đặt cho cơ sở dữ liệu hệ thống và mọi cài đặt mới được tạo:

SELECT * FROM information_schema.SCHEMATA S;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.