วิธีการแปลงชุดอักขระฐานข้อมูล MySQL ทั้งหมดและการเรียงหน้าเป็น UTF-8


459

ฉันจะแปลงชุดอักขระฐานข้อมูล MySQL ทั้งหมดเป็น UTF-8 และเปรียบเทียบเป็น UTF-8 ได้อย่างไร


22
กับผู้เข้าชมกว่า: หมายเหตุคำถามที่เกี่ยวข้องในแถบด้านข้างและการใช้งานไม่ได้utf8_unicode_ci utf8_general_ci
fuxia

14
หากคุณต้องการการสนับสนุน UTF-8 อย่างเต็มรูปแบบคุณอาจต้องการใช้ชุดอักขระutf8mb4มากกว่าutf8ที่utf8จะรองรับระนาบหลายภาษาพื้นฐานเมื่อเทียบกับช่วงเต็ม ต้องใช้ MySQL 5.5.3 ขึ้นไป
Martin Steel

4
ฉันลืมที่จะพูดถึงในความคิดเห็นของฉันข้างต้นหากคุณเปลี่ยนไปที่utf8mb4คุณจะต้องสลับการเปรียบเทียบไปยังutf8mb4_unicode_ci
มาร์ตินเหล็ก

3
ดียิ่งขึ้นการเปรียบเทียบutf8mb4_unicode_520_ciหรือสิ่งที่เป็นรุ่นล่าสุดที่มีอยู่
Rick James

@MartinSteel ฉันเชื่อว่านั่นคือการเปรียบเทียบโดยค่าเริ่มต้นด้วยชุดอักขระนั้น
VaTo

คำตอบ:


715

ใช้คำสั่งALTER DATABASEและALTER TABLE

ALTER DATABASE databasename CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE tablename CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

หรือถ้าคุณยังอยู่บน MySQL 5.5.2 หรือเก่ากว่าซึ่งไม่รองรับ 4-byte UTF-8 ให้ใช้utf8แทนutf8mb4:

ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;

12
CONVERT TOเทคนิคสันนิษฐานว่าข้อความที่ได้รับอย่างถูกต้องเก็บไว้ในบาง charset อื่น ๆ (เช่น latin1) และไม่ mangled (เช่น UTF-8 ไบต์หนาตาลงในคอลัมน์ latin1 โดยไม่ต้องแปลงไป latin1)
Rick James

1
สิ่งนี้จะสร้างตารางขึ้นใหม่ทำให้ไม่สามารถทำได้ในระบบการผลิตขนาดใหญ่ หากมั่นใจว่ามีเฉพาะ ASCII chars เท่านั้นที่ถูกเก็บไว้ในคอลัมน์ latin1 เป็นไปได้ไหมที่จะเปลี่ยนชุดอักขระ charset / collation โดยไม่ต้องสร้างใหม่
แอนดรู

@Andrew ระบบการผลิตขนาดใหญ่มักจะมีฐานข้อมูลมิเรอร์สำหรับการบำรุงรักษา
BalusC

1
charcter เปลี่ยนการตั้งค่าเป็น utf8 เปลี่ยนประเภทข้อมูลของฉันจากข้อความเป็นสื่อกลาง คาดหวังหรือไม่
Jerry

1
@Jerry อาจเป็นเพราะ: "หากคอลัมน์ถูกแปลงเป็น utf8 อักขระแต่ละตัวอาจต้องสูงถึงสามไบต์สำหรับความยาวสูงสุดที่เป็นไปได้คือ 3 × 65,535 = 196,605 ไบต์ความยาวนั้นไม่พอดีกับความยาวของคอลัมน์ TEXT ดังนั้น MySQL แปลงชนิดข้อมูลเป็น MEDIUMTEXT ซึ่งเป็นประเภทสตริงที่เล็กที่สุดซึ่งไบต์ความยาวสามารถบันทึกค่าได้ที่ 196,605 ในทำนองเดียวกันคอลัมน์ VARCHAR อาจถูกแปลงเป็น MEDIUMTEXT " การเปลี่ยนชุดตัวอักษร
jabbascript

