Làm thế nào để thay đổi đối chiếu cơ sở dữ liệu, bảng, cột?


200

Cơ sở dữ liệu latin1_general_cihiện tại và tôi muốn thay đổi đối chiếu thành utf8mb4_general_ci.

Có bất kỳ cài đặt nào trong PhpMyAdmin để thay đổi đối chiếu cơ sở dữ liệu, bảng, cột không? Thay vì thay đổi từng cái một?


3
Xem phần này để biết câu trả lời: stackoverflow.com/questions/5906585/ từ
Timo Huovinen 20/07/2015

Câu trả lời:


257

Bạn cần chuyển đổi từng bảng riêng lẻ:

ALTER TABLE mytable CONVERT TO CHARACTER SET utf8mb4 

(điều này cũng sẽ chuyển đổi các cột) hoặc xuất cơ sở dữ liệu latin1và nhập lại với utf8mb4.


15
Nhưng tôi muốn thay đổi đối chiếu các cột. Điều này sẽ chỉ thay đổi đối chiếu bảng ..
user158469

7
@rsensan: CONVERTcũng sẽ thay đổi đối chiếu các cột.
Quassnoi

21
ALTER SCHema database DEFAULT CHARACTER SET utf8 DEFAULT THU THẬP utf8_general_ci;
bão

8
@stormwild: điều này sẽ không ảnh hưởng đến các bảng hiện có
Quassnoi

47
Truy vấn của tôi: MYTABLETHAY ĐỔI BẢNG CHUYỂN ĐỔI ĐỂ TÙY CHỈNH utf8mb4 THU THẬP utf8mb4_unicode_ci; Vui lòng không sử dụng utf8_general_ci nữa ;-)
Kapitein Witbaard

209

Tôi đang đóng góp ở đây, như OP yêu cầu:

Làm thế nào để thay đổi đối chiếu cơ sở dữ liệu, bảng, cột?

Câu trả lời được chọn chỉ nêu nó ở cấp độ bảng.


Thay đổi cơ sở dữ liệu rộng:

ALTER DATABASE <database_name> CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Thay đổi nó trên mỗi bảng:

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

Thực hành tốt là thay đổi nó ở cấp độ bảng vì nó cũng sẽ thay đổi nó cho các cột. Thay đổi cho cột cụ thể là cho bất kỳ trường hợp cụ thể.

Thay đổi đối chiếu cho một cột cụ thể:

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

15
Điều này thực sự trả lời câu hỏi trực tiếp. Tôi cần điều này, vì các thay đổi cấp bảng của tôi KHÔNG cập nhật các cột. Tôi sẽ điều tra sau; nhưng đây là thông tin giúp tôi vượt qua thời kỳ khó khăn. Cảm ơn.
Parapluie

9
Câu trả lời tốt nhất cho điều này.
jubi4dition

Có, bạn cần đặc thù loại cột. Đây là một lệnh ma thuật để có được tất cả các loại. Sử dụng chỉnh sửa nhiều dòng, bạn có thể tạo lệnh để cập nhật tất cả các cột cùng một lúc bắt đầu tại đây: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

Đối với một cột duy nhất, bạn có thể chỉ cần thực hiện: ALTER TABLE table_name CHANGE cột_name VARCHAR (45) COLLATE utf8mb4_bin;
TomoMiha

68

Bạn có thể chạy một tập lệnh 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

Để thay đổi đối chiếu cho các bảng riêng lẻ, bạn có thể sử dụng,

ALTER TABLE mytable CONVERT TO CHARACTER SET utf8

Để đặt đối chiếu mặc định cho toàn bộ cơ sở dữ liệu,

ALTER DATABASE  `databasename` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin

hoặc cái gì đó khác,

Goto PhpMyAdmin-> Hoạt động-> Đối chiếu.

Ở đó bạn tìm thấy hộp chọn chứa tất cả các đối chiếu thoát hiểm. Vì vậy, ở đây bạn có thể thay đổi đối chiếu của bạn. Vì vậy, ở đây sau bảng cơ sở dữ liệu sẽ theo đối chiếu này trong khi bạn đang tạo cột mới. Không cần chọn đối chiếu trong khi tạo cột mới.


Cảm ơn rất nhiều, điều này rất hữu ích
JoZ3 8/2/2015

15

Truy vấn sau đây sẽ tạo các truy vấn ALTER thay đổi đối chiếu cho tất cả các cột thích hợp trong tất cả các bảng thành một loại nhất định (utf8_general_ci trong ví dụ của tôi bên dưới).

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 Tôi thích câu trả lời này nhất. Không phải ai cũng có PHP một cách kỳ diệu ở đâu đó. Một số sử dụng sử dụng các ngôn ngữ khác với MySQL. Điều này rất dễ chạy trong MySQL Workbench, sao chép các hàng và dán. Tôi vừa thực hiện thêm một bước để chạy phần trên information_schema.tablesvà mã trong concatALTER TABLE 'schema'.'table' CHARACTER SET = utf8mb4 , COLLATE = utf8mb4_bin ;
Pierre

