Вопрос по sql, collation, mysql, utf-8, php – Скрипт для изменения всех таблиц и полей для сопоставления utf-8-bin в MYSQL

56

Есть лиSQL или жеPHP скрипт, который я могу запустить, который изменит параметры сортировки по умолчанию во всех таблицах и полях в базе данных?

Я могу написать сам, но я думаю, что это должно быть легко доступно на таком сайте, как этот. Если я сам смогу придумать один, прежде чем кто-то его опубликует, я сам это опубликую.

Click here for script and follow the steps Chandra Kumar

Ваш Ответ

16   ответов
0

с которого я начал работать над приведенным ниже решением.

Я выпустил плагин для WordPress, не осознавая, что WordPress не устанавливает параметры сортировки автоматически. Так что многие люди, использующие плагин, в конечном итогеlatin1_swedish_ci когда это должно было бытьutf8_general_ci.

Вот код, который я добавил в плагин для обнаруженияlatin1_swedish_ci сопоставить и изменить его наutf8_general_ci.

Протестируйте этот код, прежде чем использовать его в своем плагине!

// list the names of your wordpress plugin database tables (without db prefix)
$tables_to_check = array(
    'social_message',
    'social_facebook',
    'social_facebook_message',
    'social_facebook_page',
    'social_google',
    'social_google_mesage',
    'social_twitter',
    'social_twitter_message',
);
// choose the collate to search for and replace:
$convert_fields_collate_from = 'latin1_swedish_ci';
$convert_fields_collate_to = 'utf8_general_ci';
$convert_tables_character_set_to = 'utf8';
$show_debug_messages = false;
global $wpdb;
$wpdb->show_errors();
foreach($tables_to_check as $table) {
    $table = $wpdb->prefix . $table;
    $indicies = $wpdb->get_results(  "SHOW INDEX FROM `$table`", ARRAY_A );
    $results = $wpdb->get_results( "SHOW FULL COLUMNS FROM `$table`" , ARRAY_A );
    foreach($results as $result){
        if($show_debug_messages)echo "Checking field ".$result['Field'] ." with collat: ".$result['Collation']."\n";
        if(isset($result['Field']) && $result['Field'] && isset($result['Collation']) && $result['Collation'] == $convert_fields_collate_from){
            if($show_debug_messages)echo "Table: $table - Converting field " .$result['Field'] ." - " .$result['Type']." - from $convert_fields_collate_from to $convert_fields_collate_to \n";
            // found a field to convert. check if there's an index on this field.
            // we have to remove index before converting field to binary.
            $is_there_an_index = false;
            foreach($indicies as $index){
                if ( isset($index['Column_name']) && $index['Column_name'] == $result['Field']){
                    // there's an index on this column! store it for adding later on.
                    $is_there_an_index = $index;
                    $wpdb->query( $wpdb->prepare( "ALTER TABLE `%s` DROP INDEX %s", $table, $index['Key_name']) );
                    if($show_debug_messages)echo "Dropped index ".$index['Key_name']." before converting field.. \n";
                    break;
                }
            }
            $set = false;

            if ( preg_match( "/^varchar\((\d+)\)$/i", $result['Type'], $mat ) ) {
                $wpdb->query( "ALTER TABLE `{$table}` MODIFY `{$result['Field']}` VARBINARY({$mat[1]})" );
                $wpdb->query( "ALTER TABLE `{$table}` MODIFY `{$result['Field']}` VARCHAR({$mat[1]}) CHARACTER SET {$convert_tables_character_set_to} COLLATE {$convert_fields_collate_to}" );
                $set = true;
            } else if ( !strcasecmp( $result['Type'], "CHAR" ) ) {
                $wpdb->query( "ALTER TABLE `{$table}` MODIFY `{$result['Field']}` BINARY(1)" );
                $wpdb->query( "ALTER TABLE `{$table}` MODIFY `{$result['Field']}` VARCHAR(1) CHARACTER SET {$convert_tables_character_set_to} COLLATE {$convert_fields_collate_to}" );
                $set = true;
            } else if ( !strcasecmp( $result['Type'], "TINYTEXT" ) ) {
                $wpdb->query( "ALTER TABLE `{$table}` MODIFY `{$result['Field']}` TINYBLOB" );
                $wpdb->query( "ALTER TABLE `{$table}` MODIFY `{$result['Field']}` TINYTEXT CHARACTER SET {$convert_tables_character_set_to} COLLATE {$convert_fields_collate_to}" );
                $set = true;
            } else if ( !strcasecmp( $result['Type'], "MEDIUMTEXT" ) ) {
                $wpdb->query( "ALTER TABLE `{$table}` MODIFY `{$result['Field']}` MEDIUMBLOB" );
                $wpdb->query( "ALTER TABLE `{$table}` MODIFY `{$result['Field']}` MEDIUMTEXT CHARACTER SET {$convert_tables_character_set_to} COLLATE {$convert_fields_collate_to}" );
                $set = true;
            } else if ( !strcasecmp( $result['Type'], "LONGTEXT" ) ) {
                $wpdb->query( "ALTER TABLE `{$table}` MODIFY `{$result['Field']}` LONGBLOB" );
                $wpdb->query( "ALTER TABLE `{$table}` MODIFY `{$result['Field']}` LONGTEXT CHARACTER SET {$convert_tables_character_set_to} COLLATE {$convert_fields_collate_to}" );
                $set = true;
            } else if ( !strcasecmp( $result['Type'], "TEXT" ) ) {
                $wpdb->query( "ALTER TABLE `{$table}` MODIFY `{$result['Field']}` BLOB" );
                $wpdb->query( "ALTER TABLE `{$table}` MODIFY `{$result['Field']}` TEXT CHARACTER SET {$convert_tables_character_set_to} COLLATE {$convert_fields_collate_to}" );
                $set = true;
            }else{
                if($show_debug_messages)echo "Failed to change field - unsupported type: ".$result['Type']."\n";
            }
            if($set){
                if($show_debug_messages)echo "Altered field success! \n";
                $wpdb->query( "ALTER TABLE `$table` MODIFY {$result['Field']} COLLATE $convert_fields_collate_to" );
            }
            if($is_there_an_index !== false){
                // add the index back.
                if ( !$is_there_an_index["Non_unique"] ) {
                    $wpdb->query( "CREATE UNIQUE INDEX `{$is_there_an_index['Key_name']}` ON `{$table}` ({$is_there_an_index['Column_name']})", $is_there_an_index['Key_name'], $table, $is_there_an_index['Column_name'] );
                } else {
                    $wpdb->query( "CREATE UNIQUE INDEX `{$is_there_an_index['Key_name']}` ON `{$table}` ({$is_there_an_index['Column_name']})", $is_there_an_index['Key_name'], $table, $is_there_an_index['Column_name'] );
                }
            }
        }
    }
    // set default collate
    $wpdb->query( "ALTER TABLE `{$table}` DEFAULT CHARACTER SET {$convert_tables_character_set_to} COLLATE {$convert_fields_collate_to}" );
    if($show_debug_messages)echo "Finished with table $table \n";
}
$wpdb->hide_errors();
2

