Skip to content

How to Fix MySQL Character Set to UTF-8

DodaTech 2 min read

In this tutorial, you'll learn about How to Fix MySQL Character Set to UTF. We cover key concepts, practical examples, and best practices.

The Problem

You store text with emoji, accented characters, or non-Latin scripts (Chinese, Arabic, Hindi) in MySQL, and they display as ???? or garbled characters. MySQL's default latin1 charset doesn't support multi-byte characters. The correct charset is utf8mb4, which supports the full Unicode standard including emoji. Older MySQL versions default to utf8 which is a 3-byte implementation that also can't store emoji.

Quick Fix

1. Check current charset and collation

SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';

Expected output (problem):

Variable_name           Value
character_set_server    latin1
character_set_database  latin1

2. Change database charset

ALTER DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

This sets the default charset for new tables but doesn't change existing tables.

3. Change table charset

ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

The CONVERT TO keyword changes the table charset AND converts existing data. Without CONVERT TO, only the default for new columns is changed.

4. Set server-wide default (my.cnf)

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

Restart MySQL after editing:

sudo systemctl restart mysql

5. Verify the change

SHOW VARIABLES LIKE 'character_set%';

Expected output (fixed):

Variable_name           Value
character_set_server    utf8mb4
character_set_database  utf8mb4
character_set_client    utf8mb4
character_set_connection utf8mb4

6. Check connection charset from application

import mysql.connector

conn = mysql.connector.connect(
    host="localhost",
    database="mydb",
    charset="utf8mb4"
)
cursor = conn.cursor()
cursor.execute("INSERT INTO users (name) VALUES (%s)", ("Alice 😊",))
conn.commit()

Set charset="utf8mb4" explicitly in your application connection string.

7. Fix existing garbled data (double encoding)

If data was stored as latin1 but the bytes are UTF-8:

ALTER TABLE users MODIFY name VARBINARY(255);
ALTER TABLE users MODIFY name VARCHAR(255) CHARACTER SET utf8mb4;

This converts the raw bytes without re-encoding. Only use this when data was written with the wrong charset.

8. Set charset per connection with SET NAMES

SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;

Run this after connecting to a database to ensure the session uses UTF-8. Some connection pools may require this to be set explicitly after each connection establishment.

9. Check column-level charset

SELECT table_name, column_name, character_set_name, collation_name
FROM information_schema.columns
WHERE table_schema = 'mydb' AND character_set_name IS NOT NULL;

This shows which columns still use the old charset. Even if the table and database are set to utf8mb4, individual columns may have been created before the change and still use latin1.

Prevention

  • Set character-set-server = utf8mb4 in my.cnf before creating databases
  • Use utf8mb4_unicode_ci (or utf8mb4_unicode_520_ci) for collation
  • Always specify charset in application database connection strings
  • Test with emoji (😊) and accented characters (Γ©, ΓΌ) during development
  • Avoid utf8 in MySQL β€” it's an alias for 3-byte UTF-8 that doesn't support emoji
  • Set charset on the connection, not just the server: SET NAMES utf8mb4 in each session
  • Check column-level charset with information_schema.columns

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro