เพิ่มสิ่งที่เดวิด Whittaker โพสต์ฉันได้สร้างแบบสอบถามที่สร้างตารางที่สมบูรณ์และคอลัมน์แก้ไขคำสั่งที่จะแปลงแต่ละตาราง มันอาจเป็นความคิดที่ดีที่จะทำงาน
ชุดเซสชั่น group_concat_max_len = 100000;
ก่อนเพื่อให้แน่ใจ concat กลุ่มของคุณไม่ได้ไปเกินขีด จำกัด ขนาดเล็กมากเท่าที่เห็นนี่
SELECT a.table_name, concat('ALTER TABLE ', a.table_schema, '.', a.table_name, ' DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci, ',
group_concat(distinct(concat(' MODIFY ', column_name, ' ', column_type, ' CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ', if (is_nullable = 'NO', ' NOT', ''), ' NULL ',
if (COLUMN_DEFAULT is not null, CONCAT(' DEFAULT \'', COLUMN_DEFAULT, '\''), ''), if (EXTRA != '', CONCAT(' ', EXTRA), '')))), ';') as alter_statement
FROM information_schema.columns a
INNER JOIN INFORMATION_SCHEMA.TABLES b ON a.TABLE_CATALOG = b.TABLE_CATALOG
AND a.TABLE_SCHEMA = b.TABLE_SCHEMA
AND a.TABLE_NAME = b.TABLE_NAME
AND b.table_type != 'view'
WHERE a.table_schema = ? and (collation_name = 'latin1_swedish_ci' or collation_name = 'utf8mb4_general_ci')
GROUP BY table_name;
ข้อแตกต่างระหว่างคำตอบก่อนหน้านี้คือการใช้ utf8 แทน ut8mb4 และการใช้ t1.data_type กับ t1.CHARACTER_MAXIMUM_LENGTH ไม่ได้ผลสำหรับ enums นอกจากนี้ข้อความค้นหาของฉันยังไม่รวมการดูเนื่องจากสิ่งเหล่านี้จะต้องเปลี่ยนแปลงแยกต่างหาก
ฉันเพียงแค่ใช้สคริปต์ Perl เพื่อส่งกลับการเปลี่ยนแปลงทั้งหมดเหล่านี้เป็นอาร์เรย์และทำซ้ำกับพวกเขาแก้ไขคอลัมน์ที่ยาวเกินไป (โดยทั่วไปพวกเขา varchar (256) เมื่อข้อมูลโดยทั่วไปมีเพียง 20 ตัวอักษรในตัวพวกเขาเพื่อให้แก้ไขได้ง่าย )
ฉันพบข้อมูลบางอย่างเสียหายเมื่อทำการเปลี่ยนแปลงจาก latin1 -> utf8mb4 ดูเหมือนว่าจะเป็นอักขระ utf8 ที่เข้ารหัส latin1 ในคอลัมน์จะได้รับการแปลงในการแปลง ฉันเพียงแค่เก็บข้อมูลจากคอลัมน์ที่ฉันรู้ว่าจะเป็นปัญหาในหน่วยความจำจากก่อนและหลังการเปลี่ยนแปลงและเปรียบเทียบพวกเขาและสร้างงบการปรับปรุงเพื่อแก้ไขข้อมูล