MySQL의 문자셋 및 대조 개념
WordPress가 사이트의 콘텐츠(글, 제목, 번역된 문자열 등)를 데이터베이스에 저장할 때 문자셋(character set)을 사용하여 문자를 표현하고 대조(collation)를 사용하여 해당 문자를 비교하고 정렬하는 방법을 정의합니다.
- 문자셋(Charset)
- 문자가 데이터베이스에 저장되는 방식을 정의합니다. 즉, 어떤 바이트가 어떤 문자를 나타내는지 정의합니다.
- 대조(Collation)
- 해당 문자를 비교하는 규칙(예: 대소문자 구분, 악센트 구분, 정렬 순서)을 정의합니다.
다국어 사이트에서 중요한 이유
WPML은 다국어 콘텐츠를 지원하며, 여기에는 종종 다음이 포함됩니다.
- 특수 문자(예: ñ, é, ö)
- 비라틴 문자(예: 아랍어, 일본어, 중국어, 히브리어)
- 이모지 및 기호(🎉, ✔️ 등)
이 중 상당수는 올바르게 저장하기 위해 3바이트 이상이 필요합니다. 데이터베이스에서 호환되지 않는 대조를 사용하는 경우 문자가 손실되거나 물음표(?)로 대체되거나 데이터베이스 오류(예: “Incorrect string value”)가 발생할 수 있습니다.
따라서 4바이트 유니코드 문자를 지원하는 대조를 사용하는 것을 강력히 권장합니다.
권장 사항
utf8mb4 문자셋과 다음과 같은 유니코드 호환 대조를 사용하세요.
- utf8mb4_unicode_ci – 널리 호환되는 좋은 기본값
- utf8mb4_unicode_520_ci – MySQL 5.6 이상에서 더 나은 유니코드 처리
- utf8mb4_general_ci – 약간 더 빠르지만 덜 정확한 유니코드 비교
- utf8mb4_bin – 대소문자 및 악센트 구분(이진 비교)
모두 WPML과 함께 사용해도 안전합니다.
중요: MySQL의 이전 utf8 문자셋은 문자당 최대 3바이트까지만 지원합니다. 이모지나 일부 표의문자와 같은 일부 문자는 처리할 수 없습니다. 다국어 콘텐츠에는 사용하지 마세요.
MySQL의 기본값
| MySQL 버전 | 기본 문자셋 | 기본 대조 | 유니코드 호환 여부 |
|---|---|---|---|
| < 5.5 | latin1 | latin1_swedish_ci | 아니요 |
| 5.5.x | utf8 | utf8_general_ci | 아니요 |
| 5.7+ | utf8mb4 | utf8mb4_general_ci / utf8mb4_unicode_ci | 예 |
| 8.0+ | utf8mb4 | utf8mb4_0900_ai_ci | 예 |
WordPress가 항상 MySQL의 기본값을 따르는 것은 아니며, 구성이나 마이그레이션을 통해 이를 재정의할 수 있습니다.
새 사이트의 문자셋 및 대조 설정
WordPress가 올바른 문자셋과 대조로 새 테이블을 생성하도록 하려면 wp-config.php에 다음을 정의하세요.
define( 'DB_CHARSET', 'utf8mb4' ); // If you have utf8 that's fine, WP will automatically map it as utf8mb4 define( 'DB_COLLATE', 'utf8mb4_unicode_ci' );
이는 새 설치 및 새로 생성된 테이블에 적용됩니다.
기존 사이트 및 테이블의 문자셋 및 대조 확인
기존 사이트에서 문자셋과 대조를 확인하는 방법은 다음과 같습니다.
옵션 1 phpMyAdmin
- 사이트의 데이터베이스로 이동하세요.
- 각 테이블 옆의 “대조” 열을 확인하세요.
- 테이블을 클릭하여 각 열의 개별 대조를 확인하세요.
옵션 2 WP-CLI
bash
wp db query "SELECT TABLE_NAME, TABLE_COLLATION FROM information_schema.tables WHERE table_schema = 'your_db_name';"
개별 열을 검사할 수도 있습니다.
bash
wp db query "SHOW FULL COLUMNS FROM wp_posts;"
대조가 utf8mb4_로 시작하는 경우 모든 유형의 유니코드 및 4바이트 표의문자를 지원할 준비가 된 것입니다. 문자셋도 정상입니다.
예를 들어 utf8_*과 같이 다른 항목이 표시되면 이를 변경해야 합니다.
대조는 열마다 다를 수 있다는 점에 유의하세요.
기존 테이블 및 열의 문자셋 및 대조 업데이트
wp-config.php 파일에서 DB_CHARSET 및 DB_COLLATE 상수를 업데이트하는 것은 새 테이블에만 영향을 미칩니다. 기존 테이블과 열에 변경 사항을 적용하려면 SQL을 사용하여 수동으로 변환해야 합니다.
또한 다음 명령을 사용하여 데이터베이스의 기본 MySQL 대조를 업데이트하는 것을 권장합니다.
ALTER DATABASE your_database_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
항상 백업으로 시작
변환 쿼리를 실행하기 전에 다음을 수행하세요.
- phpMyAdmin 또는 mysqldump를 사용하여 데이터베이스를 내보내세요.
- 문제가 발생할 경우를 대비하여 안전하게 보관하세요.
경고: 엄격 모드(Strict Mode)에서는 대조 업데이트가 실패할 수 있음
전체 테이블(또는 데이터베이스)의 대조를 업데이트할 때 MySQL은 테이블을 다시 빌드하고 DATETIME과 같이 관련 없는 열을 포함하여 모든 열의 기본값을 다시 검증할 수 있습니다. 데이터베이스가 엄격한 SQL 모드(STRICT_TRANS_TABLES, NO_ZERO_DATE)로 실행 중인 경우 ‘0000-00-00 00:00:00’과 같은 기본값이 있는 열은 다음과 같은 오류를 트리거합니다.
#1067 - Invalid default value.
엄격 모드의 개념
엄격 모드는 데이터베이스에 데이터가 추가되거나 업데이트될 때 MySQL이 유효하지 않거나 누락된 값을 처리하는 방법을 제어합니다. 값은 여러 가지 이유로 유효하지 않을 수 있습니다. 예를 들어 열의 데이터 유형이 잘못되었거나 범위를 벗어났을 수 있습니다.
엄격 모드의 다양한 데이터 검증 유형에 대한 정보는 MySQL 문서에서 확인할 수 있습니다.
엄격 모드가 WordPress 웹사이트 데이터베이스에 미치는 영향
기본적으로 WordPress는 일부 datetime 열의 기본값으로 ‘0000-00-00 00:00:00’을 사용하지만, 이는 NO_ZERO_DATE 엄격 모드에서 허용되지 않습니다.
이러한 기본값은 원래 테이블 생성 시(예: WordPress 설정 중)에는 허용되었지만, 엄격한 환경에서 ALTER 작업을 수행하면 실패한다는 점에 유의하세요.
엄격 모드 활성화 여부 확인 방법
다음 명령을 실행하세요.
SELECT @@SESSION.sql_mode, @@GLOBAL.sql_mode;
다음 항목을 찾으세요.
- STRICT_TRANS_TABLES
- STRICT_ALL_TABLES
- NO_ZERO_DATE
이 중 하나라도 발견되면 엄격 모드가 활성화된 것입니다.
문자셋 및 대조 업데이트 중 오류를 방지하려면 NO_ZERO_DATE 엄격 모드만 비활성화하면 됩니다.
안전하게 진행하는 방법
안전하게 진행하려면 다음 중 하나를 수행하세요.
1. 대조를 실제로 변경해야 하는 경우가 아니면 열과 테이블을 변경하지 마세요.
2. 변환 쿼리를 실행하는 동안 해당 세션에 대해서만 임시로 엄격 모드를 비활성화하세요. 다음 명령을 사용하여 이 작업을 수행할 수 있습니다.
SET SESSION sql_mode = REPLACE(@@sql_mode, 'NO_ZERO_DATE', '');
참고: 향후 MySQL에서 엄격 모드를 통합할 계획이 있습니다.
데이터와 관련된 다른 문제가 발생하는 경우 다음 명령을 사용하여 모든 엄격 모드를 비활성화할 수 있습니다.
SET SESSION sql_mode = '';
데이터 변환을 위한 쿼리
전체 데이터베이스 변환
다음은 데이터베이스의 각 테이블에 대한 ALTER TABLE 쿼리를 생성합니다.
SELECT CONCAT( 'ALTER TABLE `', TABLE_NAME, '` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;' ) AS query FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'your_database_name';
결과 쿼리를 phpMyAdmin에서 실행하거나 MySQL CLI / WP-CLI에 복사하여 붙여넣으세요.
이렇게 하면 데이터베이스의 모든 테이블에 새 문자셋과 대조가 적용됩니다.
특정 테이블 변환 선택 사항/보조
ALTER TABLE wp_posts CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
이는 wp_posts 테이블의 모든 텍스트 열을 업데이트하여 utf8mb4 및 지정된 대조를 사용하도록 합니다.
특정 열 변환 선택 사항/보조
ALTER TABLE wp_posts CHANGE post_title post_title TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
참고:
- CHANGE에서 열(유형, 이름)을 완전히 다시 선언해야 합니다.
- 열 유형이 기존 유형과 일치하는지 확인하세요.
변환 시 발생하는 일반적인 오류
테이블과 열을 변환할 때 발생할 수 있는 두 가지 일반적인 오류는 다음과 같습니다.
일치하지 않는 문자셋 및 대조
-- INVALID: utf8 collation with utf8mb4 charset ALTER TABLE wp_posts CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8_general_ci; -- Error: COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'utf8mb4'
해결책:
- 일치하는 대조 사용: utf8mb4_*
인덱스 키 길이 제한
ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
일부 구성, 특히 MySQL 5.7 미만 버전에서는 문자당 1바이트를 추가할 때 최대 인덱스 키 길이를 초과할 수 있습니다.
해결책:
- 필요한 경우 인덱싱된 VARCHAR(255)를 VARCHAR(191)로 줄이세요.
- 또는 MySQL 5.7 이상으로 업그레이드하고 innodb_large_prefix가 활성화되어 있는지 확인하세요.
요약
- 전체 유니코드 지원을 위해 utf8mb4 문자셋 사용
- 호환되는 대조 사용: utf8mb4_unicode_ci, utf8mb4_0900_ai_ci 등
- 새 테이블을 위해 wp-config.php 업데이트
- 기존 테이블 수정을 위해 SQL 마이그레이션 실행
- 문자셋과 대조를 절대 혼합하지 마세요. MySQL에서 이를 거부하거나 손상시킬 수 있습니다.