129
  1. ทำการสำรองข้อมูล!

  2. จากนั้นคุณต้องตั้งค่าชุดอักขระเริ่มต้นบนฐานข้อมูล สิ่งนี้ไม่แปลงตารางที่มีอยู่ แต่ตั้งค่าเริ่มต้นสำหรับตารางที่สร้างขึ้นใหม่เท่านั้น

    ALTER DATABASE dbname CHARACTER SET utf8 COLLATE utf8_general_ci;
  3. จากนั้นคุณจะต้องแปลงชุดถ่านในตารางและคอลัมน์ที่มีอยู่ทั้งหมด สมมติว่าข้อมูลปัจจุบันของคุณเป็นจริงในชุดถ่านปัจจุบัน หากคอลัมน์ของคุณถูกตั้งค่าเป็นชุดถ่านหนึ่งชุด แต่ข้อมูลของคุณถูกเก็บไว้ในอีกชุดหนึ่งคุณจะต้องตรวจสอบคู่มือ MySQLเกี่ยวกับวิธีจัดการกับสิ่งนี้

    ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

44
หมายเหตุ: แก้ไขตาราง tablename ชุดอักขระ CHARACTER utf8 จะตั้งค่าถ่านเริ่มต้นที่กำหนดไว้ในตารางที่ใช้สำหรับคอลัมน์ที่สร้างขึ้นใหม่เท่านั้น มันไม่แปลงคอลัมน์ที่มีอยู่ที่มีชุดชุดถ่านอยู่แล้ว
นักข่าว

ฉันควรอ่านการสำรองข้อมูลสำรองก่อน ... แต่ฉันโชคดีที่มันอยู่ในสภาพแวดล้อมการพัฒนา ดังนั้น upvote ของฉันไปหาคุณ!
DominikAngerer

4
@DominikAngerer: เกิดอะไรขึ้น
cic

16
โปรดทราบว่าutf8_general_ciไม่แนะนำวิธีปฏิบัติที่ดีที่สุดอีกต่อไป ตั้งแต่ MySQL 5.5.3 คุณควรใช้มากกว่าutf8mb4 utf8พวกเขาทั้งสองหมายถึงการเข้ารหัส UTF-8 แต่พี่utf8มีข้อ จำกัด การใช้งานการป้องกัน MySQL 0xFFFDเฉพาะของตัวละครที่หมายเลขข้างต้น
u01jmg3

76

บนเชลล์ commandline

หากคุณเป็นหนึ่งใน commandline shell คุณสามารถทำสิ่งนี้ได้อย่างรวดเร็ว เพียงกรอก "dbname": D

DB="dbname"
(
    echo 'ALTER DATABASE `'"$DB"'` CHARACTER SET utf8 COLLATE utf8_general_ci;'
    mysql "$DB" -e "SHOW TABLES" --batch --skip-column-names \
    | xargs -I{} echo 'ALTER TABLE `'{}'` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;'
) \
| mysql "$DB"

หนึ่งซับสำหรับการคัดลอก / วางอย่างง่าย

DB="dbname"; ( echo 'ALTER DATABASE `'"$DB"'` CHARACTER SET utf8 COLLATE utf8_general_ci;'; mysql "$DB" -e "SHOW TABLES" --batch --skip-column-names | xargs -I{} echo 'ALTER TABLE `'{}'` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;' ) | mysql "$DB"

2
คุณช่วยใส่รายละเอียดเพิ่มเติมในสิ่งนี้ได้ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DB="dbname"
ไหม

@ 4485670 คุณจำเป็นต้องทำงานนี้บนเปลือกบรรทัดคำสั่ง หากคุณมีการเชื่อมต่อไคลเอนต์ MySQL เท่านั้นให้ใช้รหัสของ sdfor ด้านล่าง
อาร์โนลด์แดเนียลส์

6
รหัสนี้ใช้งานได้ดีอย่าลืมเพิ่ม -h [ชื่อโฮสต์] -u [ชื่อผู้ใช้] -p [รหัสผ่าน] หลังจาก mysql ตามความจำเป็น
แยกย้ายกัน