Более полную версию скрипта выше можно найти здесь:

http://www.zen-cart.com/index.php?main_page=product_contrib_info&products_id=1937

Пожалуйста, оставьте любой отзыв об этом вкладе здесь:http://www.zen-cart.com/forum/showthread.php?p=1034214

Спасибо Дастин! Скрипт Zen-Cart (версия) - это именно то, что я искал. Он правильно обрабатывает многопольные индексы / уникальные индексы. Круто, это экономит мне много времени и сил.
Пример № 1, почему ссылки только ответы являются плохими.
0

что самый быстрый способ - использовать phpmyadmin и немного jQuery на консоли.

Перейдите к структуре таблицы и откройте консоль разработчика Chrome / Firefox (обычно F12 на клавиатуре):

run this code to select all fields with incorrect charset and start modify:

var elems = $('dfn'); var lastID = elems.length - 1;
elems.each(function(i) {
    if ($(this).html() != 'utf8_general_ci') { 
       $('input:checkbox', $('td', $(this).parent().parent()).first()).attr('checked','checked');
    }       

    if (i == lastID) {
        $("button[name='submit_mult'][value='change']").click();
    }
});

when page is loaded use this code on console to select correct encoding:

$("select[name*='field_collation']" ).val('utf8_general_ci');

save

