web-dev-qa-db-ja.com

すべてのテーブルとフィールドをMYSQLのutf-8-bin照合に変更するスクリプト

データベース内のすべてのテーブルとフィールドのデフォルトの照合順序を変更するSQLまたはPHPスクリプトを実行できますか?

私は自分で1つ書くことができますが、これはこのようなサイトですぐに利用できるものでなければならないと思います。誰かが投稿する前に自分で考え出すことができたら、自分で投稿します。

56
user19302

注意してください!実際に別のエンコーディングとしてutfを保存している場合、実際に混乱する可能性があります。最初にバックアップします。次に、いくつかの標準的な方法を試してください。

たとえば http://www.cesspit.net/drupal/node/898http://www.hackszine.com/blog/archive/2007/05/mysql_database_migration_latin.html

すべてのテキストフィールドをバイナリに変換してから、varchar/textに戻す必要がありました。これは私のお尻を保存しました。

データはUTF8で、latin1として保存されていました。私がしたこと:

インデックスを削除します。フィールドをバイナリに変換します。 utf8-general ciに変換

LAMPを使用している場合は、dbを操作する前にset NAMESコマンドを追加することを忘れないでください。また、文字エンコードヘッダーを設定してください。

23
Buzz

(148のPHPではなく)1つのコマンドで実行できます。

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 &

コマンドラインを気に入るはずです...(mysql--userおよび--passwordオプションを使用する必要があるかもしれません)。

編集:外部キーの問題を回避するため、SET foreign_key_checks = 0;およびSET foreign_key_checks = 1;を追加

85

PhpMyAdminで2つのステップを実行するのは簡単だと思います。
ステップ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

ステップ2:
このクエリは、テーブルごとに1つずつ、クエリのリストを出力します。クエリのリストをコピーして、コマンドラインまたはPhpMyAdminのSQLタブに貼り付けて変更を加える必要があります。

39
Ivan

OK、このスレッドで言われたことを考慮してこれを書きました。助けてくれてありがとう、このスクリプトが他の人を助けることを願っています。私はその使用についての保証はありませんので、実行する前にバックアップしてください。 It shouldすべてのデータベースで動作します。それは私自身でうまくいきました。

編集:文字セット/照合先の変換先の変数を上部に追加しました。 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>";

?>
27
user19302

このPHPスニペットは、db内のすべてのテーブルの照合順序を変更します。( this site から取得します。)

<?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 />";
    }
}
?> 
13
Rich Adams

awkなしの@davidに基づくコマンドラインを使用する別のアプローチ

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

プリティファイド

  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
4
RameshVel

上記のスクリプトのより完全なバージョンは、次の場所にあります。

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

2
Dustin

上記のスクリプトでは、変換用に選択されたすべてのテーブル(SHOW TABLES)、しかし、テーブルを変換する前にテーブル照合をチェックするより便利で移植可能な方法。このクエリはそれを行います:

SELECT table_name
     , table_collation 
FROM information_schema.tables
1

文字セットと照合は同じものではありません。照合とは、文字列のソート方法に関する一連のルールです。文字セットは、文字の表現方法に関する一連のルールです。照合は文字セットに依存します。

1
troelskn

カスタムシェル collat​​edb を使用すると、動作するはずです:

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

例:

collatedb root 0000 myDatabase utf8_bin
0
Abdennour TOUMI

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
davewy

Windowsユーザー向け

@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スクリプト をダウンロードして簡単に実行できます。

0
Lost Koder

最速の方法は、phpmyadminとコンソール上のjQueryを使用することだと思います。

テーブルの構造に移動し、chrome/firefox開発者コンソールを開きます(通常はキーボードのF12):

  1. このコードを実行して、誤った文字セットを持つすべてのフィールドを選択し、変更を開始します。

    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();
        }
    });
    
  2. ページがロードされたら、コンソールでこのコードを使用して正しいエンコードを選択します。

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

  4. [操作]タブの[照合順序]フィールドでテーブルの文字セットを変更する

Phpmyadmin 4.0および4.4でテスト済みですが、すべての4.xバージョンで動作すると思います

0
Luca Camillo

コマンドラインアクセスまたはINFORMATION_SCHEMAを編集するアクセス権がない場合は、phpmyadminを使用してこれを簡単に行うことができます。

まず、ここで他の多くの答えのアドバイスを聞いてください-ここで本当に物事を台無しにすることができますので、バックアップを取ります。次に、バックアップのバックアップを作成します。また、データが変更先とは異なる方法でエンコードされている場合、これは機能しません。

開始する前に変更する必要がある問題のスキーマと文字エンコードの正確な名前を見つける必要があることに注意してください。

  1. データベースをSQLとしてエクスポートします。コピーを作成します。選択したテキストエディタで開きます
  2. 最初にスキーマを検索して置換します。たとえば、検索:latin1_swedish_ci、置換:tf8_general_ci
  3. 必要に応じて、文字エンコードを検索して置換します。たとえば、検索:latin1、置換:tf8
  4. 新しいテストデータベースを作成し、新しいSQLファイルをphpmyadminにアップロードします

これは非常に簡単な方法ですが、データのエンコードは変更されないため、特定の状況でのみ機能します。

0
squarecandy

IDEの複数選択機能を使用した単純な(ダム?:)ソリューション:

  1. 「SHOW TABLES;」を実行しますクエリとコピーの結果列(テーブル名)。
  2. 複数選択を開始し、「ALTER TABLE」を追加します。
  3. 末尾を複数選択し、「文字セットに変換utf8 COLLATE utf8_general_ci;」を追加します
  4. 作成されたクエリを実行します。
0
snp0k