Como alterar o agrupamento de banco de dados, tabela, coluna?


Respostas:


257

Você precisa converter cada tabela individualmente:

ALTER TABLE mytable CONVERT TO CHARACTER SET utf8mb4 

(isso também converterá as colunas) ou exporte o banco de dados latin1e importe-o novamente utf8mb4.


15
Mas eu quero alterar o agrupamento de colunas. Este é só mudará o agrupamento da tabela ..
user158469

7
@rsensan: CONVERTtambém alterará o agrupamento de colunas.
Quassnoi 18/08/09

21
ALTER SCHEMA database PADRÃO PADRÃO SET utf8 DEFAULT COLLATE utf8_general_ci;
stormwild

8
@stormwild: isso não afetará tabelas existentes
Quassnoi

47
Minha consulta: ALTER TABLE MYTABLECONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; Por favor, não use utf8_general_ci mais ;-)
Kapitein Witbaard

209

Estou contribuindo aqui, como o OP perguntou:

Como alterar o agrupamento de banco de dados, tabela, coluna?

A resposta selecionada indica apenas no nível da tabela.


Alterando todo o banco de dados:

ALTER DATABASE <database_name> CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Alterando-o por tabela:

ALTER TABLE <table_name> CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

A boa prática é alterá-lo no nível da tabela, assim como nas colunas. Mudar para uma coluna específica é para qualquer caso específico.

Alterando o agrupamento para uma coluna específica:

ALTER TABLE <table_name> MODIFY <column_name> VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

15
Este realmente responde a pergunta diretamente. Eu precisava disso, pois minhas alterações no nível da tabela NÃO estavam atualizando as colunas. Eu investigarei isso mais tarde; mas esta é a informação que me levou através dos tempos difíceis. Obrigado.
Parapluie

9
A melhor resposta para isso.
Jbi4dition

Sim, você precisa especificar o tipo de coluna. Aqui está um comando mágico para obter todos os tipos. Usando a edição de várias linhas, você pode gerar o comando para atualizar todas as colunas de uma vez, começando aqui:SELECT table_schema , table_name , column_name , COLLATION_NAME , COLUMN_TYPE FROM information_schema.columns WHERE collation_name != 'utf8_general_ci' AND table_schema not in ('information_schema','mysql', 'performance_schema','sys');
William Entriken

Para uma única coluna, você pode simplesmente: ALTER TABLE table_name CHANGE column_name VARCHAR (45) COLLATE utf8mb4_bin;
TomoMiha 24/04

68

Você pode executar um script php.

               <?php
                   $con = mysql_connect('localhost','user','password');
                   if(!$con) { echo "Cannot connect to the database ";die();}
                   mysql_select_db('dbname');
                   $result=mysql_query('show tables');
                   while($tables = mysql_fetch_array($result)) {
                            foreach ($tables as $key => $value) {
                             mysql_query("ALTER TABLE $value CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci");
                       }}
                   echo "The collation of your database has been successfully changed!";
                ?>

43

Para alterar o agrupamento de tabelas individualmente, você pode usar,

ALTER TABLE mytable CONVERT TO CHARACTER SET utf8

Para definir o agrupamento padrão para todo o banco de dados,

ALTER DATABASE  `databasename` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin

se não,

Vá para PhpMyAdmin-> Operações-> Agrupamento.

Lá você encontra a caixa de seleção que contém todos os agrupamentos existentes. Para que aqui você possa alterar seu agrupamento. Então aqui após a tabela do banco de dados seguirá esse agrupamento enquanto você cria uma nova coluna. Não há necessidade de selecionar agrupamento ao criar novas colunas.


Muito obrigado, isso foi útil
JoZ3 8/15/15

15

A consulta a seguir irá gerar consultas ALTER que alteram o agrupamento de todas as colunas apropriadas em todas as tabelas para um determinado tipo (utf8_general_ci no meu exemplo abaixo).

SELECT concat
        (
            'ALTER TABLE ', 
                t1.TABLE_SCHEMA, 
                '.', 
                t1.table_name, 
                ' MODIFY ', 
                t1.column_name, 
                ' ', 
                t1.data_type, 
                '(' , 
                    CHARACTER_MAXIMUM_LENGTH, 
                ')', 
                ' CHARACTER SET utf8 COLLATE utf8_general_ci;'
        )
from 
    information_schema.columns t1
where 
    t1.TABLE_SCHEMA like 'you_db_name_goes_here' AND
    t1.COLLATION_NAME IS NOT NULL AND
    t1.COLLATION_NAME NOT IN ('utf8_general_ci');

+1 Eu gosto mais desta resposta. Nem todo mundo tem PHP magicamente em algum lugar. Alguns usuários usam outras linguagens com o MySQL. Foi fácil rodar no MySQL Workbench, copiar as linhas e colar. Eu apenas fiz o passo extra para executar o acima para information_schema.tableseo código em concatALTER TABLE 'schema'.'table' CHARACTER SET = utf8mb4 , COLLATE = utf8mb4_bin ;
Pierre