change the table's charset on "Collation" field on "Operation" tab

Проверено на phpmyadmin 4.0 и 4.4, но я думаю, что работает на всех версиях 4.x

0

Вот простой способ сделать это с помощью просто phpmyadmin, если у вас нет доступа к командной строке или доступа для редактирования INFORMATION_SCHEMA.

Во-первых, прислушайтесь к советам многих других ответов здесь - вы действительно можете все испортить, поэтому сделайте резервную копию. Теперь сделайте резервную копию вашей резервной копии. Также это вряд ли сработает, если ваши данные закодированы не так, как вы их изменяете.

Обратите внимание, что вам нужно будет найти точные имена нарушающей схемы и кодировки символов, которые вы должны изменить перед запуском.

  1. Export the database as SQL; Make a copy; Open it in a text editor of your choice
  2. Find and Replace the schema first, for example - find: latin1_swedish_ci, replace: utf8_general_ci
  3. Find and Replace the character encodings if you need to, for example - find: latin1, replace: utf8
  4. Create a new test database and upload your new SQL file into phpmyadmin

Это очень простой способ сделать это, но, опять же, это не изменит кодировку ваших данных, поэтому он будет работать только при определенных обстоятельствах.

1

SHOW TABLES), но более удобный и портативный способ проверки сопоставления таблиц перед преобразованием таблицы. Этот запрос делает это:

SELECT table_name
     , table_collation 
FROM information_schema.tables
1

Charset и сопоставление - это не одно и то же. Сортировка - это набор правил сортировки строк. Кодировка - это набор правил представления символов. Сортировка зависит от кодировки.

14

Этот фрагмент PHP изменит параметры сортировки для всех таблиц в БД. (Взято изэтот сайт.)

<?php
// your connection
mysql_connect("localhost","root","***");
mysql_select_db("db1");

// convert code
$res = mysql_query("SHOW TABLES");
while ($row = mysql_fetch_array($res))
{
    foreach ($row as $key => $table)
    {
        mysql_query("ALTER TABLE " . $table . " CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci");
        echo $key . " =&gt; " . $table . " CONVERTED<br />";
    }
}
?> 
После того, как я запустил его на своей базе данных, когда я пытаюсь увидеть структуру каждой моей таблицы, я вижу: # 126 - Неверный файл ключа для таблицы & apos; /tmp/#sql_321_0.MYI&apos ;; попробуй починить
0

Я обновил ответ nlaq для работы с PHP7 и для правильной обработки многоколоночных индексов, двоичных данных (например,latin1_bin) и т. д. и немного почистил код. Это единственный код, который я нашел / попробовал, который успешно перенес мою базу данных из latin1 в utf8.

<?php

/////////// BEGIN CONFIG ////////////////////

$username = "";
$password = "";
$db = "";
$host = "";

$target_charset = "utf8";
$target_collation = "utf8_unicode_ci";
$target_bin_collation = "utf8_bin";

///////////  END CONFIG  ////////////////////

function MySQLSafeQuery($conn, $query) {
    $res = mysqli_query($conn, $query);
    if (mysqli_errno($conn)) {
        echo "<b>Mysql Error: " . mysqli_error($conn) . "</b>\n";
        echo "<span>This query caused the above error: <i>" . $query . "</i></span>\n";
    }
    return $res;
}

