256

数据库latin1_general_ci现在是,我想将排序规则更改为utf8mb4_general_ci.

PhpMyAdmin 中是否有任何设置来更改数据库、表、列的排序规则?而不是一一改变?

4

21 回答 21

324

正如 OP 所要求的,我在这里做出贡献:

如何更改数据库、表、列的排序规则?

选定的答案只是在表格级别说明它。


在数据库范围内更改它:

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;
于 2016-08-17T11:51:05.107 回答
292

您需要单独转换每个表:

ALTER TABLE mytable CONVERT TO CHARACTER SET utf8mb4 

(这也将转换列),或者导出数据库latin1并使用utf8mb4.

于 2009-08-18T14:14:28.070 回答
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!";
                ?>
于 2012-10-04T06:23:05.400 回答
48

要单独更改表格的排序规则,您可以使用,

ALTER TABLE mytable CONVERT TO CHARACTER SET utf8

要为整个数据库设置默认排序规则,

ALTER DATABASE  `databasename` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin

要不然,

转到PhpMyAdmin-> 操作-> 排序。

在那里您可以找到包含所有现有排序规则的选择框。这样您就可以在此处更改排序规则。因此,在创建新列时,数据库表将遵循此排序规则。创建新列时无需选择排序规则。

于 2013-01-16T08:05:49.150 回答
23

以下查询将生成 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');
于 2016-03-14T01:26:29.187 回答
11

如果你运行 phpMyAdmin >> 选择数据库 >> 选择表 >> 转到 "操作" 选项卡 >> 在 "表选项" 部分 >> 你可以从下拉列表中选择排序规则 >> 并且一旦你在您将在屏幕顶部看到一条消息:

您的 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
于 2015-09-04T04:34:26.600 回答
9

您可以在多个级别设置默认排序规则:

http://dev.mysql.com/doc/refman/5.0/en/charset-syntax.html

1) 客户端 2) 服务器默认 3) 数据库默认 4) 表默认 5) 列

于 2009-08-18T14:15:24.027 回答
8

只需运行此 SQL 即可一次转换所有数据库表。将您的 COLLATION 和 databaseName 更改为您需要的。

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";
于 2017-10-23T15:13:18.970 回答
6

生成查询以更新每个表和每个表的列。我以前在我的一些项目中使用过它,并且能够解决我的大部分 COLLATION 问题。(尤其是在 JOINS 上)

要使用,只需将结果导出到分隔文本(可能是新行 '\n')

每张桌子

SELECT CONCAT('ALTER TABLE `', TABLE_NAME, 
              '` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;') 
       AS 'USE `DATABASE_NAME`;' 
FROM   INFORMATION_SCHEMA.TABLES 
WHERE  TABLE_SCHEMA = 'DATABASE_NAME' 
       AND TABLE_TYPE LIKE 'BASE TABLE' 

每列

SELECT CONCAT('ALTER TABLE `', TABLE_NAME, '` MODIFY COLUMN `', COLUMN_NAME,'` ', 
              DATA_TYPE, IF(CHARACTER_MAXIMUM_LENGTH IS NULL 
       OR DATA_TYPE LIKE 'longtext', '', CONCAT('(', CHARACTER_MAXIMUM_LENGTH, 
                                         ')') 
       ), ' COLLATE utf8mb4_unicode_ci;') AS 'USE `DATABASE_NAME`;' 
FROM   INFORMATION_SCHEMA.COLUMNS 
WHERE  TABLE_SCHEMA = 'DATABASE_NAME' 
       AND (SELECT INFORMATION_SCHEMA.TABLES.TABLE_TYPE 
            FROM   INFORMATION_SCHEMA.TABLES 
            WHERE  INFORMATION_SCHEMA.TABLES.TABLE_SCHEMA = 
                   INFORMATION_SCHEMA.COLUMNS.TABLE_SCHEMA 
                   AND INFORMATION_SCHEMA.TABLES.TABLE_NAME = 
                       INFORMATION_SCHEMA.COLUMNS.TABLE_NAME 
            LIMIT  1) LIKE 'BASE TABLE' 
       AND DATA_TYPE IN ( 'char', 'varchar' ) /* include other types if necessary */
于 2021-02-27T09:04:44.623 回答
5

您可以通过 PHP 脚本更改所有表的 CHARSET 和 COLLATION,如下所示。我喜欢 hkasera 的答案,但问题是查询在每个表上运行两次。这段代码除了使用MySqli代替mysql和防止双重查询外几乎相同。如果我可以投票,我会投票赞成 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();

?>
于 2015-02-02T05:36:55.747 回答
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!";
于 2016-05-05T11:41:32.170 回答
4

我很惊讶地得知,所以我不得不回到这里报告,优秀且维护良好的互连/它安全搜索和替换数据库脚本有一些选项可以将表转换为 utf8 / unicode,甚至转换为 innodb . 它是一种脚本,通常用于将数据库驱动的网站(Wordpress、Drupal、Joomla 等)从一个域迁移到另一个域。

互连脚本按钮

于 2016-10-19T20:10:52.857 回答
4

通过 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');
于 2019-11-04T13:37:19.957 回答
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');

有关更多详细信息,请阅读此博客

于 2015-06-09T13:07:05.670 回答
3

我的解决方案是@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>为您请求的编码。这也改变了每一列的编码!

于 2018-11-27T23:22:26.287 回答
2

如果要更新架构上的默认字符集:

 ALTER SCHEMA MYSCHEMA DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci;
于 2017-07-31T03:44:57.780 回答
2

我使用了以下 shell 脚本。它将数据库名称作为参数,并将所有表转换为另一个字符集和排序规则(由脚本中定义的另一个参数或默认值给出)。

#!/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
)
于 2017-10-11T10:52:12.063 回答
0

快捷方式 - 导出到 SQL 文件,使用搜索和替换来更改您需要更改的文本。创建新数据库,导入数据,然后将旧数据库和新数据库重命名为旧名称。

于 2015-11-09T14:25:00.060 回答
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!";

?>}
于 2020-05-01T21:42:30.327 回答
0

请注意,在更改数据库/表/列的字符集后,您可能需要实际转换现有数据(例如,如果您看到类似“Ù...طلوب توريد جٔ)像这样:

update country set name = convert(cast(convert(name using latin1) as binary) using utf8), cn_flag = convert(cast(convert(cn_flag using latin1) as binary) using utf8), and so on..

在转换数据库、表和字段时,我建议从这个线程中获得这个答案,这会生成大量查询,您只需在粘贴时复制这些查询,在这里我还找不到自动解决方案。另请注意,如果您将同一字段转换两次,您将获得不可恢复的问号:“???”。如果您在转换字段/表格之前转换数据,您也会得到这个问号。

于 2021-02-11T11:57:50.437 回答
-1

我刚刚编写了一个 bash 脚本来查找给定数据库中的所有表并隐藏它们(及其列)。

脚本可在此处获得:https ://github.com/Juddling/mysql-charset

于 2019-04-19T02:34:18.063 回答