3
คุณอาจต้องการปิดการใช้งานการตรวจสอบกุญแจต่างประเทศในระบบจริง: DB="db_name"; ( echo 'ALTER DATABASE '"$ DB"' `ชุดตัวอักษร CHARACTER utf8 COLLATE utf8_general_ci; '; mysql - ผู้ใช้ - รหัสผ่าน - โฮสต์ "$ DB" - e "ตารางแสดง" - แบทช์ - ข้าม - ชื่อคอลัมน์ | xargs -I {} echo 'SET foreign_key_checks = 0; แก้ไขตาราง'{}'แปลงเป็นชุดอักขระ utf8 COLLATE utf8_general_ci; ' ) | mysql -uuser -ppassword -hhost "$ DB" `
อดัมเนลสัน

1
ไม่ได้ผลสำหรับฉันจนกว่าฉันจะใช้ "แสดงตารางเต็มโดยที่ Table_Type = 'BASE TABLE'" แทนที่จะเป็น "SHOW TABLES"
Brian Peterson

68

คุณสามารถสร้าง sql เพื่ออัพเดทตารางทั้งหมดด้วย:

SELECT CONCAT("ALTER TABLE ",TABLE_SCHEMA,".",TABLE_NAME," CHARACTER SET utf8 COLLATE utf8_general_ci;   ",
    "ALTER TABLE ",TABLE_SCHEMA,".",TABLE_NAME," CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;  ") 
    AS alter_sql
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = your_database_name;

จับเอาท์พุทและเรียกใช้มัน

คำตอบของ Arnold Daniels ด้านบนนั้นงดงามมาก


ทำไมคุณเพิ่มการเปลี่ยนแปลงตารางแบบสอบถามสองอัน อย่างใดอย่างหนึ่งไม่เพียงพอ?
Akshay

7
@ Akshay คำถามที่ดี แบบสอบถามตารางการเปลี่ยนแปลงครั้งแรกตั้งค่าเริ่มต้นสำหรับคอลัมน์ใหม่และแบบสอบถามตารางการเปลี่ยนแปลงครั้งที่สองจะแปลงคอลัมน์ที่มีอยู่
UnlimitedInfinity

4
FYI: อ้างอิงจากdev.mysql.com/doc/refman/5.5/en/alter-table.htmlเอกสารประกอบของ MySQL รุ่น "แปลงเป็นตัวอักษร SET" ของคำสั่ง ALTER จะทำทั้งสองขั้นตอนในขั้นตอนเดียว: "เพื่อเปลี่ยนค่าเริ่มต้นของตาราง ชุดอักขระและคอลัมน์อักขระทั้งหมด (CHAR, VARCHAR, TEXT) เป็นชุดอักขระใหม่ ...
devGuy

2
ฉันมีข้อผิดพลาด # 1054 - คอลัมน์ที่ไม่รู้จัก 'webdb_playground' ใน 'where clause' แต่ฉันแน่ใจว่า db ของฉันนั้นถูกต้อง
Yannis Dran

1
@YannisDran ชื่อ db ของคุณอาจไม่ได้อยู่ในสตริงเช่นนั้นWHERE TABLE_SCHEMA=webdb_playgroundทำให้เกิดข้อผิดพลาดคอลัมน์ที่ไม่รู้จักคุณ แต่WHERE TABLE_SCHEMA="webdb_playground"จะประสบความสำเร็จ สิ่งที่ต้องลองในกรณีที่คนอื่นพบว่า
jabbascript

17

ก่อนที่จะดำเนินการตรวจสอบให้แน่ใจว่าคุณ: ทำการสำรองฐานข้อมูลเสร็จสมบูรณ์!

ขั้นตอนที่ 1: การเปลี่ยนแปลงระดับฐานข้อมูล

  • การระบุชุด Collation และ Character ของฐานข้อมูลของคุณ

    SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM 
    information_schema.SCHEMATA S
    WHERE schema_name = 'your_database_name'
    AND
    (DEFAULT_CHARACTER_SET_NAME != 'utf8'
        OR
     DEFAULT_COLLATION_NAME not like 'utf8%');
  • แก้ไขการเปรียบเทียบสำหรับฐานข้อมูล

    ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_unicode_ci;

ขั้นตอนที่ 2: การเปลี่ยนแปลงระดับตาราง

  • การระบุตารางฐานข้อมูลด้วยชุดอักขระหรือการเปรียบเทียบที่ไม่ถูกต้อง

    SELECT CONCAT(
    'ALTER TABLE ',  table_name, ' CHARACTER SET utf8 COLLATE utf8_general_ci;  ', 
    'ALTER TABLE ',  table_name, ' CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;  ')
    FROM information_schema.TABLES AS T, information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` AS C
    WHERE C.collation_name = T.table_collation
    AND T.table_schema = 'your_database_name'
    AND
    (C.CHARACTER_SET_NAME != 'utf8'
        OR
     C.COLLATION_NAME not like 'utf8%')
  • การปรับการเรียงคอลัมน์และชุดอักขระของคอลัมน์ตาราง