function binary_typename($type) {
    $mysql_type_to_binary_type_map = array(
        "VARCHAR" => "VARBINARY",
        "CHAR" => "BINARY(1)",
        "TINYTEXT" => "TINYBLOB",
        "MEDIUMTEXT" => "MEDIUMBLOB",
        "LONGTEXT" => "LONGBLOB",
        "TEXT" => "BLOB"
    );

    $typename = "";
    if (preg_match("/^varchar\((\d+)\)$/i", $type, $mat))
        $typename = $mysql_type_to_binary_type_map["VARCHAR"] . "(" . (2*$mat[1]) . ")";
    else if (!strcasecmp($type, "CHAR"))
        $typename = $mysql_type_to_binary_type_map["CHAR"] . "(1)";
    else if (array_key_exists(strtoupper($type), $mysql_type_to_binary_type_map))
        $typename = $mysql_type_to_binary_type_map[strtoupper($type)];
    return $typename;
}

echo "<pre>";

// Connect to database
$conn = mysqli_connect($host, $username, $password);
mysqli_select_db($conn, $db);

// Get list of tables
$tabs = array();
$query = "SHOW TABLES";
$res = MySQLSafeQuery($conn, $query);
while (($row = mysqli_fetch_row($res)) != null)
    $tabs[] = $row[0];

// Now fix tables
foreach ($tabs as $tab) {
    $res = MySQLSafeQuery($conn, "SHOW INDEX FROM `{$tab}`");
    $indicies = array();

    while (($row = mysqli_fetch_array($res)) != null) {
        if ($row[2] != "PRIMARY") {
            $append = true;
            foreach ($indicies as $index) {
                if ($index["name"] == $row[2]) {
                    $index["col"][] = $row[4];
                    $append = false;
                }
            }
            if($append)
                $indicies[] = array("name" => $row[2], "unique" => !($row[1] == "1"), "col" => array($row[4]));
        }
    }

    foreach ($indicies as $index) {
        MySQLSafeQuery($conn, "ALTER TABLE `{$tab}` DROP INDEX `{$index["name"]}`");
        echo "Dropped index {$index["name"]}. Unique: {$index["unique"]}\n";
    }

    $res = MySQLSafeQuery($conn, "SHOW FULL COLUMNS FROM `{$tab}`");
    while (($row = mysqli_fetch_array($res)) != null) {
        $name = $row[0];
        $type = $row[1];
        $current_collation = $row[2];
        $target_collation_bak = $target_collation;
        if(!strcasecmp($current_collation, "latin1_bin"))
            $target_collation = $target_bin_collation;
        $set = false;
        $binary_typename = binary_typename($type);
        if ($binary_typename != "") {
            MySQLSafeQuery($conn, "ALTER TABLE `{$tab}` MODIFY `{$name}` {$binary_typename}");
            MySQLSafeQuery($conn, "ALTER TABLE `{$tab}` MODIFY `{$name}` {$type} CHARACTER SET '{$target_charset}' COLLATE '{$target_collation}'");
            $set = true;
            echo "Altered field {$name} on {$tab} from type {$type}\n";
        }
        $target_collation = $target_collation_bak;
    }

    // Rebuild indicies
    foreach ($indicies as $index) {
         // Handle multi-column indices
         $joined_col_str = "";
         foreach ($index["col"] as $col)
             $joined_col_str = $joined_col_str . ", `" . $col . "`";
         $joined_col_str = substr($joined_col_str, 2);

         $query = "";
         if ($index["unique"])
             $query = "CREATE UNIQUE INDEX `{$index["name"]}` ON `{$tab}` ({$joined_col_str})";
         else
             $query = "CREATE INDEX `{$index["name"]}` ON `{$tab}` ({$joined_col_str})";
         MySQLSafeQuery($conn, $query);

        echo "Created index {$index["name"]} on {$tab}. Unique: {$index["unique"]}\n";
    }

    // Set default character set and collation for table
    MySQLSafeQuery($conn, "ALTER TABLE `{$tab}`  DEFAULT CHARACTER SET '{$target_charset}' COLLATE '{$target_collation}'");
}