1
Este erros para fora em (médio / longo) tipos de colunas de texto, que têm de ser limpas manualmente
stiebrs

11

Se você executar o phpMyAdmin >> selecione o banco de dados >> selecione a tabela >> vá para a guia "Operações" >> na seção "Opções da tabela" >>, você pode selecionar Agrupamento na lista suspensa >> e depois de pressionar {Ir} no Na parte superior da tela, você verá uma mensagem:

Sua consulta SQL foi executada com sucesso

e um script

ALTER TABLE `tableName` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci 

Mas isso NÃO mudará os agrupamentos das colunas existentes. Para fazer isso, você pode usar este script (este também veio do phpMyAdmin)

ALTER TABLE  `tableName` CHANGE  `Name`  `Name` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL


5

Basta executar este SQL para converter todas as tabelas do banco de dados de uma só vez. Mude seu COLLATION e databaseName para o que você precisa.

SELECT CONCAT("ALTER TABLE ", TABLE_SCHEMA, '.', TABLE_NAME," COLLATE utf8_general_ci;") AS    ExecuteTheString
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA="databaseName"
AND TABLE_TYPE="BASE TABLE";

4

Você pode alterar o CHARSET e COLLATION de todas as suas tabelas através do script PHP da seguinte maneira. Eu gosto da resposta da hkasera, mas o problema é que a consulta é executada duas vezes em cada tabela. Este código é quase o mesmo, exceto usando o MySqli em vez do mysql e a prevenção de consultas duplas. Se eu pudesse votar, teria votado na resposta da hkasera.

<?php
$conn1=new MySQLi("localhost","user","password","database");
if($conn1->connect_errno){
    echo mysqli_connect_error();
    exit;
}
$res=$conn1->query("show tables") or die($conn1->error);
while($tables=$res->fetch_array()){
    $conn1->query("ALTER TABLE $tables[0] CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci") or die($conn1->error);
}
echo "The collation of your database has been successfully changed!";

$res->free();
$conn1->close();

?>

Isso funcionou para mim perfeitamente, após a atualização para o Zabbix 5. Só para dizer que eu mudei o Charset e Agrupamento assim: CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin.
robe007

4

Você pode simplesmente adicionar este código ao arquivo de script

//Database Connection
$host = 'localhost';
$db_name = 'your_database_name';
$db_user =  'your_database_user_name';
$db_pass = 'your_database_user_password';

$con = mysql_connect($host,$db_user,$db_pass);

if(!$con) { echo "Cannot connect to the database ";die();}

  mysql_select_db($db_name);

  $result=mysql_query('show tables');

  while($tables = mysql_fetch_array($result)) {
    foreach ($tables as $key => $value) {
    mysql_query("ALTER TABLE $value CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci");
  }
}

echo "The collation of your database has been successfully changed!";

4

Fiquei surpreso ao saber e, portanto, tive que voltar aqui e relatar que o excelente e bem conservado script Interconnect / it SAFE SEARCH AND REPLACE ON DATABASE tem algumas opções para converter tabelas em utf8 / unicode e até converter em innodb . É um script comumente usado para migrar um site direcionado a banco de dados (Wordpress, Drupal, Joomla, etc) de um domínio para outro.

botões de script de interconexão


3

Eu li aqui, que você precisa converter cada tabela manualmente, não é verdade. Aqui está uma solução de como fazer isso com um procedimento armazenado:

DELIMITER $$

DROP PROCEDURE IF EXISTS changeCollation$$

-- character_set parameter could be 'utf8'
-- or 'latin1' or any other valid character set
CREATE PROCEDURE changeCollation(IN character_set VARCHAR(255))
BEGIN
DECLARE v_finished INTEGER DEFAULT 0;
DECLARE v_table_name varchar(255) DEFAULT "";
DECLARE v_message varchar(4000) DEFAULT "No records";

-- This will create a cursor that selects each table,
-- where the character set is not the one
-- that is defined in the parameter

DECLARE alter_cursor CURSOR FOR SELECT DISTINCT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE()
AND COLLATION_NAME NOT LIKE CONCAT(character_set, '_%');

-- This handler will set the value v_finished to 1
-- if there are no more rows

DECLARE CONTINUE HANDLER
FOR NOT FOUND SET v_finished = 1;

OPEN alter_cursor;

-- Start a loop to fetch each rows from the cursor
get_table: LOOP

-- Fetch the table names one by one
FETCH alter_cursor INTO v_table_name;

-- If there is no more record, then we have to skip
-- the commands inside the loop
IF v_finished = 1 THEN
LEAVE get_table;
END IF;

IF v_table_name != '' THEN

IF v_message = 'No records' THEN
SET v_message = '';
END IF;

