¿Cómo cambiar el juego de caracteres predeterminado de una tabla MySQL?

97

Hay un MySQL tableque tiene esta definición tomada de SQLYog Enterprise:

Table              Create Table                                             
-----------------  ---------------------------------------------------------
etape_prospection  CREATE TABLE `etape_prospection` (                       
                     `etape_prosp_id` int(10) NOT NULL AUTO_INCREMENT,      
                     `type_prosp_id` int(10) NOT NULL DEFAULT '0',          
                     `prosp_id` int(10) NOT NULL DEFAULT '0',               
                     `etape_prosp_date` datetime DEFAULT NULL,              
                     `etape_prosp_comment` text,                            
                     PRIMARY KEY (`etape_prosp_id`),                        
                     KEY `concerne_fk` (`prosp_id`),                        
                     KEY `de_type_fk` (`type_prosp_id`)                     
                   ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1  

Quiero cambiar el default charsetde esta tabla de latin1a utf8. Como hacer eso ?

feromix
fuente
3
El nombre correcto para "UTF8" en MySQL es "utf8mb4" el juego de caracteres "utf8" está roto, solo admite hasta 3 bytes de caracteres. Consulte el manual de mysql para obtener más detalles, o busque en Google "mysql" y "utf8" ... dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8.html
Samuel Åslund

Respuestas:

203

Si desea cambiar la tabla default character sety todas las columnas de caracteres a un nuevo conjunto de caracteres, use una declaración como esta:

ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;

Entonces la consulta será:

ALTER TABLE etape_prospection CONVERT TO CHARACTER SET utf8;

fuente
22
Por el contrario, si usa la ALTER TABLE tbl CHARACTER SET utf8sintaxis sugerida por otros, cambiará solo la codificación predeterminada para la tabla; las columnas existentes no se convertirán como lo harán si usa esta respuesta.
eaj
7
Si desea aplicar este cambio para todas las tablas que no están codificadas en ut8 en una base de datos, puede usar esta consulta y ejecutar las consultas resultantes: SELECT concat('alter table ', table_name, ' CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;') FROM information_schema.tables WHERE table_schema='<your_database_name>' and table_collation != 'utf8_general_ci' GROUP BY table_name;
Maxooo
3
esto no cambia el juego de caracteres predeterminado . para cambiar el valor predeterminado, haga lo que dijo eakALTER TABLE tbl CHARACTER SET utf8
Contador م
7
Me gustaría agregar que, por lo general, no desea usar utf8 sino utf8mb4 para obtener lo que podría esperar que sea utf8. Para explicar: en MySQL utf8 es realmente solo un subconjunto de utf8, que sería mejor llamado utf8mb3. Solo puede codificar hasta 3 bytes de caracteres utf8 en lugar de los hasta 4 bytes que se especifican. Esto significa que muchos emoji no serán codificables y simplemente se perderán si intenta escribirlos en la base de datos. Ver, por ejemplo. medium.com/@adamhooper/… para obtener más detalles.
dwt
6
para multibyte que puede usarALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
RN Kushwaha
18

Cambiar el juego de caracteres predeterminado de la tabla:

ALTER TABLE etape_prospection
  CHARACTER SET utf8,
  COLLATE utf8_general_ci;

Para cambiar el conjunto de caracteres de la columna de cadena supere esta consulta:

ALTER TABLE etape_prospection
  CHANGE COLUMN etape_prosp_comment etape_prosp_comment TEXT CHARACTER SET utf8 COLLATE utf8_general_ci;
Devart
fuente
10
Nunca, nunca debe usar utf8_general_ci: simplemente no funciona. Es un retroceso a los viejos tiempos de la tacañería ASCII de hace cincuenta años. La coincidencia Unicode que no distingue entre mayúsculas y minúsculas no se puede realizar sin el mapa de plegado del UCD. Por ejemplo, "Σίσυφος" tiene tres sigmas diferentes; o cómo la minúscula de “TSCHüẞ” es “tschüβ”, pero la mayúscula de “tschüβ” es “TSCHÜSS”. Puede tener razón o puede ser rápido. Por lo tanto, debe usar utf8_unicode_ci, porque si no le importa la corrección, entonces es trivial hacerlo infinitamente rápido.
Yohanes AI
1
El juego de caracteres MySQL UTF8 está roto, ¡debe usar utf8mb4!
Samuel Åslund
5

El ALTER TABLEcomando MySQL debería funcionar. El siguiente comando cambiará el juego de caracteres predeterminado de su tabla y el juego de caracteres de todas sus columnas a UTF8.

ALTER TABLE etape_prospection CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

Este comando convertirá todas las columnas similares a texto en la tabla al nuevo juego de caracteres. Los conjuntos de caracteres utilizan diferentes cantidades de datos por carácter, por lo que MySQL convertirá el tipo de algunas columnas para garantizar que haya suficiente espacio para adaptarse a la misma cantidad de caracteres que el tipo de columna anterior.

Le recomiendo que lea la documentación de ALTER TABLE MySQL antes de modificar cualquier dato en vivo.

piersadrian
fuente
1
Sí, funciona, pero una cosa es diferente con la conversión a modo: no puede eliminar la opción de juego de caracteres antiguo de las columnas automáticamente.
tech_me
3

Si alguien está buscando una solución completa para cambiar el juego de caracteres predeterminado para todas las tablas de la base de datos y convertir los datos, esta podría ser una:

DELIMITER $$

CREATE PROCEDURE `exec_query`(IN sql_text VARCHAR(255))
BEGIN
  SET @tquery = `sql_text`;
  PREPARE `stmt` FROM @tquery;
  EXECUTE `stmt`;
  DEALLOCATE PREPARE `stmt`;
END$$

CREATE PROCEDURE `change_character_set`(IN `charset` VARCHAR(64), IN `collation` VARCHAR(64))
BEGIN
DECLARE `done` BOOLEAN DEFAULT FALSE;
DECLARE `tab_name` VARCHAR(64);
DECLARE `charset_cursor` CURSOR FOR 
    SELECT `table_name` FROM `information_schema`.`tables`
    WHERE `table_schema` = DATABASE() AND `table_type` = 'BASE TABLE';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET `done` = TRUE;

SET foreign_key_checks = 0;
OPEN `charset_cursor`;
`change_loop`: LOOP
FETCH `charset_cursor` INTO `tab_name`;
IF `done` THEN
    LEAVE `change_loop`;
END IF;
CALL `exec_query`(CONCAT(
  'ALTER TABLE `',
  tab_name,
  '` CONVERT TO CHARACTER SET ',
  QUOTE(charset),
  ' COLLATE ',
  QUOTE(collation),
  ';'
));
CALL `exec_query`(CONCAT('REPAIR TABLE `', tab_name, '`;'));
CALL `exec_query`(CONCAT('OPTIMIZE TABLE `', tab_name, '`;'));
END LOOP `change_loop`;
CLOSE `charset_cursor`;
SET foreign_key_checks = 1;
END$$

DELIMITER ;

Puede colocar este código dentro del archivo, por ejemplo, chg_char_set.sqly ejecutarlo, por ejemplo, llamándolo desde la terminal MySQL:

SOURCE ~/path-to-the-file/chg_char_set.sql

Luego llame al procedimiento definido con los parámetros de entrada deseados, por ejemplo

CALL change_character_set('utf8mb4', 'utf8mb4_bin');

Una vez que haya probado los resultados, puede eliminar esos procedimientos almacenados:

DROP PROCEDURE `change_character_set`;
DROP PROCEDURE `exec_query`;
milijan
fuente
Falta una condición que nos lleva a seleccionar vistas también. Es DONDE table_schema = DATABASE (); => DONDE tabla_esquema = BASE_DATOS () Y tipo_tabla = 'TABLA BASE'; ¡¡Pero gracias!! ¡Esto es lo que necesito!
nguyenhoai890
2

Puede cambiar el valor predeterminado con un alter table set default charsetpero eso no cambiará el juego de caracteres de las columnas existentes. Para cambiar eso, debe usar un alter table modify column.

Cambiar el juego de caracteres de una columna solo significa que podrá almacenar una gama más amplia de caracteres. Su aplicación habla con la base de datos utilizando el cliente mysql, por lo que es posible que también deba cambiar la codificación del cliente.

Joni
fuente
Lo haría si no fuera por el teclado limitado del iPod touch :-)
Joni
bueno el iPod Touch / iPhone debe tener algún inconveniente. :-P Nunca me di cuenta de que faltaban hasta que lo mencionaste. ;-)
Aufwind
Mantenga presionado el botón del carácter de la cita para ver el carácter de la cita inversa.
Chloe