// Set default character set and collation for database
MySQLSafeQuery($conn, "ALTER DATABASE `{$db}` DEFAULT CHARACTER SET '{$target_charset}' COLLATE '{$target_collation}'");

mysqli_close($conn);
echo "</pre>";

?>
0

For Windows Users

В дополнение к ответу @davidwinterbottom, Пользователи Windows могут использовать команду ниже:

mysql.exe --database=[database] -u [user] -p[password] -B -N -e "SHOW TABLES" \
| awk.exe '{print "SET foreign_key_checks = 0; ALTER TABLE", $1, "CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci; SET foreign_key_checks = 1; "}' \
| mysql.exe -u [user] -p[password] --database=[database] &

Замените заполнители [база данных], [пользователь] и [пароль] фактическими значениями.

Git-bash пользователи могут скачать этоскрипт bash и запустить его легко.

24

Быть осторожен! Если вы на самом деле храните UTF в качестве другой кодировки, у вас может быть настоящий беспорядок. Сделай резервную копию сначала. Затем попробуйте некоторые из стандартных методов:

например http://www.cesspit.net/drupal/node/898 http://www.hackszine.com/blog/archive/2007/05/mysql_database_migration_latin.html

Мне пришлось прибегнуть к преобразованию всех текстовых полей в двоичные, а затем обратно в varchar / text. Это спасло мою задницу.

У меня были данные UTF8, хранящиеся как latin1. Что я сделал:

Падение индексов. Конвертировать поля в двоичные файлы Конвертировать в utf8-general ci

Если вы используете LAMP, не забудьте добавить команду set NAMES перед взаимодействием с db и убедитесь, что вы установили заголовки кодировки символов.

0

Простое (тупое? :) решение с использованием функции множественного выбора вашей IDE:

  1. run "SHOW TABLES;" query and copy results column (table names).
  2. multi-select beginnings and add "ALTER TABLE ".
  3. multi-select endings and add " CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;"
  4. run created queries.
0

collatedb, он должен работать :

collatedb <username> <password> <database> <collation>

Пример :

collatedb root 0000 myDatabase utf8_bin
27

Хорошо, я написал это с учетом того, что было сказано в этой теме. Спасибо за помощь, и я надеюсь, что этот скрипт поможет другим. У меня нет никаких гарантий на его использование, поэтому ПОЖАЛУЙСТА, BACKUP, прежде чем запускать его. Этоshould работа со всеми базами данных; и это прекрасно сработало само по себе.

РЕДАКТИРОВАТЬ: Вверху добавлены переменные, для которых нужно конвертировать charset / collate. EDIT2: изменяет базу данных и таблицы; кодировка / сопоставление по умолчанию

<?php

function MysqlError()
{
    if (mysql_errno())
    {
        echo "<b>Mysql Error: " . mysql_error() . "</b>\n";
    }
}

$username = "root";
$password = "";
$db = "database";
$host = "localhost";

$target_charset = "utf8";
$target_collate = "utf8_general_ci";

echo "<pre>";

$conn = mysql_connect($host, $username, $password);
mysql_select_db($db, $conn);

$tabs = array();
$res = mysql_query("SHOW TABLES");
MysqlError();
while (($row = mysql_fetch_row($res)) != null)
{
    $tabs[] = $row[0];
}