จับเอาต์พุต sql ส่วนบนและรัน (เช่นต่อไปนี้)

ALTER TABLE rma CHARACTER SET utf8 COLLATE utf8_general_ci;ALTER TABLE rma CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;  
ALTER TABLE rma_history CHARACTER SET utf8 COLLATE utf8_general_ci;ALTER TABLE rma_history CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;  
ALTER TABLE rma_products CHARACTER SET utf8 COLLATE utf8_general_ci;ALTER TABLE rma_products CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;  
ALTER TABLE rma_report_period CHARACTER SET utf8 COLLATE utf8_general_ci;ALTER TABLE rma_report_period CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;  
ALTER TABLE rma_reservation CHARACTER SET utf8 COLLATE utf8_general_ci;ALTER TABLE rma_reservation CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;  
ALTER TABLE rma_supplier_return CHARACTER SET utf8 COLLATE utf8_general_ci;ALTER TABLE rma_supplier_return CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;  
ALTER TABLE rma_supplier_return_history CHARACTER SET utf8 COLLATE utf8_general_ci;ALTER TABLE rma_supplier_return_history CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;  
ALTER TABLE rma_supplier_return_product CHARACTER SET utf8 COLLATE utf8_general_ci;ALTER TABLE rma_supplier_return_product CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci; 

อ้างถึง: https://confluence.atlassian.com/display/CONFKB/How+to+Fix+the+Collation+and+Character+Set+of+a+MySQL+Database


1
ปัจจุบันสคริปต์นี้ใช้ 'utf8_unicode_ci' สำหรับ db แต่ 'utf8_general_ci' สำหรับตาราง - เป็นความตั้งใจหรือไม่ (ผมคิดว่าทั้งสองควรใช้ charset เดียวกัน)
gmcnaughton

stackoverflow.com/questions/10957238/…ได้ทิ้งคำตอบแบบเต็มไว้ที่นี่
VH

8

ใช้HeidiSQL ฟรีและเป็นเครื่องมือฐานข้อมูลที่ดีมาก

จากเมนูเครื่องมือให้ป้อนเครื่องมือแก้ไขตารางเป็นกลุ่ม

เลือกฐานข้อมูลที่สมบูรณ์หรือเลือกตารางที่จะแปลง

  • เห็บเปลี่ยนการเรียงหน้าเริ่มต้น: utf8mb4_general_ci
  • tick แปลงเป็นชุดอักขระ: utf8

ปฏิบัติ

นี้จะแปลงฐานข้อมูลที่สมบูรณ์จากละตินเป็น utf8 ในเวลาเพียงไม่กี่วินาที

ทำงานเหมือนมีเสน่ห์ :)

HeidiSQL เชื่อมต่อโดยค่าเริ่มต้นเป็น utf8 ดังนั้นตอนนี้อักขระพิเศษใด ๆ ควรถูกมองว่าเป็นอักขระ (æøå) และไม่เข้ารหัสตามที่ตรวจสอบข้อมูลตาราง

