Tengo una solución que convertirá bases de datos y tablas ejecutando algunos comandos. También convierte todas las columnas del tipo varchar
, text
, tinytext
, mediumtext
, longtext
, char
. También debe hacer una copia de seguridad de su base de datos en caso de que algo se rompa.
Copie el siguiente código en un archivo llamado preAlterTables.sql:
use information_schema;
SELECT concat("ALTER DATABASE `",table_schema,"` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;") as _sql
FROM `TABLES` where table_schema like "yourDbName" group by table_schema;
SELECT concat("ALTER TABLE `",table_schema,"`.`",table_name,"` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;") as _sql
FROM `TABLES` where table_schema like "yourDbName" group by table_schema, table_name;
SELECT concat("ALTER TABLE `",table_schema,"`.`",table_name, "` CHANGE `",column_name,"` `",column_name,"` ",data_type,"(",character_maximum_length,") CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",IF(is_nullable="YES"," NULL"," NOT NULL"),";") as _sql
FROM `COLUMNS` where table_schema like "yourDbName" and data_type in ('varchar','char');
SELECT concat("ALTER TABLE `",table_schema,"`.`",table_name, "` CHANGE `",column_name,"` `",column_name,"` ",data_type," CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",IF(is_nullable="YES"," NULL"," NOT NULL"),";") as _sql
FROM `COLUMNS` where table_schema like "yourDbName" and data_type in ('text','tinytext','mediumtext','longtext');
Reemplace todas las ocurrencias de "yourDbName" con la base de datos que desea convertir. Entonces corre:
mysql -uroot < preAlterTables.sql | egrep '^ALTER' > alterTables.sql
Esto generará un nuevo archivo alterTables.sql, con todas las consultas que necesita para convertir la base de datos. Ejecute el siguiente comando para iniciar la conversión:
mysql -uroot < alterTables.sql
También puede adaptar esto para que se ejecute a través de múltiples bases de datos, cambiando la condición para el esquema_tabla. Por ejemplo table_schema like "wiki_%"
, convertirá todas las bases de datos con el prefijo de nombre wiki_
. Para convertir todas las bases de datos, reemplace la condición con table_type!='SYSTEM VIEW'
.
Un problema que podría surgir. Tenía algunas columnas varchar (255) en las claves mysql. Esto causa un error:
ERROR 1071 (42000) at line 2229: Specified key was too long; max key length is 767 bytes
Si eso sucede, simplemente puede cambiar la columna para que sea más pequeña, como varchar (150), y volver a ejecutar el comando.
Tenga en cuenta : esta respuesta convierte la base de datos en utf8mb4_unicode_ci
lugar de la que se utf8mb4_bin
hace en la pregunta. Pero simplemente puedes reemplazar esto.
mysql -uroot -pThatrootPassWord < alterTables.sql
funciona. Y como ya notó, utf8mb4_bin es lo que, entre otros, recomienda nextcloud.Usé el siguiente script de shell. Toma el nombre de la base de datos como parámetro y convierte todas las tablas a otro conjunto de caracteres y clasificación (dado por otros parámetros o valores predeterminados definidos en el script).
fuente
Escribiría un script (en Perl, o lo que sea) para usar información_esquema (TABLAS y COLUMNAS) para recorrer todas las tablas y MODIFICAR COLUMNA en cada campo CHAR / VARCHAR / TEXT. Recogería todos los MODIFYs en un solo ALTER para cada tabla; Esto será más eficiente.
Creo (pero no estoy seguro) que la sugerencia de Raihan solo cambia el valor predeterminado para la tabla.
fuente
Me encontré con esta situación; Aquí está el enfoque que usé para convertir mi base de datos:
Primero, debe editar
my.cnf
para establecer una conexión de base de datos predeterminada (entre aplicaciones y MYSQL) compatible con utf8mb4_unicode_ci. Sin estos caracteres como emojis y similares enviados por sus aplicaciones, no llegarán a sus tablas en bytes / codificación correctos (a menos que los parámetros de DB CNN de su aplicación especifiquen una conexión utf8mb4).Instrucciones dadas aquí .
Ejecute el siguiente SQL (no es necesario prepararse para cambiar columnas individuales, las
ALTER TABLE
declaraciones lo harán).Antes de ejecutar el siguiente código, reemplace "DbName" con su nombre de base de datos real.
Recopile y guarde la salida del SQL anterior en un archivo dot sql y ejecútelo.
Si obtiene un error como
#1071 - Specified key was too long; max key length is 1000 bytes.
el nombre de la tabla problemática, esto significa que la clave de índice en alguna columna de esa tabla (que se suponía que se convertiría en MB4) sería muy grande, por lo tanto, la columna Varchar debería ser <= 250 para que su la clave de índice tendrá un máximo de 1000 bytes. Verifique las columnas en las que tiene índices y si una de ellas es un varchar> 250 (muy probablemente 255), entoncesPaso 1: verifique los datos en esa columna para asegurarse de que el tamaño máximo de la cadena en esa columna sea <= 250.
Consulta de ejemplo:
Paso 2: si la longitud máxima de los datos de la columna indexada <= 250, cambie la longitud de la columna a 250. Si eso no es posible, elimine el índice en esa columna
Paso 3: luego ejecute la consulta alter table para esa tabla nuevamente y la tabla ahora debe convertirse a utf8mb4 con éxito.
¡Salud!
fuente
Escribí esta guía: http://hanoian.com/content/index.php/24-automate-the-converting-a-mysql-database-character-set-to-utf8mb4
Desde mi trabajo, vi que ALTERAR la base de datos y las tablas no es suficiente. Tuve que ir a cada tabla y ALTERAR cada una de las columnas text / mediumtext / varchar también.
Afortunadamente, pude escribir un script para detectar los metadatos de las bases de datos MySQL, por lo que podría recorrer las tablas y columnas y ALTERARLAS automáticamente.
Índice largo para MySQL 5.6:
Hay una cosa que debe tener el privilegio DBA / SUPER USUARIO: establecer los parámetros de la base de datos:
En las respuestas a esta pregunta, hay instrucciones sobre cómo establecer esos parámetros arriba: https://stackoverflow.com/questions/35847015/mysql-change-innodb-large-prefix
Por supuesto, en mi artículo, hay instrucciones para hacerlo también.
Para MySQL versión 5.7 o posterior , innodb_large_prefix está activado de forma predeterminada, y innodb_file_format también es Barracuda de forma predeterminada.
fuente
Para las personas que podrían tener este problema, la mejor solución es modificar primero las columnas a un tipo binario, de acuerdo con esta tabla:
Y después de eso, modifique la columna de nuevo a su tipo anterior y con el juego de caracteres deseado.
P.ej.:
Lo intenté en varias tablas latin1 y mantuvo todos los diacríticos.
Puede extraer esta consulta para todas las columnas haciendo esto:
fuente
Hice un script que hace esto más o menos automáticamente:
fuente