Saya punya solusi yang akan mengonversi basis data dan tabel dengan menjalankan beberapa perintah. Hal ini juga mengkonversi semua kolom jenis varchar
, text
, tinytext
, mediumtext
, longtext
, char
. Anda juga harus mencadangkan basis data jika terjadi kerusakan.
Salin kode berikut ke file yang bernama preAlterTables.sql:
use information_schema;
SELECT concat("ALTER DATABASE `",table_schema,"` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;") as _sql
FROM `TABLES` where table_schema like "yourDbName" group by table_schema;
SELECT concat("ALTER TABLE `",table_schema,"`.`",table_name,"` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;") as _sql
FROM `TABLES` where table_schema like "yourDbName" group by table_schema, table_name;
SELECT concat("ALTER TABLE `",table_schema,"`.`",table_name, "` CHANGE `",column_name,"` `",column_name,"` ",data_type,"(",character_maximum_length,") CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",IF(is_nullable="YES"," NULL"," NOT NULL"),";") as _sql
FROM `COLUMNS` where table_schema like "yourDbName" and data_type in ('varchar','char');
SELECT concat("ALTER TABLE `",table_schema,"`.`",table_name, "` CHANGE `",column_name,"` `",column_name,"` ",data_type," CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",IF(is_nullable="YES"," NULL"," NOT NULL"),";") as _sql
FROM `COLUMNS` where table_schema like "yourDbName" and data_type in ('text','tinytext','mediumtext','longtext');
Ganti semua kemunculan "yourDbName" dengan database yang ingin Anda konversi. Lalu lari:
mysql -uroot < preAlterTables.sql | egrep '^ALTER' > alterTables.sql
Ini akan menghasilkan file baru alterTables.sql, dengan semua pertanyaan yang Anda butuhkan untuk mengonversi database. Jalankan perintah berikut untuk memulai konversi:
mysql -uroot < alterTables.sql
Anda juga dapat mengadaptasi ini untuk dijalankan melalui banyak basis data, dengan mengubah kondisi untuk table_schema. Misalnya table_schema like "wiki_%"
akan mengonversi semua basis data dengan nama awalan wiki_
. Untuk mengonversi semua basis data, ganti kondisinya dengan table_type!='SYSTEM VIEW'
.
Suatu masalah yang mungkin muncul. Saya memiliki beberapa kolom varchar (255) di kunci mysql. Ini menyebabkan kesalahan:
ERROR 1071 (42000) at line 2229: Specified key was too long; max key length is 767 bytes
Jika itu terjadi, Anda cukup mengubah kolom menjadi lebih kecil, seperti varchar (150), dan jalankan kembali perintah.
Harap dicatat : Jawaban ini mengubah database menjadi utf8mb4_unicode_ci
alih-alih utf8mb4_bin
, ditanyakan dalam pertanyaan. Tetapi Anda bisa langsung mengganti ini.
mysql -uroot -pThatrootPassWord < alterTables.sql
berfungsi. Dan seperti yang sudah Anda catat, utf8mb4_bin adalah apa yang direkomendasikan oleh nextcloud.Saya menggunakan skrip shell berikut. Dibutuhkan nama database sebagai parameter dan mengubah semua tabel ke charset dan collation lain (diberikan oleh parameter lain atau nilai default yang didefinisikan dalam skrip).
sumber
Saya akan menulis skrip (dalam Perl, atau apa pun) untuk menggunakan information_schema (TABLES dan COLUMNS) untuk menelusuri semua tabel, dan melakukan MODIFY COLUMN pada setiap bidang CHAR / VARCHAR / TEXT. Saya akan mengumpulkan semua MODIFY menjadi ALTER tunggal untuk setiap tabel; ini akan lebih efisien.
Saya pikir (tapi tidak yakin) bahwa saran Raihan hanya mengubah default untuk tabel.
sumber
Berlari ke dalam situasi ini; inilah pendekatan yang saya gunakan untuk mengonversi basis data saya:
Pertama, Anda perlu mengedit
my.cnf
untuk membuat koneksi database default (antara aplikasi dan MYSQL) sesuai utf8mb4_unicode_ci. Tanpa karakter ini seperti emoji dan yang serupa yang dikirimkan oleh aplikasi Anda tidak akan bisa masuk ke tabel Anda dalam byte / encoding yang tepat (kecuali params DB CNN aplikasi Anda menentukan koneksi utf8mb4).Instruksi diberikan di sini .
Jalankan SQL berikut (tidak perlu bersiap-siap SQL untuk mengubah kolom individual,
ALTER TABLE
pernyataan akan melakukannya).Sebelum Anda menjalankan kode di bawah ini, ganti "DbName" dengan nama DB Anda yang sebenarnya.
Kumpulkan dan simpan output dari SQL di atas dalam file dot sql dan jalankan.
Jika Anda mendapatkan kesalahan seperti
#1071 - Specified key was too long; max key length is 1000 bytes.
bersama dengan nama tabel yang bermasalah, ini berarti kunci indeks pada beberapa kolom dari tabel itu (yang seharusnya dikonversi ke MB4 charstring) akan sangat besar sehingga kolom Varchar harus <= 250 sehingga itu kunci indeks akan menjadi maksimal 1000 byte. Periksa kolom di mana Anda memiliki indeks dan jika salah satunya adalah varchar> 250 (kemungkinan besar 255)Langkah 1: periksa data di kolom itu untuk memastikan bahwa ukuran string maksimal dalam kolom itu adalah <= 250.
Contoh permintaan:
Langkah 2: jika panjang karakter maksimum dari data kolom yang diindeks <= 250 kemudian ubah panjang col menjadi 250. jika itu tidak memungkinkan, hapus indeks pada kolom itu
Langkah 3: kemudian jalankan query tabel alter untuk tabel itu lagi dan tabel sekarang harus dikonversi menjadi utf8mb4 berhasil.
Tepuk tangan!
sumber
Saya menulis panduan ini: http://hanoian.com/content/index.php/24-automate-the-converting-a-mysql-database-character-set-to-utf8mb4
Dari pekerjaan saya, saya melihat bahwa ALTER database dan tabel tidak cukup. Saya harus masuk ke setiap tabel dan ALTER masing-masing kolom teks / mediumteks / varchar juga.
Untungnya saya bisa menulis skrip untuk mendeteksi metadata dari database MySQL, sehingga bisa loop melalui tabel dan kolom dan MENGUBAH mereka secara otomatis.
Indeks panjang untuk MySQL 5.6:
Ada satu hal yang harus Anda lakukan sebagai hak istimewa DBA / SUPER USER: Mengatur parameter basis data:
Dalam jawaban untuk pertanyaan ini, ada instruksi cara mengatur parameter di atas: https://stackoverflow.com/questions/35847015/mysql-change-innodb-large-prefix
Tentu saja, dalam artikel saya, ada instruksi untuk melakukannya juga.
Untuk MySQL versi 5.7 atau lebih baru , innodb_large_prefix AKTIF secara default, dan innodb_file_format juga merupakan Barracuda secara default.
sumber
Untuk orang-orang yang mungkin memiliki masalah ini solusi terbaik adalah memodifikasi terlebih dahulu kolom ke tipe biner, menurut tabel ini:
Dan setelah itu memodifikasi kolom kembali ke tipe sebelumnya dan dengan rangkaian karakter yang Anda inginkan.
Misalnya.:
Saya mencoba beberapa tabel latin1 dan menyimpan semua diakritik.
Anda dapat mengekstrak kueri ini untuk semua kolom yang melakukan ini:
sumber
Saya membuat skrip yang melakukan ini kurang lebih secara otomatis:
sumber