1
Lỗi này xảy ra với các loại cột văn bản (trung bình / dài), phải được dọn sạch bằng tay
stiebrs

11

Nếu bạn chạy phpMyAdmin >> chọn cơ sở dữ liệu >> chọn bảng >> đi đến tab "Hoạt động" >> trong phần "Tùy chọn bảng" >> bạn có thể chọn Collation từ danh sách thả xuống >> và khi bạn nhấn {Go} tại trên cùng của màn hình, bạn sẽ thấy một thông báo:

Truy vấn SQL của bạn đã được thực hiện thành công

và một kịch bản

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

Nhưng nó sẽ KHÔNG thay đổi sự đối chiếu của các cột hiện có. Để làm như vậy, bạn có thể sử dụng tập lệnh này (tập lệnh này cũng đến từ phpMyAdmin)

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


5

Chỉ cần chạy SQL này để chuyển đổi tất cả các bảng cơ sở dữ liệu cùng một lúc. Thay đổi THU THẬP và tên cơ sở dữ liệu của bạn thành những gì bạn cần.

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

Bạn có thể thay đổi CHARSET và THU THẬP tất cả các bảng của mình thông qua tập lệnh PHP như sau. Tôi thích câu trả lời của hkasera nhưng vấn đề với nó là truy vấn chạy hai lần trên mỗi bảng. Mã này gần như giống nhau ngoại trừ sử dụng MySqli thay vì mysql và ngăn chặn truy vấn kép. Nếu tôi có thể bỏ phiếu, tôi đã bỏ phiếu cho câu trả lời của 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();

?>

Điều này làm việc cho tôi một cách hoàn hảo, sau khi nâng cấp lên Zabbix 5. Chỉ cần nói rằng tôi đã thay đổi CharsetCollation như thế này: CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin.
robe007

4

Bạn có thể đơn giản thêm mã này vào tệp script

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

Tôi đã rất ngạc nhiên khi biết, và vì vậy tôi đã phải quay lại đây và báo cáo rằng, Interconnect / nó được TÌM KIẾM TUYỆT VỜI và duy trì tốt trên tập lệnh DATABASE có một số tùy chọn để chuyển đổi bảng thành utf8 / unicode và thậm chí chuyển đổi sang innodb . Đó là một tập lệnh thường được sử dụng để di chuyển một trang web điều khiển cơ sở dữ liệu (Wordpress, Drupal, Joomla, v.v.) từ tên miền này sang tên miền khác.

các nút script kết nối


3

Tôi đọc nó ở đây, rằng bạn cần chuyển đổi từng bảng theo cách thủ công, điều đó không đúng. Đây là một giải pháp làm thế nào để làm điều đó với một thủ tục được lưu trữ:

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 ;

Sau khi thủ tục được tạo, hãy gọi nó đơn giản:

CALL changeCollation('utf8');

Để biết thêm chi tiết đọc blog này .


2

nếu bạn muốn cập nhật bộ ký tự mặc định trên lược đồ:

 ALTER SCHEMA MYSCHEMA DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci;

1

Tôi đã sử dụng kịch bản shell sau đây. Nó lấy tên cơ sở dữ liệu làm tham số và chuyển đổi tất cả các bảng thành bộ ký tự và đối chiếu khác (được cung cấp bởi một tham số khác hoặc giá trị mặc định được xác định trong tập lệnh).

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

Giải pháp của tôi là sự kết hợp giữa @Dzintars và @Quassnoi Trả lời.

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

Bằng cách sử dụng CONVERT TO, điều này tạo ra một tập lệnh, chuyển đổi tất cả các Bảng <your-database>thành mã hóa được yêu cầu của bạn. Điều này cũng thay đổi mã hóa của mỗi cột !


1

Biến thể tốt hơn để tạo tập lệnh SQL theo yêu cầu SQL. Nó sẽ không làm hỏng mặc định / nulls.

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

Cách nhanh chóng - xuất ra tệp SQL, sử dụng tìm kiếm và thay thế để thay đổi văn bản bạn cần thay đổi. Tạo cơ sở dữ liệu mới, nhập dữ liệu và sau đó đổi tên cơ sở dữ liệu cũ và cơ sở dữ liệu mới thành tên cũ.


0

Để thay đổi đối chiếu tất cả các trường trong tất cả các bảng của cơ sở dữ liệu cùng một lúc:

Tôi chỉ thêm một vòng lặp khác cho các trường trong bảng vào giải pháp thông qua Php trước khi được đề cập. Điều này đã giúp, tất cả các trường trong bảng cũng được chuyển đổi.

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

?>}

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.