Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Sự cố với các ký tự UTF-8; những gì tôi thấy không phải là những gì tôi đã lưu trữ

Vấn đề này gây khó khăn cho những người tham gia trang web này và nhiều người khác.

Bạn đã liệt kê năm trường hợp chính của CHARACTER SET rắc rối.

Phương pháp hay nhất

Về sau, tốt nhất là sử dụng CHARACTER SET utf8mb4COLLATION utf8mb4_unicode_520_ci . (Có một phiên bản đối chiếu Unicode mới hơn trong đường dẫn.)

utf8mb4 là một tập hợp con của utf8 trong đó nó xử lý mã utf8 4 byte, mã này cần cho Biểu tượng cảm xúc và một số mã tiếng Trung.

Bên ngoài MySQL, "UTF-8" đề cập đến tất cả các mã hóa kích thước, do đó có hiệu quả giống như utf8mb4 của MySQL , không phải utf8 .

Tôi sẽ cố gắng sử dụng những cách viết và viết hoa đó để phân biệt bên trong và bên ngoài MySQL trong phần sau.

Tổng quan về những gì bạn nên làm

  • Đặt trình chỉnh sửa của bạn, v.v. thành UTF-8.
  • Các biểu mẫu HTML phải bắt đầu như <form accept-charset="UTF-8"> .
  • Có các byte của bạn được mã hóa thành UTF-8.
  • Thiết lập UTF-8 làm mã hóa đang được sử dụng trong ứng dụng khách.
  • Đã khai báo cột / bảng CHARACTER SET utf8mb4 (Kiểm tra với SHOW CREATE TABLE .)
  • <meta charset=UTF-8> ở đầu HTML
  • Quy trình được Lưu trữ có được bộ ký tự / đối chiếu hiện tại. Họ có thể cần xây dựng lại.

UTF- 8 trong suốt

Thêm chi tiết về ngôn ngữ máy tính (và các phần sau của nó)

Kiểm tra dữ liệu

Xem dữ liệu bằng công cụ hoặc bằng SELECT Không thể tin cậy được. Quá nhiều ứng dụng khách như vậy, đặc biệt là các trình duyệt, cố gắng bù đắp các mã hóa không chính xác và hiển thị cho bạn văn bản chính xác ngay cả khi cơ sở dữ liệu bị sai lệch. Vì vậy, hãy chọn một bảng và cột có một số văn bản không phải tiếng Anh và thực hiện

SELECT col, HEX(col) FROM tbl WHERE ...

HEX cho UTF-8 được lưu trữ chính xác sẽ là

  • Đối với một khoảng trống (bằng bất kỳ ngôn ngữ nào):20
  • Đối với tiếng Anh:4x , 5x , 6x hoặc 7x
  • Đối với hầu hết các nước Tây Âu, các chữ cái có dấu phải là Cxyy
  • Chữ Kirin, tiếng Do Thái và tiếng Farsi / tiếng Ả Rập:Dxyy
  • Phần lớn Châu Á:Exyyzz
  • Biểu tượng cảm xúc và một số tiếng Trung:F0yyzzww
  • Thêm chi tiết

Nguyên nhân cụ thể và cách khắc phục sự cố đã thấy

Bị cắt ngắn text (Se cho Señor ):

  • Các byte được lưu trữ không được mã hóa dưới dạng utf8mb4. Khắc phục sự cố này.
  • Ngoài ra, hãy kiểm tra xem kết nối trong quá trình đọc có phải là UTF-8 không.

Kim cương đen có dấu chấm hỏi (Se�or cho Señor ); một trong những trường hợp này tồn tại:

Trường hợp 1 (byte ban đầu là không UTF-8):

  • Các byte được lưu trữ không được mã hóa dưới dạng utf8. Khắc phục sự cố này.
  • Kết nối (hoặc SET NAMES ) cho INSERT SELECT không phải là utf8 / utf8mb4. Khắc phục sự cố này.
  • Ngoài ra, hãy kiểm tra xem cột trong cơ sở dữ liệu có phải là CHARACTER SET utf8 không (hoặc utf8mb4).

Trường hợp 2 (byte ban đầu was UTF-8):

  • Kết nối (hoặc SET NAMES ) cho SELECT không phải là utf8 / utf8mb4. Khắc phục sự cố này.
  • Ngoài ra, hãy kiểm tra xem cột trong cơ sở dữ liệu có phải là CHARACTER SET utf8 không (hoặc utf8mb4).

Kim cương đen chỉ xuất hiện khi trình duyệt được đặt thành <meta charset=UTF-8> .

Dấu hỏi (những viên thông thường, không phải kim cương đen) (Se?or cho Señor ):

  • Các byte được lưu trữ không được mã hóa dưới dạng utf8 / utf8mb4. Khắc phục sự cố này.
  • Cột trong cơ sở dữ liệu không phải là CHARACTER SET utf8 (hoặc utf8mb4). Sửa lỗi này. (Sử dụng SHOW CREATE TABLE .)
  • Ngoài ra, hãy kiểm tra xem kết nối trong quá trình đọc có phải là UTF-8 không.

Mojibake (Señor cho Señor ) :( Cuộc thảo luận này cũng áp dụng cho Mã hóa kép , không nhất thiết phải hiển thị.)

  • Các byte được lưu trữ cần được mã hóa UTF-8. Khắc phục sự cố này.
  • Kết nối khi INSERTingSELECTing văn bản cần chỉ định utf8 hoặc utf8mb4. Khắc phục sự cố này.
  • Cột cần được khai báo CHARACTER SET utf8 (hoặc utf8mb4). Khắc phục sự cố này.
  • HTML phải bắt đầu bằng <meta charset=UTF-8> .

Nếu dữ liệu trông đúng, nhưng không sắp xếp chính xác, thì có thể là bạn đã chọn sai đối chiếu hoặc không có đối chiếu nào phù hợp với nhu cầu của bạn hoặc bạn có Mã hóa kép .

Mã hóa kép có thể được xác nhận bằng cách thực hiện SELECT .. HEX .. được mô tả ở trên.

é should come back C3A9, but instead shows C383C2A9
The Emoji 👽 should come back F09F91BD, but comes back C3B0C5B8E28098C2BD

Có nghĩa là, hex dài hơn khoảng gấp đôi so với thời gian cần thiết. Điều này xảy ra do chuyển đổi từ latin1 (hoặc bất cứ thứ gì) thành utf8, sau đó xử lý các byte đó như thể chúng là latin1 và lặp lại chuyển đổi. hoạt động chính xác bởi vì nó, ví dụ, sắp xếp như thể chuỗi là Señor .

Sửa dữ liệu, nếu có thể

Đối với Cắt ngắn Dấu hỏi , dữ liệu bị mất.

Đối với Mojibake / Mã hóa kép , ...

Đối với Kim cương đen , ...

Các bản sửa lỗi được liệt kê ở đây. (5 bản sửa lỗi khác nhau cho 5 trường hợp khác nhau; hãy chọn cẩn thận): http:// mysql. rjweb.org/doc.php/charcoll#fixes_for_various_case



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Chọn một máy chủ tìm kiếm toàn văn bản độc lập:Sphinx hay SOLR?

  2. MySQL:Sắp xếp các giá trị GROUP_CONCAT

  3. Cách tính thứ hạng trong MySQL

  4. Cách tạo cài đặt MySQL để thử nghiệm cục bộ

  5. Danh sách đầy đủ các ngôn ngữ trong MySQL