关于mysql:如何更改数据库,表,列的排序规则?

How to change collation of database, table, column?

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

phpmyadmin中是否有更改数据库、表、列排序规则的设置?而不是一个接一个地改变?


您需要分别转换每个表:

1
ALTER TABLE mytable CONVERT TO CHARACTER SET utf8mb4

(这也将转换列),或者用latin1导出数据库,然后用utf8mb4导入。


我在这里做贡献,正如手术要求:

How to change collation of database, table, column?

所选答案只在表格级别上说明。

更改IT数据库范围:

1
ALTER DATABASE <database_name> CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

按表更改:

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

好的做法是在表级别更改它,因为它也会为列更改它。对特定列的更改适用于任何特定情况。

更改特定列的排序规则:

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


您可以运行一个PHP脚本。

1
2
3
4
5
6
7
8
9
10
11
               <?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!";
                ?>


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

1
ALTER TABLE mytable CONVERT TO CHARACTER SET utf8

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

1
ALTER DATABASE  `databasename` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin

否则,

转到phpmyadmin->operations->collation。

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


以下查询将生成将所有表中所有适当列的排序规则更改为特定类型的alter查询(下面的示例中是utf8_-general_-ci)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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');


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

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

1)客户2)服务器默认值3)数据库默认值4)表格默认值5)立柱


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

Your SQL query has been executed successfully

还有一个剧本

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

但它不会更改现有列的排序规则。为此,您可以使用此脚本(此脚本也来自phpmyadmin)

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


我很惊讶地了解到,所以我必须回到这里并报告,优秀且维护良好的interconnect/it安全搜索和数据库脚本替换对于将表转换为utf8/unicode,甚至转换为innodb都有一些选择。它是一个脚本,通常用于将数据库驱动的网站(wordpress、drupal、joomla等)从一个域迁移到另一个域。

interconnect script buttons

  • 网址:https://github.com/interconnect/search-replace-db
  • https://interconnect.com/products/search-and-replace-for-wordpress-数据库/

您可以通过下面的PHP脚本更改所有表的字符集和排序规则。我喜欢HKASERA的回答,但问题是查询在每个表上运行两次。除了使用mysqli而不是mysql以及防止双重查询之外,此代码几乎是相同的。如果我能投赞成票,我会投反对票。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?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();

?>

我在这里读到,您需要手动转换每个表,这不是真的。下面是一个如何使用存储过程的解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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,
'.
'
, 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 ;

创建过程后,只需调用它:

1
CALL changeCollation('utf8');

有关详细信息,请阅读此日志。


您可以简单地将此代码添加到脚本文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//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!";


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

1
 ALTER SCHEMA MYSCHEMA DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci;


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/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
)


运行这个SQL。将排序规则更改为所需内容和databasename。

1
2
3
4
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";


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

脚本可从以下网址获取:https://github.com/juddling/mysql-charset


我的解决方案是@dzintars和@quassnoi答案的组合。

1
2
3
4
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生成一个脚本,它将的所有表转换为您请求的编码。这也会更改每列的编码!


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