สามจุดที่ MySQL ต้องใช้รหัสอักขระ
- คอลัมน์หรือตาราง: ชุดอักขระที่ใช้เก็บข้อมูล เช่น
utf8mb4,latin1หรือtis620 - การเชื่อมต่อ: ชุดอักขระที่ไคลเอนต์และเซิร์ฟเวอร์ใช้คุยกัน – ตั้งด้วย
SET NAMES utf8mb4หรือในการตั้งค่าการเชื่อมต่อ - ไฟล์: รหัสอักขระที่ใช้อ่านไฟล์นำเข้าหรือเขียนไฟล์ส่งออก – ใน phpMyAdmin คือ ชุดอักขระของไฟล์ (Character set of the file)
ถ้าสามจุดนี้ไม่ตรงกัน อักขระจะเพี้ยน กรณีที่พบบ่อยที่สุดคือ ข้อความ UTF-8 ถูกเขียนผ่านการเชื่อมต่อ latin1 ลงคอลัมน์ latin1 แอปดูปกติดี แต่ phpMyAdmin และไฟล์ส่งออกกลับแสดงเป็นภาษาต่างดาว
ก่อน
"1","ÊÁªÒ 㨴Õ","¶¹¹ÊØ¢ØÁÇÔ·","¡Ãا෾ÁËÒ¹¤Ã"
หลัง
"1","สมชาย ใจดี","ถนนสุขุมวิท","กรุงเทพมหานคร"
ตรวจชุดอักขระ
SHOW VARIABLES LIKE 'character_set%';แสดงค่าของเซิร์ฟเวอร์และการเชื่อมต่อSHOW CREATE TABLE customers;แสดงชุดอักขระของตารางและคอลัมน์SELECT name, HEX(name) FROM customers LIMIT 5;แสดงไบต์จริง: ในคอลัมน์utf8mb4ตัวอักษรไทยขึ้นต้นด้วยE0B8หรือE0B9ส่วนC3A0C2B8คือข้อความที่ถูกเข้ารหัสซ้ำสองครั้งจนเสีย
ซ่อมไฟล์ส่งออกหรือไฟล์สำรอง
- ส่งออกตารางใน phpMyAdmin เป็น SQL หรือ CSV – หรือใช้
mysqldump --default-character-set=utf8mb4 - วางไฟล์ลงในช่องด้านบน Mojibuster ซ่อมเฉพาะจุดที่เสีย อักขระที่ถูกต้องอยู่เหมือนเดิม
- ตรวจจุดที่แก้ได้ใต้ มีอะไรเปลี่ยนบ้าง แล้วดาวน์โหลดไฟล์
- นำเข้าสู่ตารางที่เป็น
utf8mb4และเลือกutf-8เป็นชุดอักขระในหน้าต่างนำเข้า - ทดลองกับสำเนาก่อนจะแทนที่ตารางจริง
ไฟล์ส่งออกไม่เคยออกจากคอมพิวเตอร์ของคุณ ซึ่งสำคัญมากกับข้อมูลลูกค้า ถ้าอยากรู้ว่าอักขระแปลก ๆ เหล่านี้คืออะไร อ่านต่อที่ mojibake คืออะไร
แก้ที่ต้นเหตุ
- สร้างตารางใหม่ด้วย
DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci - ตั้งการเชื่อมต่อของแอปเป็น
utf8mb4เช่นใน PHP ใส่charset=utf8mb4ใน DSN ของ PDO - ถ้าไบต์ UTF-8 อยู่ในคอลัมน์
latin1อย่าแปลงตรง ๆ ด้วยCONVERT TO– จะเข้ารหัสซ้ำอีกรอบและข้อความเสียหนักขึ้น วิธีที่ปลอดภัยคือผ่านชนิดไบนารี: เริ่มด้วยMODIFY name VARBINARY(255)แล้วตามด้วยMODIFY name VARCHAR(255) CHARACTER SET utf8mb4 - ถ้า MySQL แทนอักขระด้วย
?แปลว่าคอลัมน์หรือการเชื่อมต่อแสดงอักขระนั้นไม่ได้ และข้อมูลที่เก็บไปแล้วหายถาวร – อ่านเพิ่มที่ mojibake คืออะไร
คำถามที่พบบ่อย
ทำไมในแอปของฉันทุกอย่างปกติ แต่ใน phpMyAdmin ผิด
เพราะแอปกับฐานข้อมูลทำผิดแบบเดียวกันสองครั้ง คือแอปเขียน UTF-8 ผ่านการเชื่อมต่อ latin1 แล้วอ่านกลับด้วยวิธีเดิม ส่วน phpMyAdmin เชื่อมต่อถูกต้อง จึงแสดงสิ่งที่ถูกเก็บไว้จริง ถ้าเว็บของคุณเป็น WordPress ดู WordPress และฐานข้อมูล และ ข้อความซ้อนสองชั้น ด้วย
ควรเลือก collation ไหนสำหรับภาษาไทย
utf8mb4_unicode_ci เหมาะกับแอปส่วนใหญ่ และตั้งแต่ MySQL 8 ค่าเริ่มต้นคือ utf8mb4_0900_ai_ci ที่สำคัญกว่าคือชุดอักขระ utf8mb4 ไม่ใช่ utf8 ซึ่งเก็บอีโมจิใน MySQL ไม่ได้
ใช้กับ MariaDB ได้ไหม
ได้ MariaDB จัดการชุดอักขระเหมือน MySQL และคำสั่งก็เหมือนกัน
ไฟล์สำรองใหญ่ได้สูงสุดเท่าไร
สูงสุด 100 MB ต่อไฟล์ ถ้าฐานข้อมูลใหญ่กว่านั้น ให้ส่งออกทีละตาราง