ข้อผิดพลาดที่แท้จริงเมื่อย้ายจากละตินเป็น utf8 คือเพื่อให้แน่ใจว่า pdo เชื่อมต่อกับ utf8 charset หากไม่ใช่คุณจะได้รับข้อมูลขยะที่แทรกลงในตาราง utf8 และเครื่องหมายคำถามทั่วหน้าเว็บของคุณทำให้คุณคิดว่าข้อมูลตารางไม่ใช่ utf8 ...


คุณช่วยอธิบายได้มั้ย ฉันมีปัญหาตรงนี้ - อักขระพิเศษและช่องว่างปรากฏเป็นเครื่องหมายคำถาม ฉันพยายามแปลงฐานข้อมูลใน MAMP โดยใช้ PHPMyAdmin มีการพัฒนาแบบออฟไลน์ตอนนี้ฉันพบว่าโฮสต์ของฉันไม่รองรับ utf8mb4 ฉันไม่มี Windows ดังนั้นจึงไม่สามารถใช้ HeidiSQL ได้ มีวิธีที่ฉันสามารถทำได้ด้วย PHPMyAdmin หรือไม่?
RexTheRunt

แบบนี้ โดยเฉพาะอย่างยิ่งคุณมีโต๊ะมากมาย
tyan

ฉันได้รับและข้อผิดพลาดเมื่อพยายามแปลง CHARSET: SQL Error (1025): ข้อผิดพลาดในการเปลี่ยนชื่อ ... แต่นี่เป็นเครื่องมือจัดการ SQL ที่น่าทึ่ง!
marcolopes

หากใครต้องการภาพรวมที่ดีและการสอนสำหรับ heidisql, ตรวจสอบบทความนี้
DougB

6

แรงบันดาลใจจากความคิดเห็น @sdfor ที่นี่เป็นสคริปต์ทุบตีที่ทำงาน

#!/bin/bash

printf "### Converting MySQL character set ###\n\n"

printf "Enter the encoding you want to set: "
read -r CHARSET

# Get the MySQL username
printf "Enter mysql username: "
read -r USERNAME

# Get the MySQL password
printf "Enter mysql password for user %s:" "$USERNAME"
read -rs PASSWORD

DBLIST=( mydatabase1 mydatabase2 )

printf "\n"


for DB in "${DBLIST[@]}"
do
(
    echo 'ALTER DATABASE `'"$DB"'` CHARACTER SET utf8 COLLATE `'"$CHARSET"'`;'
    mysql "$DB" -u"$USERNAME" -p"$PASSWORD" -e "SHOW TABLES" --batch --skip-column-names \
    | xargs -I{} echo 'ALTER TABLE `'{}'` CONVERT TO CHARACTER SET utf8 COLLATE `'"$CHARSET"'`;'
) \
| mysql "$DB" -u"$USERNAME" -p"$PASSWORD"

echo "$DB database done..."
done

echo "### DONE ###"
exit

4

ในกรณีที่ข้อมูลไม่อยู่ในชุดอักขระเดียวกันคุณอาจพิจารณาข้อมูลโค้ดนี้จากhttp://dev.mysql.com/doc/refman/5.0/en/charset-conversion.html

หากคอลัมน์มีชนิดข้อมูลที่ไม่ใช่ไบนารี (CHAR, VARCHAR, TEXT) เนื้อหาควรถูกเข้ารหัสในชุดอักขระคอลัมน์ไม่ใช่ชุดอักขระอื่น หากเนื้อหาถูกเข้ารหัสในชุดอักขระที่แตกต่างกันคุณสามารถแปลงคอลัมน์เพื่อใช้ชนิดข้อมูลไบนารีก่อนแล้วจึงไปยังคอลัมน์ที่ไม่ใช่ไบนารีพร้อมชุดอักขระที่ต้องการ

นี่คือตัวอย่าง:

 ALTER TABLE t1 CHANGE c1 c1 BLOB;
 ALTER TABLE t1 CHANGE c1 c1 VARCHAR(100) CHARACTER SET utf8;

