데이터베이스 전체에서 CHARACTER SET 및 COLLATION을 변경하는 방법은 무엇입니까?


172

우리의 이전 프로그래머는 테이블 (Mysql)에 잘못된 데이터 정렬을 설정했습니다. 그는 UTF8이어야 할 때 라틴 데이터 정렬로 설정했으며 이제 문제가 있습니다. 중국어와 일본어 문자가있는 모든 레코드는 ??? 캐릭터.

데이터 정렬을 변경하고 캐릭터의 디테일을 되 찾을 수 있습니까?



콜 레이션은 '???'와 어떤 관련이 있습니까? 문자 세트? 나는 그것이 문자 세트와 관련이 있다고 생각 했습니까?
peterchaula 2016 년

의도를 반영하여 제목을 변경하고 있습니다. 데이터베이스기본 데이터 정렬 변경 은 원하는 것보다 훨씬 적습니다.
Rick James

답변:


365

데이터베이스 데이터 정렬 변경 :

ALTER DATABASE <database_name> CHARACTER SET utf8 COLLATE utf8mb4_0900_ai_ci;

테이블 데이터 정렬 변경 :

ALTER TABLE <table_name> CONVERT TO CHARACTER SET utf8 COLLATE utf8mb4_0900_ai_ci;

열 데이터 정렬 변경 :

ALTER TABLE <table_name> MODIFY <column_name> VARCHAR(255) CHARACTER SET utf8 COLLATE utf8mb4_0900_ai_ci;

utf8mb4_0900_ai_ci의미 는 무엇입니까 ?

3 bytes -- utf8
4 bytes -- utf8mb4 (new)
v4.0 --   _unicode_
v5.20 --  _unicode_520_
v9.0 --   _0900_ (new)
_bin      -- just compare the bits; don't consider case folding, accents, etc
_ci       -- explicitly case insensitive (A=a) and implicitly accent insensitive (a=á)
_ai_ci    -- explicitly case insensitive and accent insensitive
_as (etc) -- accent-sensitive (etc)
_bin         -- simple, fast
_general_ci  -- fails to compare multiple letters; eg ss=ß, somewhat fast
...          -- slower
_0900_       -- (8.0) much faster because of a rewrite

더 많은 정보:


4
CHARACTER SET utf8기본적으로 조심 utf8_general_ci하지만 ALTER DATABASE <database_name> CHARACTER SET utf8 COLLATE utf8_unicode_ci;필요한 경우 데이터 정렬을 정의 할 수도 있습니다.
KCD

1
... 그리고 테스트 해 볼 것을 권장합니다create table testit(a varchar(1)); show create table testit \G drop table testit;
KCD

2
두 번째가 데이터 정렬을 다음과 같이 변경한다고 언급하고 싶습니다 utf8_general_ci. 로 변경하려면 utf8_unicode_ci데이터 정렬을 정의 할 수 있습니다 ALTER TABLE <table_name> CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;. @KCD가 지적했듯이 데이터베이스에서 작동하는 것과 똑같은 테이블에서 작동합니다.
더 현명한

9
완전한 utf8 지원을 위해 다음을 수행하는 것이 좋습니다 ALTER DATABASE <database_name> CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci. 다른 두 진술에 대해서도 똑같이해야합니다.
Greeso

"ALTER TABLE <table_name> MODIFY <column_name> ..."을 사용해야합니까? dev.mysql.com/doc/refman/5.5/en/alter-table.html 에 따르면 "ALTER TABLE <table_name> CONVERT TO CHARACTER SET ..."도 열을 변경하는 것 같습니다. 또는 설명서를 올바르게 읽거나 이해하지 못할 수도 있습니다.
hansfn

49

모든 데이터베이스 / 테이블 / 열을 변경하는 방법은 다음과 같습니다. 이 쿼리를 실행하면 전체 스키마를 utf8로 변환하는 데 필요한 모든 후속 쿼리가 출력됩니다. 도움이 되었기를 바랍니다!

-DATABASE 기본 데이터 정렬 변경

SELECT DISTINCT concat('ALTER DATABASE `', TABLE_SCHEMA, '` CHARACTER SET utf8 COLLATE utf8_unicode_ci;')
from information_schema.tables
where TABLE_SCHEMA like  'database_name';

-테이블 데이터 정렬 / 문자 세트 변경

SELECT concat('ALTER TABLE `', TABLE_SCHEMA, '`.`', table_name, '` CHARACTER SET utf8 COLLATE utf8_unicode_ci;')
from information_schema.tables
where TABLE_SCHEMA like 'database_name';

-COLUMN 데이터 정렬 / 문자 세트 변경

SELECT concat('ALTER TABLE `', t1.TABLE_SCHEMA, '`.`', t1.table_name, '` MODIFY `', t1.column_name, '` ', t1.data_type , '(' , t1.CHARACTER_MAXIMUM_LENGTH , ')' , ' CHARACTER SET utf8 COLLATE utf8_unicode_ci;')
from information_schema.columns t1
where t1.TABLE_SCHEMA like 'database_name' and t1.COLLATION_NAME = 'old_charset_name';

