2011-05-06 2 views
124

이전 프로그래머가 테이블 (Mysql)에서 잘못된 데이터 정렬을 설정했습니다. UTF8이어야 할 라틴계 데이터 정렬로 설정 했으므로 이제 문제가 발생합니다. 중국어와 일본 문자가있는 모든 레코드는 ???으로 바뀝니다. 캐릭터.데이터베이스의 기본 데이터 정렬을 변경하는 방법은 무엇입니까?

데이터 정렬을 변경하고 문자 세부 사항을 되돌릴 수 있습니까?

+0

[MySql alter table Collation] (http://stackoverflow.com/questions/742205/mysql-alter-table-collation) 중복 가능 – kenorb

답변

285

변경 데이터베이스 데이터 정렬 (라틴의 목록을 확인 모든 256 개 문자는 MySQL의의 라틴 정의에 따라 정의되지 않음) 테이블 정렬 :

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

변경 열 정렬 :

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

상세 정보 :

+4

'CHARACTER SET utf8'은 'utf8_general_ci'로 기본 설정되어 있습니다 만, 다음과 같이 데이터 정렬을 정의하십시오. 'ALTER DATABASE CHARACTER SET utf8 COLLATE utf8_unicode_ci;'필요하다면 – KCD

+0

...'test table testit (a varchar (1)); 쇼 테이블 testit \ G 드롭 테이블 testit을 보여' – KCD

+0

감사합니다 @ 티모 Huovinen, 명령은 매력처럼 작동합니다 : D 조 –

3

here은 프로세스를 잘 설명한다. 그러나 라틴 공간에 맞지 않는 캐릭터 중 일부는 영원히 사라졌습니다. UTF-8은 latin1의 상위 집합입니다. 반대가 아닙니다.

ALTER DATABASE <database_name> CHARACTER SET utf8 COLLATE utf8_unicode_ci; 

변화 : - 대부분의 단일 바이트 공간에 맞게되지만, 정의되지 않은 사람이되지 않습니다

14

이 MySQL의에서 그주의는 utf8 문자 집합은 실제 UTF8 문자 집합의 부분 집합이다. 1 바이트의 저장 공간을 절약하기 위해 Mysql 팀은 전체 4 바이트 대신 3 바이트의 UTF8 문자 만 저장하기로 결정했습니다. 즉 동양의 일부 아시아 언어와 이모티콘은 완전히 지원되지 않습니다. 모든 UTF8 문자를 저장할 수 있는지 확인하려면 utf8mb4 데이터 형식을 사용하고 utf8mb4_bin 또는 utf8mb4_general_ci을 Mysql에 사용하십시오.

+1

이것은 매우 도움이되었습니다. – Raz0rwire

+1

http://stackoverflow.com/questions/367711/what-is-the-best-collation-to-use-for-mysql-with-php?rq=1 –

29

Heres 모든 데이터베이스/테이블/열을 변경하는 방법. 이 쿼리를 실행하면 전체 스키마를 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'; 

- 변경 열 정렬/문자 세트

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'; 
+0

좋습니다. ! 그것은 같은 문제를 해결하려고하는 약 1 시간입니다. 나는이 3 개의 명령을 사용하고, charset이 변경된 것을 보았다. 그러나 주된 문제는 나에게 남아있다. 만약 내가 직접 데이터베이스에 쓴다면 모든 것이 내 브라우저에서 잘 보인다. 하지만 웹 사이트 양식에서 일부 콘텐츠를 추가하면 데이터베이스의 결과는 단지 ??????.입니다. 내가 고려해야 할 것이 있습니까? 내 웹 응용 프로그램은 .NET MVC 응용 프로그램입니다. – Tchaps

+0

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

+0

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

4

에 추가 것을 David Whittaker가 게시했습니다. 전체 테이블을 생성하고 열을 변경하는 쿼리를 만들었습니다. 각 테이블을 아프게 변환하십시오. 실행하는 것이 좋습니다.

SET SESSION group_concat_max_len = 100000;

먼저 그룹 concat이 here처럼 매우 작은 제한을 초과하지 않는지 확인하십시오.

 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; 

이전의 대답과 여기의 차이는 UTF8 대신 ut8mb4를 사용하여 열거 형을 위해 작동하지 않았다 t1.CHARACTER_MAXIMUM_LENGTH와 t1.data_type를 사용했다입니다. 또한 이러한 쿼리는 별도로 변경해야하기 때문에 뷰를 제외합니다.

나는이 모든 변경을 배열로 반환하기 위해 단순히 Perl 스크립트를 사용하여 너무 길었던 (일반적으로 데이터가 일반적으로 20 자 밖에 없었을 때 일반적으로 varchar (256)이었습니다. 쉬운 수정이었다).

latin1 -> utf8mb4에서 변경할 때 일부 데이터가 손상된 것을 발견했습니다. 열에서 utf8로 인코딩 된 latin1 문자가 변환에서 정상적으로 나타납니다. 나는 단순히 변경 전후의 메모리에서 문제가 될 것으로 알고있는 열의 데이터를 보유하고 데이터를 비교하기 위해 업데이트 명령문을 생성했습니다.