ตรวจสอบให้แน่ใจว่าได้เลือกการเปรียบเทียบที่ถูกต้องหรือคุณอาจได้รับความขัดแย้งของคีย์ที่ไม่ซ้ำกัน เช่นÉleanoreและ Eleanore อาจได้รับการพิจารณาเหมือนกันในการเปรียบเทียบบางอย่าง

นอกเหนือ:

ฉันมีสถานการณ์ที่ตัวละครบางตัว "แตก" ในอีเมลแม้ว่าพวกเขาจะถูกเก็บเป็น UTF-8 ในฐานข้อมูล หากคุณกำลังส่งอีเมลโดยใช้ข้อมูล utf8 คุณอาจต้องการแปลงอีเมลของคุณเพื่อส่งเป็น UTF8

ใน PHPMailer เพียงอัปเดตบรรทัดนี้: public $CharSet = 'utf-8';


4

สำหรับฐานข้อมูลที่มีตารางจำนวนมากคุณสามารถใช้สคริปต์ php เพื่ออัปเดตชุดอักขระของฐานข้อมูลและตารางทั้งหมดโดยใช้ข้อมูลต่อไปนี้:

$conn = mysqli_connect($host, $username, $password, $database);

if ($conn->connect_error) {
  die("Connection failed: " . $conn->connect_error);
}

$alter_database_charset_sql = "ALTER DATABASE ".$database." CHARACTER SET utf8 COLLATE utf8_unicode_ci";
mysqli_query($conn, $alter_database_charset_sql);

$show_tables_result = mysqli_query($conn, "SHOW TABLES");
$tables  = mysqli_fetch_all($show_tables_result);

foreach ($tables as $index => $table) {
  $alter_table_sql = "ALTER TABLE ".$table[0]." CONVERT TO CHARACTER SET utf8  COLLATE utf8_unicode_ci";
  $alter_table_result = mysqli_query($conn, $alter_table_sql);
  echo "<pre>";
  var_dump($alter_table_result);
  echo "</pre>";
}

เราจะเรียกใช้สคริปต์นี้จากที่ไหน
Yannis Dran

1
@YannisDran มันไม่สำคัญว่าตราบใดที่ IP ที่คุณเรียกใช้งานจากนั้นมีการเข้าถึงฐานข้อมูล ตรวจสอบให้แน่ใจว่าคุณทำการสำรองข้อมูลก่อน!
Dan Lucas

ดีและเราจะรันได้อย่างไร เราต้องอัพโหลดมันบนเซิร์ฟเวอร์แล้วเรียกใช้ป้อนพา ธ ไปยังตำแหน่งของมันหรือไม่?
Yannis Dran

4
DELIMITER $$  

CREATE PROCEDURE `databasename`.`update_char_set`()  

BEGIN  
 DECLARE done INT DEFAULT 0;  
 DECLARE t_sql VARCHAR(256);  
 DECLARE tableName VARCHAR(128);  
 DECLARE lists CURSOR FOR SELECT table_name FROM `information_schema`.`TABLES` WHERE table_schema = 'databasename';  
 DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;  
 OPEN lists;  
 FETCH lists INTO tableName;  
 REPEAT  
    SET @t_sql = CONCAT('ALTER TABLE ', tableName, ' CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci');  
    PREPARE stmt FROM @t_sql;  
    EXECUTE stmt;  
    DEALLOCATE PREPARE stmt;  
 FETCH lists INTO tableName;  
 UNTIL done END REPEAT;  
 CLOSE lists;  
END$$  

DELIMITER ;  

CALL databasename.update_char_set();

ขอบคุณนี่เป็นหนึ่งในคำตอบไม่กี่ข้อที่แสดงให้เห็นว่าทำอย่างไรกับฐานข้อมูลทั้งหมด (เช่นแต่ละตาราง) ทำงานเหมือนจับใจ
Machisuji

3
mysqldump -uusername -ppassword -c -e --default-character-set=utf8 --single-transaction --skip-set-charset --add-drop-database -B dbname > dump.sql
cp dump.sql dump-fixed.sql
vim dump-fixed.sql