좋은. ! 같은 문제를 해결하려고 약 1 시간이 걸립니다. 이 세 가지 명령을 사용했는데 문자 집합이 변경되었음을 알았습니다. 그러나 주요 문제는 여전히 남아 있습니다. 데이터베이스에 직접 쓴 경우 모든 것이 브라우저에 잘 표시됩니다. 그러나 웹 사이트 양식에서 일부 내용을 추가하면 데이터베이스의 결과는 ???????입니다. 고려해야 할 것이 있습니까? 내 웹 앱은 .NET MVC 앱입니다.
Tchaps

향후 프로젝트를위한 유용한 쿼리에 저장.
Manatax

이 자동화 된 쿼리는 아직 사용하기에 안전하지 않기 때문에 일부 수정을 제안했습니다. CHARACTER_MAXIMUM_LENGTH에 여전히 문제가 있습니다. 예를 들어 latin1_swedish_ci에서 utf8_unicode_ci로 변경하면 원래 파일이 너무 높을 수 있습니다.
Ruben

1
이것은 훌륭한 답변입니다. 세 가지 의견 / 질문이 있습니다. 1) COLUMN 코드에서 "t1"을 사용하는 이유는 무엇입니까? 나는 그것을 필요로하지 않습니다. 2) 왜 "t1.column_type"뿐만 아니라 "t1.data_type, '(', t1.CHARACTER_MAXIMUM_LENGTH, ')'"? 3) 대문자와 소문자가 혼합 된 이유-TABLE_SCHEMA 대 table_name 등?
hansfn

25

Mysql에서 utf8문자 집합은 실제 UTF8 문자 집합의 일부일뿐입니다. 1 바이트의 저장 공간을 절약하기 위해 Mysql 팀은 전체 4 바이트 대신 3 바이트의 UTF8 문자 만 저장하기로 결정했습니다. 이는 일부 동아시아 언어 및 이모티콘이 완전히 지원되지 않음을 의미합니다. 모든 UTF8 문자를 저장할 수 있도록하려면 utf8mb4데이터 유형을 사용 utf8mb4_bin하거나 utf8mb4_general_ciMysql을 사용하십시오.


1
지금은 utf8mb4_unicode_ci대신에 사용 하는 것이 좋습니다 utf8mb4_general_ci. 참조 stackoverflow.com/questions/766809/...을 하고 drupal.stackexchange.com/questions/166405/...
로빈 반 Baalen

6

David Whittaker가 게시 한 내용 외에도 각 테이블을 변환 할 전체 테이블과 열 alter 문을 생성하는 쿼리를 만들었습니다. 달리는 것이 좋습니다

세션 설정 group_concat_max_len = 100000;

먼저 그룹 concat이 여기에 표시된 것처럼 매우 작은 한계를 넘지 않도록 하십시오 .

     SELECT a.table_name, concat('ALTER TABLE ', a.table_schema, '.', a.table_name, ' DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci, ',
        group_concat(distinct(concat(' MODIFY ',  column_name, ' ', column_type, ' CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ', if (is_nullable = 'NO', ' NOT', ''), ' NULL ',
        if (COLUMN_DEFAULT is not null, CONCAT(' DEFAULT \'', COLUMN_DEFAULT, '\''), ''), if (EXTRA != '', CONCAT(' ', EXTRA), '')))), ';') as alter_statement
    FROM information_schema.columns a
    INNER JOIN INFORMATION_SCHEMA.TABLES b ON a.TABLE_CATALOG = b.TABLE_CATALOG
        AND a.TABLE_SCHEMA = b.TABLE_SCHEMA
        AND a.TABLE_NAME = b.TABLE_NAME
        AND b.table_type != 'view'
    WHERE a.table_schema = ? and (collation_name = 'latin1_swedish_ci' or collation_name = 'utf8mb4_general_ci')
    GROUP BY table_name;

이전 답변의 차이점은 ut8mb4 대신 utf8을 사용하고 t1.data_type을 t1과 함께 사용했다는 것입니다 .CHARACTER_MAXIMUM_LENGTH는 열거 형에서 작동하지 않습니다. 또한 내 쿼리는 뷰를 별도로 변경해야하기 때문에 뷰를 제외합니다.

나는 단순히 Perl 스크립트를 사용하여 이러한 모든 변경 사항을 배열로 반환하고 반복했습니다. 너무 긴 열을 수정했습니다 (일반적으로 데이터에 일반적으로 20 문자 만있을 때 varchar (256) 였으므로 쉽게 고쳤습니다. ).

latin1-> utf8mb4에서 변경할 때 일부 데이터가 손상되었음을 발견했습니다. 열에서 utf8로 인코딩 된 latin1 문자가 변환에서 왜곡되는 것처럼 보입니다. 필자는 변경 전후의 메모리에서 문제가 될 것으로 알고있는 열의 데이터를 보유하고 데이터를 수정하기 위해 업데이트 문을 생성했습니다.


4

여기 에 프로세스가 잘 설명되어 있습니다. 그러나 라틴 공간에 맞지 않는 일부 문자는 영원히 사라졌습니다. UTF-8은 latin1의 슈퍼 세트입니다. 반대는 아닙니다. 대부분은 단일 바이트 공간에 맞지 만 정의되지 않은 것은 맞지 않습니다 (latin1 목록을 확인하십시오-mysql의 latin1 정의에 따라 256 문자가 모두 정의되어 있지는 않습니다)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.