Comment changer le classement de la base de données, table, colonne?

201

La base de données est latin1_general_cimaintenant et je veux changer le classement enutf8mb4_general_ci .

Existe-t-il un paramètre dans PhpMyAdmin pour modifier le classement de la base de données, de la table, de la colonne? Plutôt que de changer un par un?

user158469
la source
3
Voir ceci pour la réponse: stackoverflow.com/questions/5906585/…
Timo Huovinen

Réponses:

258

Vous devez soit convertir chaque table individuellement:

ALTER TABLE mytable CONVERT TO CHARACTER SET utf8mb4 

(cela convertira également les colonnes), ou exportez la base de données avec latin1et réimportez-la avec utf8mb4.

Quassnoi
la source
15
Mais je veux changer le classement des colonnes. Cela ne changera que le classement de la table.
user158469
7
@rsensan: CONVERTmodifiera également le classement des colonnes.
Quassnoi
21
ALTER SCHEMA database DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
stormwild
8
@stormwild: cela n'affectera pas les tables existantes
Quassnoi
47
Ma requête: ALTER TABLE MYTABLECONVERT EN CARACTER SET SET utf8mb4 COLLATE utf8mb4_unicode_ci; Veuillez ne plus utiliser utf8_general_ci ;-)
Kapitein Witbaard
210

Je contribue ici, comme l'OP l'a demandé:

Comment changer le classement de la base de données, table, colonne?

La réponse sélectionnée l'indique simplement au niveau de la table.


Modification de la base de données à l'échelle:

ALTER DATABASE <database_name> CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Changer par table:

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

La bonne pratique consiste à le modifier au niveau de la table car il le modifiera également pour les colonnes. Changer pour une colonne spécifique est pour n'importe quel cas spécifique.

Modification du classement pour une colonne spécifique:

ALTER TABLE <table_name> MODIFY <column_name> VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Nabeel Ahmed
la source
15
Celui-ci répond en fait directement à la question. J'en avais besoin, car mes modifications au niveau de la table ne mettaient PAS à jour les colonnes. J'examinerai cela plus tard; mais ce sont les informations qui m'ont fait traverser les moments difficiles. Merci.
Parapluie
9
La meilleure réponse à cela.
jubi4dition
Oui, vous devez préciser le type de colonne. Voici une commande magique pour obtenir tous les types. En utilisant l'édition multi-ligne, vous pouvez générer la commande pour mettre à jour toutes les colonnes à la fois en commençant ici: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
Pour une seule colonne, vous pouvez simplement faire: ALTER TABLE nom_table CHANGE nom_colonne VARCHAR (45) COLLATE utf8mb4_bin;
TomoMiha
68

Vous pouvez exécuter un 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
la source
43

Pour modifier le classement des tables individuellement, vous pouvez utiliser,

ALTER TABLE mytable CONVERT TO CHARACTER SET utf8

Pour définir le classement par défaut pour toute la base de données,

ALTER DATABASE  `databasename` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin

ou sinon,

Goto PhpMyAdmin-> Operations-> Collation.

Là, vous trouverez la boîte de sélection qui contient tous les classements existants. Pour qu'ici vous puissiez changer votre classement. Donc, ici, après que la table de base de données suivra ce classement pendant que vous créez une nouvelle colonne. Pas besoin de sélectionner le classement lors de la création de nouvelles colonnes.

jeeva
la source
Merci beaucoup, cela a été utile
JoZ3
15

La requête suivante va générer des requêtes ALTER qui modifient le classement de toutes les colonnes appropriées dans toutes les tables en un certain type (utf8_general_ci dans mon exemple ci-dessous).

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
la source
+1 J'aime le plus cette réponse. Tout le monde n'a pas PHP comme par magie. Certains utilisent d'autres langages avec MySQL. C'était facile à exécuter dans MySQL Workbench, à copier les lignes et à coller. Je viens de faire l'étape supplémentaire pour exécuter ce qui précède information_schema.tableset le code en concatALTER TABLE 'schema'.'table' CHARACTER SET = utf8mb4 , COLLATE = utf8mb4_bin ;
Pierre
1
Cela bogue sur les types de colonne de texte (moyenne / longue), qui doivent être nettoyés manuellement
stiebrs
11

