¿Cómo cambiar la intercalación predeterminada de una base de datos?


Nuestro programador anterior estableció la intercalación incorrecta en una tabla (Mysql). Lo arregló con la colación latina, cuando debería ser UTF8, y ahora tengo problemas. Cada registro con China y Japón personaje de turno ??? caracter.

Es posible cambiar la intercalación y recuperar el detalle de personaje?

Author: kenorb, 2011-05-06

5 answers

Cambiar la recopilación de la base de datos:

ALTER DATABASE <database_name> CHARACTER SET utf8 COLLATE utf8_unicode_ci;

Cotejo de la tabla de cambios:

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

Cambiar la colación de columnas:

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

Más información:

 308
Author: Timo Huovinen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:29

He aquí cómo cambiar todas las bases de datos/tablas/columnas. Ejecute estas consultas y generarán todas las consultas posteriores necesarias para convertir todo su esquema a utf8. Espero que esto ayude!

Change Cambiar la Intercalación predeterminada de LA BASE DE DATOS

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

Change Change TABLE Collation / Char Set

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

Change Cambiar la Intercalación DE COLUMNAS / Conjunto de Caracteres

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';
 34
Author: David Whittaker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-03 15:54:41

Tenga en cuenta que en Mysql, el conjunto de caracteres utf8 es solo un subconjunto del conjunto de caracteres UTF8 real. Para guardar un byte de almacenamiento, el equipo de Mysql decidió almacenar solo tres bytes de caracteres UTF8 en lugar de los cuatro bytes completos. Eso significa que algunos idiomas de Asia oriental y emoji no son totalmente compatibles. Para asegurarse de que puede almacenar todos los caracteres UTF8, use el tipo de datos utf8mb4, y utf8mb4_bin o utf8mb4_general_ci en Mysql.

 20
Author: bluecollarcoder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-03 15:04:28

Añadiendo a lo que David Whittaker publicó, he creado una consulta que genera la tabla completa y columnas alter declaración que convertirá cada tabla. Puede ser una buena idea ejecutar

ESTABLECER SESIÓN group_concat_max_len = 100000;

Primero para asegurarse de que su concat de grupo no supere el límite muy pequeño como se ve aquí.

     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;

Una diferencia aquí entre la respuesta anterior es que estaba usando utf8 en lugar de ut8mb4 y usando t1.data_type con t1.CHARACTER_MAXIMUM_LENGTH no funcionó para enumeraciones. Además, mi consulta excluye las vistas, ya que tendrán que alterarse por separado.

Simplemente usé un script de Perl para devolver todos estos alters como una matriz e iteré sobre ellos, arreglé las columnas que eran demasiado largas (generalmente eran varchar(256) cuando los datos generalmente solo tenían 20 caracteres en ellos, por lo que fue una solución fácil).

Encontré que algunos datos estaban dañados al alterar desde latin1 -> utf8mb4. Parecía estar codificado en utf8 latin1 los caracteres en las columnas se estropearían en la conversión. Simplemente guardé los datos de las columnas que sabía que iba a ser un problema en la memoria de antes y después del alter y los comparé y generé instrucciones de actualización para corregir los datos.

 6
Author: Jacob Hundley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:15

Aquí describe bien el proceso. Sin embargo, algunos de los personajes que no encajaban en el espacio latino se han ido para siempre. UTF-8 es un SUPERCONJUNTO de latin1. No al revés. La mayoría encajará en un solo espacio de bytes, pero los indefinidos no (compruebe una lista de latin1-no todos los 256 caracteres están definidos, dependiendo de la definición latin1 de mysql)

 4
Author: MJB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-11 14:57:17