// now, fix tables
foreach ($tabs as $tab)
{
    $res = mysql_query("show index from {$tab}");
    MysqlError();
    $indicies = array();

    while (($row = mysql_fetch_array($res)) != null)
    {
        if ($row[2] != "PRIMARY")
        {
            $indicies[] = array("name" => $row[2], "unique" => !($row[1] == "1"), "col" => $row[4]);
            mysql_query("ALTER TABLE {$tab} DROP INDEX {$row[2]}");
            MysqlError();
            echo "Dropped index {$row[2]}. Unique: {$row[1]}\n";
        }
    }

    $res = mysql_query("DESCRIBE {$tab}");
    MysqlError();
    while (($row = mysql_fetch_array($res)) != null)
    {
        $name = $row[0];
        $type = $row[1];
        $set = false;
        if (preg_match("/^varchar\((\d+)\)$/i", $type, $mat))
        {
            $size = $mat[1];
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} VARBINARY({$size})");
            MysqlError();
         ,   mysql_query("ALTER TABLE {$tab} MODIFY {$name} VARCHAR({$size}) CHARACTER SET {$target_charset}");
            MysqlError();
            $set = true;

            echo "Altered field {$name} on {$tab} from type {$type}\n";
        }
        else if (!strcasecmp($type, "CHAR"))
        {
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} BINARY(1)");
            MysqlError();
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} VARCHAR(1) CHARACTER SET {$target_charset}");
            MysqlError();
            $set = true;

            echo "Altered field {$name} on {$tab} from type {$type}\n";
        }
        else if (!strcasecmp($type, "TINYTEXT"))
        {
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} TINYBLOB");
            MysqlError();
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} TINYTEXT CHARACTER SET {$target_charset}");
            MysqlError();
            $set = true;

            echo "Altered field {$name} on {$tab} from type {$type}\n";
        }
        else if (!strcasecmp($type, "MEDIUMTEXT"))
        {
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} MEDIUMBLOB");
            MysqlError();
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} MEDIUMTEXT CHARACTER SET {$target_charset}");
            MysqlError();
            $set = true;

            echo "Altered field {$name} on {$tab} from type {$type}\n";
        }
        else if (!strcasecmp($type, "LONGTEXT"))
        {
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} LONGBLOB");
            MysqlError();
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} LONGTEXT CHARACTER SET {$target_charset}");
            MysqlError();
            $set = true;

            echo "Altered field {$name} on {$tab} from type {$type}\n";
        }
        else if (!strcasecmp($type, "TEXT"))
        {
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} BLOB");
            MysqlError();
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} TEXT CHARACTER SET {$target_charset}");
            MysqlError();
            $set = true;

            echo "Altered field {$name} on {$tab} from type {$type}\n";
        }

        if ($set)
            mysql_query("ALTER TABLE {$tab} MODIFY {$name} COLLATE {$target_collate}");
    }

    // re-build indicies..
    foreach ($indicies as $index)
    {
        if ($index["unique"])
        {
            mysql_query("CREATE UNIQUE INDEX {$index["name"]} ON {$tab} ({$index["col"]})");
            MysqlError();
        }
        else
        {
            mysql_query("CREATE INDEX {$index["name"]} ON {$tab} ({$index["col"]})");
            MysqlError();
        }

        echo "Created index {$index["name"]} on {$tab}. Unique: {$index["unique"]}\n";
    }

    // set default collate
    mysql_query("ALTER TABLE {$tab}  DEFAULT CHARACTER SET {$target_charset} COLLATE {$target_collate}");
}

// set database charset
mysql_query("ALTER DATABASE {$db} DEFAULT CHARACTER SET {$target_charset} COLLATE {$target_collate}");

mysql_close($conn);
echo "</pre>";

?>
Внимание: глядя на исходный код, мне кажется, что этот скрипт не создает заново многоколоночные уникальные индексы, он просто удаляет их.
Ага; Все идет нормально. Я применял его один за другим в своих базах данных и пока без потери данных. nlaq
Единственная проблема заключается в том, что он удаляет весь ваш многоколонный индекс. По крайней мере, он показывает журнал, позволяющий узнать, какие из них были сброшены!
Очень полезная отправная точка! Мой ответ обновляет это для обработки многоколоночных индексов, двоичных сопоставлений и т. Д. И немного очищен.
Великий пост! Кто-нибудь изменял этот скрипт для обработки «многоколоночных уникальных индексов»? Это так, пожалуйста, напишите или напишите мне на gmail - jjwdesign. Спасибо джефф
85

