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

200

O banco de dados está latin1_general_ciagora e desejo alterar o agrupamento para utf8mb4_general_ci.

Existe alguma configuração no PhpMyAdmin para alterar o agrupamento do banco de dados, tabela, coluna? Em vez de mudar um por um?

user158469
fonte
3
Veja isto para a resposta: stackoverflow.com/questions/5906585/…
Timo Huovinen

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.

Quassnoi
fonte
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;
Nabeel Ahmed
fonte
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!";
                ?>
hkasera
fonte
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.

jeeva
fonte
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');
Parampal Pooni
fonte
+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
Yevgeniy Afanasyev
fonte
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";
Dzintars
fonte
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();

?>
mtmehdi
fonte
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!";
Chandra Kumar
fonte
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

Adam Nofsinger
fonte
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 .

András Ottó
fonte
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;
Mircea Stanciu
fonte
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
)
Petr Stastny
fonte
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 !

Florian Kirmaier
fonte
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');
Max Ivanov
fonte
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.

kickoff3pm
fonte
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!";

?>}
Kim Michael
fonte