-- This technic makes the trick, it prepares a statement
-- that is based on the v_table_name parameter and it means
-- that this one is different by each iteration inside the loop

SET @s = CONCAT('ALTER TABLE ',v_table_name,
' CONVERT TO CHARACTER SET ', character_set);
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET v_message = CONCAT('The table ', v_table_name ,
' was changed to the default collation of ', character_set,
'.\n', v_message);

SET v_table_name = '';

END IF;
-- Close the loop and the cursor
END LOOP get_table;
CLOSE alter_cursor;

-- Returns information about the altered tables or 'No records'
SELECT v_message;

END $$

DELIMITER ;

Após a criação do procedimento, chame-o simplesmente:

CALL changeCollation('utf8');

Para mais detalhes, leia este blog .


2

se você deseja atualizar o conjunto de caracteres padrão em um esquema:

 ALTER SCHEMA MYSCHEMA DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci;

1

Eu usei o seguinte script de shell. Ele pega o nome do banco de dados como parâmetro e converte todas as tabelas em outro conjunto de caracteres e agrupamento (fornecido por outros parâmetros ou valor padrão definido no script).

#!/bin/bash

# mycollate.sh <database> [<charset> <collation>]
# changes MySQL/MariaDB charset and collation for one database - all tables and
# all columns in all tables

DB="$1"
CHARSET="$2"
COLL="$3"

[ -n "$DB" ] || exit 1
[ -n "$CHARSET" ] || CHARSET="utf8mb4"
[ -n "$COLL" ] || COLL="utf8mb4_general_ci"

echo $DB
echo "ALTER DATABASE $DB CHARACTER SET $CHARSET COLLATE $COLL;" | mysql

echo "USE $DB; SHOW TABLES;" | mysql -s | (
    while read TABLE; do
        echo $DB.$TABLE
        echo "ALTER TABLE $TABLE CONVERT TO CHARACTER SET $CHARSET COLLATE $COLL;" | mysql $DB
    done
)

1

Minha solução é uma combinação de @Dzintars e @Quassnoi Answer.

SELECT CONCAT("ALTER TABLE ", TABLE_SCHEMA, '.', TABLE_NAME," CONVERT TO CHARACTER SET utf8mb4 ;") AS    ExecuteTheString
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA="<your-database>"
AND TABLE_TYPE="BASE TABLE";

Ao usar CONVERT TO, isso gera um script, que converte todas as tabelas da <your-database>codificação solicitada. Isso também altera a codificação de todas as colunas !


1

Melhor variante para gerar script SQL por solicitação de SQL. Isso não arruinará os padrões / nulos.

SELECT concat
    (
        'ALTER TABLE ', 
            t1.TABLE_SCHEMA, 
            '.', 
            t1.table_name, 
            ' MODIFY ', 
            t1.column_name, 
            ' ', 
            t1.column_type,
            ' CHARACTER SET utf8 COLLATE utf8_general_ci',
            if(t1.is_nullable='YES', ' NULL', ' NOT NULL'),
            if(t1.column_default is not null, concat(' DEFAULT \'', t1.column_default, '\''), ''),
            ';'
    )
from 
    information_schema.columns t1
where 
    t1.TABLE_SCHEMA like 'your_table_here' AND
    t1.COLLATION_NAME IS NOT NULL AND
    t1.COLLATION_NAME NOT IN ('utf8_general_ci');

0

Maneira rápida - exporte para o arquivo SQL, use a pesquisa e substitua para alterar o texto que você precisa alterar. Crie um novo banco de dados, importe os dados e renomeie o banco de dados antigo e o novo para o nome antigo.


0

Para alterar o agrupamento de todos os campos em todas as tabelas de um banco de dados de uma vez:

Eu estava apenas adicionando outro loop para os campos dentro das tabelas para a solução via Php antes mencionado. Isso ajudou, todos os campos nas tabelas também são convertidos.

<?php
$con = mysql_connect('localhost','user','pw');
if(!$con) { echo "Cannot connect to the database ";die();}
mysql_select_db('database_name');
$result=mysql_query('show tables');
while($tables = mysql_fetch_array($result)) {

foreach ($tables as $key => $table) {                   // for each table

    $sql = "ALTER TABLE $table CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci";
    echo "\n".$sql;
    mysql_query($sql);

    $sql = "show fields in ".$table." where type like 'varchar%' or type like 'char%' or type='text' or type='mediumtext';";
    $rs2=mysql_query($sql);
    while( $rw2 = mysql_fetch_array($rs2) ){            // for each field in table

        $sql = "ALTER TABLE `".$table."` CHANGE `".$rw2['Field']."` `".$rw2['Field']."` ".$rw2['Type']." CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;";
        echo "\n".$sql;
        mysql_query($sql);

    } 


}
}
echo "The collation of your database has been successfully changed!";

?>}

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.