Может быть сделано одной командой (вместо 148 PHP):

mysql --database=dbname -B -N -e "SHOW TABLES" \
| awk '{print "SET foreign_key_checks = 0; ALTER TABLE", $1, "CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci; SET foreign_key_checks = 1; "}' \
| mysql --database=dbname &

Вы должны любить командную строку ... (Возможно, вам придется использовать--user а также--password варианты дляmysql).

РЕДАКТИРОВАТЬ: чтобы избежать проблем с внешними ключами, добавилSET foreign_key_checks = 0; а такжеSET foreign_key_checks = 1;

это приведет к ошибке, если у вас есть представления в вашей базе данных. исключить представления заменить"SHOW TABLES" с"SHOW FULL TABLES WHERE Table_Type = 'BASE TABLE'", Требуется MySQL 5.0.2 или выше.
отлично, у меня это сработало ... некоторые проблемы с кодировками символов со значениями в полях, к счастью, моя база данных пока мала
Вы должны знать, что такой подход может вызвать проблемы. Во-первых, после выполнения этого все столбцы latin1, которые были TEXT, теперь будут MEDIUMTEXT. В результате вы можете молча потерять / усечь данные. Ссылаться на:codex.wordpress.org/Converting_Database_Character_Sets а такжеmysqlperformanceblog.com/2009/03/17/converting-character-sets для более подробной информации.
@ ДэвидWinterbottom для этого ответа у вас должна быть статуя установлена в вашу честь в вашем родном городе.
Точный код для командной строки, на которую я получаю ответ:mysql -u root -ppassword --database=dbname -B -N -e "SHOW TABLES" | awk '{print "SET foreign_key_checks = 0; ALTER TABLE", $1, "CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci; SET foreign_key_checks = 1; "}' | mysql -u root -ppassword --database=dbname &
39

Я думаю, что это легко сделать в два этапа в PhpMyAdmin.
Step 1:

SELECT CONCAT('ALTER TABLE `', t.`TABLE_SCHEMA`, '`.`', t.`TABLE_NAME`,
 '` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;') as stmt 
FROM `information_schema`.`TABLES` t
WHERE 1
AND t.`TABLE_SCHEMA` = 'database_name'
ORDER BY 1

Step 2:
Этот запрос выведет список запросов, по одному для каждой таблицы. Вы должны скопировать список запросов и вставить их в командную строку или на вкладку SQL PhpMyAdmin для внесения изменений.

Пожалуйста, предоставьте ссылки на сайты на английском языке или лучше, предоставьте полный ответ и используйте ссылки только в качестве ссылки!
Работает отлично! Спасибо, это очень умный и хитрый способ выполнить групповую смену параметров сортировки только с помощью mysql или phpMyAdmin. Это очень полезно при установке Redmine, где параметры сортировки по умолчанию - latin1 вместо utf8.
Обратите внимание, что этот запрос НЕ внесет никаких изменений в вашу БД. Он выведет список запросов - по одному для каждой таблицы. Поэтому вам нужно скопировать список запросов и вставить их в командную строку или на вкладку SQL PHPMyAdmin для внесения изменений.
4

Другой подход, использующий командную строку, основан на @avid, безawk

for t in $(mysql --user=root --password=admin  --database=DBNAME -e "show tables";);do echo "Altering" $t;mysql --user=root --password=admin --database=DBNAME -e "ALTER TABLE $t CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;";done

prettified

  for t in $(mysql --user=root --password=admin  --database=DBNAME -e "show tables";);
    do 
       echo "Altering" $t;
       mysql --user=root --password=admin --database=DBNAME -e "ALTER TABLE $t CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;";
    done
Вы должны добавить--silent к первомуmysql команда, чтобы избежать ошибки для первой строки, котораяTables_in_xxx, Кроме того, экранирование имен таблиц позволит избежать ошибки в таблицах, использующих зарезервированное имя (например,Order).

Похожие вопросы