:%s/DEFAULT CHARACTER SET latin1/DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci/
:%s/DEFAULT CHARSET=latin1/DEFAULT CHARSET=utf8/
:wq

mysql -uusername -ppassword < dump-fixed.sql

3

วิธีที่ปลอดภัยที่สุดคือการปรับเปลี่ยนคอลัมน์ให้เป็นประเภทไบนารีก่อนแล้วจึงปรับเปลี่ยนกลับไปเป็นประเภทอื่นโดยใช้ชุดอักขระที่ต้องการ

แต่ละประเภทคอลัมน์มีประเภทไบนารีตามลำดับดังนี้:

  1. CHAR => BINARY
  2. TEXT => BLOB
  3. TINYTEXT => TINYBLOB
  4. MEDIUMTEXT => MEDIUMBLOB
  5. LONGTEXT => LONGBLOB
  6. VARCHAR => VARBINARY

เช่น.:

ALTER TABLE [TABLE_SCHEMA].[TABLE_NAME] MODIFY [COLUMN_NAME] VARBINARY;

ALTER TABLE [TABLE_SCHEMA].[TABLE_NAME] MODIFY [COLUMN_NAME] VARCHAR(140) CHARACTER SET utf8mb4;

ฉันลองในตาราง latin1 หลายอันและเก็บเครื่องหมายกำกับไว้ทั้งหมด

คุณสามารถแยกแบบสอบถามนี้สำหรับคอลัมน์ทั้งหมดที่ทำสิ่งนี้:

SELECT
CONCAT('ALTER TABLE ', TABLE_SCHEMA,'.', TABLE_NAME,' MODIFY ', COLUMN_NAME,' VARBINARY;'),
CONCAT('ALTER TABLE ', TABLE_SCHEMA,'.', TABLE_NAME,' MODIFY ', COLUMN_NAME,' ', COLUMN_TYPE,' CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;')
FROM information_schema.columns
WHERE TABLE_SCHEMA IN ('[TABLE_SCHEMA]')
AND COLUMN_TYPE LIKE 'varchar%'
AND (COLLATION_NAME IS NOT NULL AND COLLATION_NAME NOT LIKE 'utf%');

หลังจากที่คุณทำเช่นนี้ในทุกคอลัมน์แล้วคุณทำมันในตารางทั้งหมด:

ALTER TABLE [TABLE_SCHEMA].[TABLE_NAME] CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

เพื่อสร้างแบบสอบถามนี้สำหรับทุกตารางของคุณใช้แบบสอบถามต่อไปนี้:

