Як змінити зіставлення бази даних, таблиці, стовпця?


201

База даних latin1_general_ciзараз є, і я хочу змінити зіставлення utf8mb4_general_ci.

Чи є налаштування в PhpMyAdmin для зміни зіставлення бази даних, таблиці, стовпця? Замість того, щоб змінювати одну за одною?


3
Дивіться цей відповідь: stackoverflow.com/questions/5906585 / ...
Тімо Huovinen

Відповіді:


260

Вам потрібно перетворити кожну таблицю окремо:

ALTER TABLE mytable CONVERT TO CHARACTER SET utf8mb4 

(це так само конвертуватиме стовпці) або експортувати базу даних latin1та імпортувати її назад utf8mb4.


15
Але я хочу змінити зіставлення стовпців. Це змінить лише порівняння таблиці ..
user158469

7
@rsensan: CONVERTтакож змінить зіставлення стовпців.
Quassnoi

21
ALTER SCHEMA database DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
stormwild

8
@stormwild: це не вплине на існуючі таблиці
Quassnoi

47
Мій запит: MYTABLEПОВЕРНУТЬСЯ ТАБЛИЧНОГО КОНВЕРТАЦІЇ НАСТРОЙКИ ХАРАКТЕРУ utf8mb4 COLLATE utf8mb4_unicode_ci; Будь ласка, більше не використовуйте utf8_general_ci ;-)
Kapitein Witbaard

213

Я вношу свій внесок тут, як просив ОП:

Як змінити зіставлення бази даних, таблиці, стовпця?

Вибрана відповідь просто констатує її на рівні таблиці.


Змінивши базу даних у широкому масштабі:

ALTER DATABASE <database_name> CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Змінюючи його за столом:

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

Доброю практикою є його зміна на рівні таблиці, оскільки вона також буде змінюватися для стовпців. Зміна конкретного стовпця стосується будь-якого конкретного випадку.

Зміна порівняння для певного стовпця:

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

15
Цей насправді відповідає безпосередньо на питання. Мені це було потрібно, оскільки мої зміни на рівні таблиці НЕ оновлювали стовпці. Я розслідую це пізніше; але це інформація, яка пережила мене у важкі часи. Дякую.
Parapluie

9
Найкраща відповідь на це.
jubi4dition

Так, вам потрібно специфікувати тип стовпця. Ось магічна команда отримати всі типи. Використовуючи багаторядкове редагування, ви можете створити команду для оновлення всіх стовпців одночасно, починаючи тут: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

Для одного стовпця ви можете просто зробити: ALTER TABLE table_name CHANGE Имя_ столбца VARCHAR (45) COLLATE utf8mb4_bin;
TomoMiha

68

Ви можете запустити скрипт 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

Щоб змінити зіставлення таблиць індивідуально, ви можете використовувати,

ALTER TABLE mytable CONVERT TO CHARACTER SET utf8

Щоб встановити порівняння за замовчуванням для всієї бази даних,

ALTER DATABASE  `databasename` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin

інакше,

Перейдіть на PhpMyAdmin-> Операції-> Збір.

Там ви знайдете поле вибору, яке містить усі наявні посилання. Так що тут ви можете змінити своє порівняння. Тож тут після таблиці баз даних слід це порівняння під час створення нового стовпця. Не потрібно вибирати зіставлення під час створення нових стовпців.


Велике спасибі, це було корисно
JoZ3

15

Наступний запит генерує ALTER-запити, які змінюють зіставлення для всіх відповідних стовпців у всіх таблицях на певний тип (utf8_general_ci в моєму прикладі нижче).

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 Мені найбільше подобається ця відповідь. Не у всіх є десь магічно PHP. Деякі користувачі використовують інші мови з MySQL. Це було легко запустити в MySQL Workbench, скопіювати рядки та вставити. Я щойно зробив додатковий крок для запуску вищезазначеного для information_schema.tablesта коду в ALTER TABLE 'schema'.'table' CHARACTER SET = utf8mb4 , COLLATE = utf8mb4_bin ;
П'єр

1
Ця помилка виводиться на (середні / довгі) типи стовпців тексту, які потрібно очистити вручну
stiebrs

11

Якщо ви запускаєте phpMyAdmin >> виберіть базу даних >> виберіть таблицю >>, перейдіть на вкладку "Операції" >> у розділі "Параметри таблиці" >>, ви можете вибрати Збір зі спадного списку >> та натиснувши кнопку {Go} у вікні вгорі екрана ви побачите повідомлення:

Ваш запит SQL успішно виконаний

і сценарій

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

Але це НЕ буде змінювати порівняння існуючих стовпців. Для цього ви можете скористатися цим сценарієм (цей також походить від phpMyAdmin)

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


5

Просто запустіть цей SQL, щоб перетворити всі таблиці баз даних одночасно. Змініть COLLATION і ім'я бази даних на те, що вам потрібно.

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

Ви можете змінити CHARSET і КОЛЯЦІЮ всіх своїх таблиць за допомогою PHP-скрипту наступним чином. Мені подобається відповідь hkasera, але проблема в тому, що запит виконується двічі на кожній таблиці. Цей код майже той самий, за винятком використання MySqli замість mysql та запобігання подвійного запиту. Якби я міг проголосувати, я би проголосував відповідь хкасери.

<?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();

?>

Це працює для мене ідеальним, після поновлення до Zabbix 5. Просто щоб сказати , що я змінив Charset і параметри сортування , як це: CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin.
robe007

4

Ви можете просто додати цей код до файлу сценарію

//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

Я був здивований, дізнавшись, і тому мені довелося повертатися сюди і повідомляти, що відмінний і доглянутий сценарій взаємозв’язку / БЕЗПЕЧЕНОГО ПОШУКУ ТА ЗАМІНИ НА ДАТАБАЗУ має деякі варіанти перетворення таблиць у utf8 / unicode і навіть для перетворення в innodb . Це сценарій, який зазвичай використовується для переміщення веб-сайту, керованого базами даних (Wordpress, Drupal, Joomla тощо) з одного домену в інший.

з'єднати кнопки сценарію


3

Я прочитав тут, що вам потрібно перетворити кожну таблицю вручну, це неправда. Ось рішення, як це зробити зі збереженою процедурою:

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 ;

Після створення процедури зателефонуйте просто:

CALL changeCollation('utf8');

Детальніше читайте це блог .


2

якщо ви хочете оновити схему за замовчуванням на схемі:

 ALTER SCHEMA MYSCHEMA DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci;

1

Я використовував наступний скрипт оболонки. Він приймає ім'я бази даних як параметр і перетворює всі таблиці в іншу діаграму та порівняння (задані іншими параметрами або значенням за замовчуванням, визначеними в сценарії).

#!/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

Моє рішення - це поєднання @Dzintars та @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";

Використовуючи CONVERT TOце, створюється сценарій, який перетворює всі таблиці <your-database>в потрібне кодування. Це також змінює кодування кожного стовпця !


1

Кращий варіант для створення SQL-скрипту за запитом SQL. Це не зіпсує параметри / нулі.

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

Швидкий спосіб - експортуйте у файл SQL, використовуйте пошук та заміну, щоб змінити текст, який потрібно змінити. Створіть нову базу даних, імпортуйте дані, а потім перейменуйте стару базу даних та нову на стару назву.


0

Щоб змінити зіставлення всіх полів у всіх таблицях бази даних відразу:

Я просто додавав ще один цикл для полів у таблицях до рішення через Php, раніше згаданий. Це допомогло, всі поля в таблицях також перетворені.

<?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!";

?>}

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.