Si vous exécutez phpMyAdmin >> sélectionnez la base de données >> sélectionnez la table >> allez dans l'onglet "Opérations" >> dans la section "Options de la table" >> vous pouvez choisir le classement dans la liste déroulante >> et une fois que vous appuyez sur {Go} au en haut de l'écran, vous verrez un message:

Votre requête SQL a été exécutée avec succès

et un script

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

Mais cela ne changera PAS les classements des colonnes existantes. Pour ce faire, vous pouvez utiliser ce script (celui-ci provient également de phpMyAdmin)

ALTER TABLE  `tableName` CHANGE  `Name`  `Name` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
Yevgeniy Afanasyev
la source
5

Exécutez simplement ce SQL pour convertir toutes les tables de base de données à la fois. Modifiez votre COLLATION et databaseName en fonction de vos besoins.

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
la source
4

Vous pouvez modifier le CHARSET et la COLLATION de toutes vos tables via le script PHP comme suit. J'aime la réponse de hkasera mais le problème est que la requête s'exécute deux fois sur chaque table. Ce code est presque le même sauf en utilisant MySqli au lieu de mysql et la prévention des doubles requêtes. Si je pouvais voter, j'aurais voté la réponse de 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
la source
Cela a fonctionné pour moi parfaitement, après mise à niveau vers Zabbix 5. Juste pour dire que j'ai changé le jeu de caractères et Collation comme ceci: CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin.
robe007
4

Vous pouvez simplement ajouter ce code au fichier 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
la source
4

J'ai été surpris d'apprendre, et j'ai donc dû revenir ici et signaler, que l'excellent et bien entretenu Interconnect / it SAFE SEARCH AND REPLACE ON DATABASE script a quelques options pour convertir les tables en utf8 / unicode, et même pour convertir en innodb . Il s'agit d'un script couramment utilisé pour migrer un site Web basé sur une base de données (Wordpress, Drupal, Joomla, etc.) d'un domaine à un autre.

boutons de script d'interconnexion

Adam Nofsinger
la source
3

Je l'ai lu ici, que vous devez convertir chaque table manuellement, ce n'est pas vrai. Voici une solution pour le faire avec une procédure stockée:

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 ;

Une fois la procédure créée, appelez-la simplement:

CALL changeCollation('utf8');

Pour plus de détails, lisez ce blog .

András Ottó
la source
2

si vous souhaitez mettre à jour le jeu de caractères par défaut sur un schéma:

 ALTER SCHEMA MYSCHEMA DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci;
Mircea Stanciu
la source
1

J'ai utilisé le script shell suivant. Il prend le nom de la base de données comme paramètre et convertit toutes les tables en un autre jeu de caractères et classement (donné par un autre paramètre ou une valeur par défaut définie dans le 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
la source
1

Ma solution est une combinaison de @Dzintars et @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";

En utilisant CONVERT TO, cela génère un script, qui convertit toutes les tables de <your-database>votre encodage demandé. Cela modifie également l'encodage de chaque colonne !

Florian Kirmaier
la source
1

Meilleure variante pour générer un script SQL par requête SQL. Cela ne ruinera pas les valeurs par défaut / nulles.

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
la source
0

Un moyen rapide - exporter vers un fichier SQL, utiliser la recherche et remplacer pour changer le texte que vous devez changer. Créez une nouvelle base de données, importez les données, puis renommez l'ancienne base de données et la nouvelle en l'ancien nom.

coup d'envoi3pm
la source
0

Pour modifier le classement de tous les champs dans toutes les tables d'une base de données à la fois:

J'étais en train d'ajouter une autre boucle pour les champs dans les tables à la solution via Php avant mentionné. Cela a aidé, tous les champs des tables sont également convertis.

<?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
la source