SELECT
CONCAT('ALTER TABLE ', TABLE_SCHEMA, '.', TABLE_NAME, ' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_COLLATION NOT LIKE 'utf8%'
and TABLE_SCHEMA in ('[TABLE_SCHEMA]');

และตอนนี้คุณปรับเปลี่ยนคอลัมน์และตารางทั้งหมดของคุณแล้วให้ทำเช่นเดียวกันกับฐานข้อมูล:

ALTER DATABASE [DATA_BASE_NAME] CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci;

1

หากคุณไม่สามารถแปลงตารางของคุณหรือตารางของคุณถูกตั้งค่าเป็นชุดอักขระที่ไม่ใช่ utf8 เสมอ แต่คุณต้องการ utf8 ทางออกที่ดีที่สุดของคุณอาจล้างออกแล้วเริ่มต้นใหม่อีกครั้งและระบุอย่างชัดเจน:

create database database_name character set utf8;

0

ทางออกเดียวที่ใช้ได้สำหรับฉัน: http://docs.moodle.org/23/en/Converting_your_MySQL_database_to_UTF8

การแปลงฐานข้อมูลที่มีตาราง

mysqldump -uusername -ppassword -c -e --default-character-set=utf8 --single-transaction --skip-set-charset --add-drop-database -B dbname > dump.sql

cp dump.sql dump-fixed.sql
vim dump-fixed.sql

:%s/DEFAULT CHARACTER SET latin1/DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci/
:%s/DEFAULT CHARSET=latin1/DEFAULT CHARSET=utf8/
:wq

mysql -uusername -ppassword < dump-fixed.sql

0

เปลี่ยนแปลง table_name charset = 'utf8';

นี่เป็นคำถามง่ายๆที่ฉันสามารถใช้สำหรับกรณีของฉันคุณสามารถเปลี่ยน table_name ตามความต้องการของคุณ


โดยปกติคำตอบควรมีคำอธิบายเกี่ยวกับสิ่งที่คุณแนะนำให้ทำ
RiggsFolly

0

ในการเปลี่ยนชุดอักขระที่เข้ารหัสเป็น UTF-8 สำหรับฐานข้อมูลเองให้พิมพ์คำสั่งต่อไปนี้ที่พร้อมท์ mysql> แทนที่ DBNAME ด้วยชื่อฐานข้อมูล:

ALTER DATABASE DBNAME CHARACTER SET utf8 COLLATE utf8_general_ci;

0

คุณยังสามารถ DB เครื่องมือ Navicat ซึ่งทำได้ง่ายกว่า

  • มหาเทพ

คลิกขวาที่ฐานข้อมูลของคุณและเลือก DB Properties & Change ตามที่คุณต้องการใน Drop Down

ป้อนคำอธิบายรูปภาพที่นี่


0

โซลูชันบรรทัดคำสั่งและยกเว้นการดู

ฉันเพียงแค่ตอบคำถามของ @ Jasny ให้กับผู้อื่นที่ชอบ@Brianและฉันมีมุมมองในฐานข้อมูลของเรา

หากคุณมีข้อผิดพลาดเช่นนี้:

ERROR 1347 (HY000) at line 17: 'dbname.table_name' is not of type 'BASE TABLE'

เป็นเพราะคุณอาจมีมุมมองและคุณต้องยกเว้นพวกเขา แต่เมื่อพยายามที่จะแยกออก MySQL จะคืนค่า 2 คอลัมน์แทน 1

SHOW FULL TABLES WHERE Table_Type = 'BASE TABLE';
-- table_name1  BASE TABLE
-- table_name2  BASE TABLE

ดังนั้นเราต้องปรับคำสั่งของ Jasny ด้วยawkเพื่อแยกเฉพาะคอลัมน์ที่ 1 ซึ่งมีชื่อตาราง

DB="dbname"
(
    echo 'ALTER DATABASE `'"$DB"'` CHARACTER SET utf8 COLLATE utf8_general_ci;'
    mysql "$DB" -e "SHOW FULL TABLES WHERE Table_Type = 'BASE TABLE'" --batch --skip-column-names \
    | awk '{print $1 }' \
    | xargs -I{} echo 'ALTER TABLE `'{}'` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;'
) \
| mysql "$DB"

หนึ่งซับสำหรับการคัดลอก / วางอย่างง่าย

DB="dbname"; ( echo 'ALTER DATABASE `'"$DB"'` CHARACTER SET utf8 COLLATE utf8_general_ci;'; mysql "$DB" -e "SHOW FULL TABLES WHERE Table_Type = 'BASE TABLE'" --batch --skip-column-names | awk '{print $1 }' | xargs -I{} echo 'ALTER TABLE `'{}'` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;' ) | mysql "$DB"

-1

ในการเปลี่ยนการเข้ารหัสชุดอักขระเป็น UTF-8 ให้ทำตามขั้นตอนง่าย ๆ ใน PHPMyAdmin

  1. เลือกฐานข้อมูลของคุณ เอสเอส

  2. ไปที่การดำเนินงาน เอสเอส

  3. ในแท็บการดำเนินการบนเมนูแบบเลื่อนลงการเรียงล่างเลือกคุณต้องการการเข้ารหัสเช่น (utf8_general_ci) และตรวจสอบช่องทำเครื่องหมาย (1) เปลี่ยนการเรียงหน้าตารางทั้งหมด (2) เปลี่ยนการเรียงคอลัมน์คอลัมน์ทั้งหมด และกดปุ่ม Go

เอสเอส

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.