最近、データベースのCHARSET=utf8 COLLATE=latin1
からCHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
への移行を完了しました。プロセス中に、それぞれの文字セットと照合プロパティを変更することにより、テーブルが一度に1つずつ移行されました。
移行が完了し、すべてのサーバーとデータベース自体がutf8mb4とutf8mb4_unicode_ciを使用するように設定されたので、これらのプロパティを列とテーブルから削除して、サーバーに設定されているデフォルト値を継承するにはどうすればよいですか?
たとえば、現在、ほとんどの列のSHOW FULL COLUMNS FROM table;
照合順序を実行すると、NULLではなくutf8mb4_unicode_ciに設定されます。
列の変換:
ALTER TABLE table_name MODIFY col_name VARCHAR(100) CHARACTER SET utf8;
テーブルの変換:
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8;
プログラマーとして、データベースに「継承」があると想定するのは簡単です。値がnullの場合は、親を調べます。
継承はありません
テキストタイプの列にnull文字セットまたは照合順序を含めることはできません。各フィールドは、作成時に固定の文字セットと照合順序を持ちます。テーブルレベルまたはデータベースレベルで完全に異なる文字セットに変更し、既存の列の既存のデータが新しい文字セットを自動的に継承するとします。おそらく壊れているように見えます。
ここにいくつかのドキュメントがあります: https://dev.mysql.com/doc/refman/8.0/en/charset-table.html
MySQLは次の方法でテーブルの文字セットと照合を選択します。
CHARACTER SET charset_nameとCOLLATE collation_nameの両方が指定されている場合、文字セットcharset_nameと照合collation_nameが使用されます。
COLLATEなしでCHARACTER SET charset_nameを指定すると、文字セットcharset_nameとそのデフォルトの照合が使用されます。各文字セットのデフォルトの照合を表示するには、SHOW CHARACTER SETステートメントを使用するか、INFORMATION_SCHEMA CHARACTER_SETSテーブルをクエリします。
COLACT collation_nameがCHARACTER SETなしで指定されている場合、collation_nameおよびcollation collation_nameに関連付けられている文字セットが使用されます。
それ以外の場合(CHARACTER SETもCOLLATEも指定されていない場合)、データベースの文字セットと照合順序が使用されます。
明確にするために、文字セットと照合は列の作成時に選択されます。それらを変更する場合は、同時にデータも変換する必要があります。
私のテストでは、列に設定されていない場合、SHOW FULL COLUMNS
は常にテーブルの照合を結果に含めるように見えます。テキストタイプの列のみ。数値、日付などは照合順序がありません。
例の表には、照合がある1つの列があります。
CREATE TABLE `testCollationChanging` (
`apiUserID` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(128) NOT NULL,
`email` varchar(128) COLLATE latin1_general_ci NULL,
`apiKey` char(32) NOT NULL,
`companyID` int(11) NOT NULL,
`userID` int(11) NOT NULL,
PRIMARY KEY (`apiUserID`),
UNIQUE KEY `Duplicate name/company combo check` (`name`,`companyID`) USING BTREE,
UNIQUE KEY `apiKey` (`apiKey`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci;
SHOW FULL COLUMNS FROM `testCollationChanging`;
ALTER TABLE `testCollationChanging` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci;
SHOW FULL COLUMNS FROM `testCollationChanging`;
DROP TABLE `testCollationChanging`;
これは、次の2つの結果セットを示しています...
apiUserID int(11) NO PRI auto_increment select,insert,update,references
name varchar(128) latin1_swedish_ci NO MUL select,insert,update,references
email varchar(128) latin1_general_ci YES select,insert,update,references
apiKey char(32) latin1_swedish_ci NO UNI select,insert,update,references
companyID int(11) NO select,insert,update,references
userID int(11) NO select,insert,update,references
そして
apiUserID int(11) NO PRI auto_increment select,insert,update,references
name varchar(128) utf8mb4_unicode_520_ci NO MUL select,insert,update,references
email varchar(128) utf8mb4_unicode_520_ci YES select,insert,update,references
apiKey char(32) utf8mb4_unicode_520_ci NO UNI select,insert,update,references
companyID int(11) NO select,insert,update,references
userID int(11) NO select,insert,update,references
列の照合順序に一貫性がない場合は、それらも変換する必要があると思います。上記の例では、適切に変換されているようです。
組み込む...
SELECT * FROM information_schema.TABLES WHERE TABLE_NAME = 'testCollationChanging';
SELECT * FROM information_schema.COLUMNS WHERE TABLE_NAME = 'testCollationChanging';
結果には、情報スキーマが各列に対して照合を保持していることが示されています。