Bra*_*ell 6 mysql foreign-key collation character-set
我正在尝试将 MySQL 数据库以及所有包含表的字符集和排序规则从utf8 / utf8_unicode_ci转换为utf8mb4 / utf8mb4_unicode_ci。
我将我的数据库名称称为:MyDB
我将我的表称为:MyTable1 [、MyTable2、MyTable3等]
我已经使用以下命令设置了数据库字符集和排序规则:
ALTER DATABASE MyDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Run Code Online (Sandbox Code Playgroud)
然后我使用这个 SQL 脚本生成所有表命令:
SELECT CONCAT("ALTER TABLE ",TABLE_SCHEMA,".",TABLE_NAME," CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ",
"ALTER TABLE ",TABLE_SCHEMA,".",TABLE_NAME," CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ")
AS alter_sql
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'MyDB';
Run Code Online (Sandbox Code Playgroud)
此 SQL 生成了一个包含以下内容的表:
ALTER TABLE MyDB.MyTable1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE MyDB.MyTable1 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE MyDB.MyTable2 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE MyDB.MyTable2 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
... etc
Run Code Online (Sandbox Code Playgroud)
现在我的表有很多外键约束,如果我直接执行此查询,由于修改过程中途不兼容的字符集,我会收到外键约束错误:
#1025 - Error on rename of './MyDB/#sql-bba_3975' to './MyDB/MyTable1' (errno: 150)
Run Code Online (Sandbox Code Playgroud)
所以我想我可以在运行查询之前将 FOREIGN_KEY_CHECKS 设置为 0。我记得以前当我必须将数据库从 latin1 转换为 utf8 时这样做过。
SET FOREIGN_KEY_CHECKS=0;
ALTER TABLE MyDB.MyTable1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE MyDB.MyTable1 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE MyDB.MyTable2 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE MyDB.MyTable2 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
... etc
Run Code Online (Sandbox Code Playgroud)
对于同一张表,我仍然遇到相同的错误。
SHOW ENGINE INNODB STATUS;
...
LATEST FOREIGN KEY ERROR
------------------------
161103 9:59:06 Error in foreign key constraint of table MyDB/MyTable1:
there is no index in the table which would contain
the columns as the first columns, or the data types in the
table do not match the ones in the referenced table
or one of the ON ... SET NULL columns is declared NOT NULL. Constraint:
,
CONSTRAINT "MyTable1_ibfk_4" FOREIGN KEY ("MyTable1_Column1") REFERENCES "MyTable2" ("MyTable2_PK") ON UPDATE CASCADE
...
Run Code Online (Sandbox Code Playgroud)
如果我禁用了外键检查,我怎么可能仍然收到外键错误?
我尝试过一些奇怪的实验......
SELECT @@FOREIGN_KEY_CHECKS;
SET FOREIGN_KEY_CHECKS=0;
SELECT @@FOREIGN_KEY_CHECKS;
SET FOREIGN_KEY_CHECKS=1;
SELECT @@FOREIGN_KEY_CHECKS;
Run Code Online (Sandbox Code Playgroud)
所有的选择都1
在应该返回的时候返回1 0 1
。
但如果我执行这个:
SELECT @@FOREIGN_KEY_CHECKS;
SET FOREIGN_KEY_CHECKS=0;
SELECT @@FOREIGN_KEY_CHECKS;
#SET FOREIGN_KEY_CHECKS=1;
SELECT @@FOREIGN_KEY_CHECKS;
Run Code Online (Sandbox Code Playgroud)
所有的选择都会0
在应该返回的时候返回1 0 0
。
这使我认为我对服务器会话变量如何工作的理解从根本上是错误的。
笔记:
我知道在进行转换之前我可以删除数据库中的所有外键,但如果不需要,我宁愿不这样做。我的数据库有很多外键,我不想在转换过程中错过任何一个。
排序ALTERs
以便 FK 检查将停止抱怨。先做孩子再做父母(或者是相反的方式??)。
如果您有任何循环引用,那么,是的,删除并重新应用 FK。
(你已经指出了避免 FK 的另一个原因。)
当你这样做时,请考虑utf8mb4_unicode_520_ci
;它来自较新的 Unicode 标准。
归档时间: |
|
查看次数: |
6628 次 |
最近记录: |