2026年11月13日
2026年11月13日
How to Change MySQL Character Set and Collation (utf8mb4)
This article is a localized edition of the Japanese original. Read the Japanese original
In MySQL, the character set (charset) decides which byte sequences are used to store characters, and the collation decides how characters are compared and sorted. Problems such as emoji that cannot be saved, characters replaced by ?, or searches that do or do not distinguish upper and lower case all come down to these two settings. Everything in this article was checked against the MySQL 8.4 reference manual as of November 2026, and the SQL was run on MySQL 8.4.
The settings exist at four levels
Character set and collation are set separately at the following four levels. When a lower level does not specify them, the value of the level above it is used.
| Level | When it is decided | How to change it |
|---|---|---|
| Server | When MySQL starts | character-set-server and collation-server in the configuration file |
| Database | At CREATE DATABASE |
ALTER DATABASE (changes only the default for tables created later) |
| Table | At CREATE TABLE |
ALTER TABLE ... CONVERT TO (also converts existing columns) |
| Column | When the column is created | ALTER TABLE ... MODIFY (that column only) |
The setting actually used to store data is the column setting. Changing the database or server setting does not change existing columns.
In addition, there are character sets used for communication with the client (character_set_client, character_set_connection and character_set_results). If these do not match the columns, text becomes garbled when it is saved or displayed.
Step 1: Check the current settings
-- Server and connection settings
SHOW VARIABLES LIKE 'character_set_%';
SHOW VARIABLES LIKE 'collation_%';
-- Database defaults
SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME = 'mydb';
-- Default collation of each table
SELECT TABLE_NAME, TABLE_COLLATION
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'mydb';
-- Per-column settings (the values actually used for storage)
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;
Replace mydb with your database name. To see the whole definition of one table at once, SHOW CREATE TABLE table_name; is handy.
Which character set and collation to use
Choose utf8mb4 as the character set. It can also store 4-byte characters such as emoji and some kanji. MySQL's utf8 is an alias for utf8mb3 (up to 3 bytes), which cannot store 4-byte characters, and utf8mb3 itself is deprecated. Since MySQL 8.0, the server's default character set is utf8mb4 and the default collation is utf8mb4_0900_ai_ci.
The main collations differ as follows.
| Collation | Characteristics |
|---|---|
utf8mb4_0900_ai_ci |
Default since MySQL 8.0. Does not distinguish accents (including Japanese voiced and semi-voiced marks) or case |
utf8mb4_ja_0900_as_cs |
For Japanese. Distinguishes accents and case. Sorts hiragana and katakana as equal |
utf8mb4_ja_0900_as_cs_ks |
Same as above, and also distinguishes hiragana from katakana |
utf8mb4_bin |
Compares the raw byte sequences |
utf8mb4_unicode_ci and utf8mb4_unicode_520_ci |
Collations based on an older standard. Also available in MariaDB |
With an _ai_ci collation, for example, the Japanese strings "ハハ" and "パパ" compare as equal. For columns where searches or unique constraints (UNIQUE) must tell them apart, specify a collation such as utf8mb4_ja_0900_as_cs. Changing the collation can also make rows violate a unique constraint and cause ALTER TABLE to fail, so check for duplicates first.
Collations with 0900 in the name treat trailing spaces as ordinary characters ('a' and 'a ' are different strings). If you switch from an older collation, search results can change because of the different handling of spaces. If the same database is shared with MariaDB or MySQL 5.7, choose a collation the other side supports.
Step 2: Back up before you start
Converting the character set rebuilds the table, which is heavy work, and undoing it requires a backup.
mysqldump -u root -p --single-transaction mydb > ~/mydb-before-charset.sql
With -p alone, you are prompted for the password. Do not put the password directly on the command line.
Step 3: Change the database default
ALTER DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
This changes only the default for tables created from now on. Existing tables and columns stay as they are.
When you create a new database, specify the settings from the start.
CREATE DATABASE newdb CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
Step 4: Convert existing tables and columns
To convert the table default and all string columns in the table at once, use CONVERT TO.
ALTER TABLE posts CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
Without CONVERT TO, as in ALTER TABLE posts CHARACTER SET utf8mb4;, only the table default changes and existing columns are not converted.
To change a single column, use MODIFY. You must restate the column's original NOT NULL and DEFAULT, or they are dropped.
ALTER TABLE posts
MODIFY title VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_ja_0900_as_cs NOT NULL;
To convert all tables in a database, generate the conversion SQL, review it, and then run it.
SELECT CONCAT('ALTER TABLE `', TABLE_NAME,
'` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;')
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'mydb' AND TABLE_TYPE = 'BASE TABLE';
Things to watch when converting
- An ALTER TABLE that changes the character set or collation copies and rebuilds the whole table (
ALGORITHM=COPY). On large tables this takes time, and writes to the table are blocked meanwhile. Do it when traffic is low. - Going from utf8mb3 or latin1 to utf8mb4 increases the maximum number of bytes per character. A
TEXTcolumn may be changed toMEDIUMTEXTso that the data still fits. - InnoDB index keys have a length limit (3072 bytes with row formats such as
DYNAMIC, 767 bytes with the olderCOMPACTandREDUNDANT). utf8mb4 is counted as 4 bytes per character, so in a 767-byte environment you cannot index aVARCHAR(255)column. CheckRow_formatinSHOW TABLE STATUSand, if needed, limit the index to the first 191 characters or similar. - Characters that do not exist in the source character set can cause data loss. Compare the row counts and the contents of key columns before and after the conversion.
When the data is already garbled
CONVERT TO converts data that is correctly stored in the column's character set into another character set. If, for example, a column is latin1 but actually contains UTF-8 byte sequences (saved through a misconfigured connection), running CONVERT TO encodes it twice and makes it impossible to fix.
In that case, first change the column to a binary type to drop its character set label, then change it back to a string type with the correct character set (this is the method shown in the official MySQL manual).
-- Example: fixing title, which holds UTF-8 but was created as a latin1 column
ALTER TABLE posts MODIFY title VARBINARY(800);
ALTER TABLE posts MODIFY title VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL;
Make the binary type at least as long as the original column's maximum byte length (BLOB for a TEXT column, MEDIUMBLOB for MEDIUMTEXT). This method cannot fix a column that mixes data in several character sets. Take a backup before trying it, and test it on a copy of the table first. For garbled text in WordPress, also see Fixing garbled characters in the WordPress database.
Step 5: Change the server default in the configuration file
Changing the server default makes it the default for databases created without a character set. The location of the configuration file depends on the environment.
| Environment | Main configuration file |
|---|---|
| MySQL on Ubuntu/Debian | /etc/mysql/mysql.conf.d/mysqld.cnf |
| MySQL on RHEL-based systems | /etc/my.cnf or a file in /etc/my.cnf.d/ |
| Windows | my.ini, for example in the MySQL data directory |
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_0900_ai_ci
[client]
default-character-set = utf8mb4
default-character-set under [client] is the character set that clients such as the mysql command use when they connect. After the change, restart MySQL (sudo systemctl restart mysql on Ubuntu) and check the values with the SQL from Step 1.
For application connections, specify the character set when connecting. With PHP's PDO, add charset=utf8mb4 to the DSN.
For a WordPress database
WordPress uses these two settings in wp-config.php to decide the connection's character set and collation.
<?php
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );
When DB_COLLATE is empty, the database's default collation is used. Since WordPress 4.2, WordPress creates tables in utf8mb4 when the database supports it. Old tables made only of utf8 (utf8mb3) columns are converted to utf8mb4 by the WordPress upgrade routine, but tables that contain latin1 or other columns are not converted (confirmed in maybe_convert_table_to_utf8mb4() in the WordPress source code). You only need to convert tables by hand when such old tables remain. Before changing wp-config.php, check with the SQL from Step 1 which character set the table columns actually use.
Summary
- Character set and collation exist at four levels (server, database, table, column), and the column setting is what is used for storage.
ALTER DATABASEchanges only the default for tables created later. Convert existing tables withALTER TABLE ... CONVERT TO.- Use utf8mb4 as the character set. Choose the collation according to how you want comparisons to work (voiced marks, kana, case).
- Back up before converting, and check index lengths and duplicates under unique constraints.
- Data that is already garbled cannot be fixed with
CONVERT TO. Try the binary-type method on a copy of the table first.
Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)