我对 MySQL 5.6.10 中的一对父子表有疑问。下游也涉及 Django 应用程序,以及源自 SAS 的 .tab 数据文件。
父表 (ccs1) 定义了 18 个高级医疗代码,我将它们标记为 idx,并使用 varchar(2) 字段表示数字 1 到 18。子表定义了 138 个子代码,它们提供了另一个级别的医疗细节对于父级代码:1.1、1.2、2.1、2.2、2.3 等,也在其自己的表中标记为 idx。在孩子中,我创建了一个varchar(2)
名为 ccs1_id 的附加变量,它是孩子 idx 代码中的第一个数字,并尝试将其设置为对父表中等效 idx 变量的外键引用。(这是为好奇的人使用行业标准 CCS 表 - 总共有 4 个级别,例如 4.4.5.1,否则我不会使用 varchar 表示)。
读取子表时,foreign_key_checks = 0 的数据插入失败。当我关闭密钥检查时,数据似乎可以正确读取(在 MySQL 工作台 gui 中查看时)。当我尝试在 django 应用程序中使用数据并通过父外键引用过滤子表值时,它仅成功过滤了2位(字符)的高级代码:10. 18. 过滤掉父级键 1 到 9 失败。
这两个表都是用 varchar(2) 等相关变量构建的——我在下面为每个表都包含了 SHOW CREATE TABLE 输出。
到目前为止,我最好的线索是来自 SHOW ENGINE 日志中的最新外键错误,当我尝试加载父子表时,foreign_key_checks = 1。父加载成功,然后子失败:
TRANSACTION 1022234, ACTIVE 0 sec inserting, thread declared inside InnoDB 5000
mysql tables in use 1, locked 1
4 lock struct(s), heap size 320, 1 row lock(s), undo log entries 1
MySQL thread id 177, OS thread handle 0x2280, query id 12426 localhost 127.0.0.1 root
System lock
LOAD DATA LOCAL INFILE '/abc/dim_dx_ccs2.tab'
INTO TABLE dim_dx_ccs2
IGNORE 1 LINES
(idx, idxm, label, ccs1_id)
Foreign key constraint fails for table `phrat`.`dim_dx_ccs2`:
,
CONSTRAINT `ccs1_id_refs_idx_1213764e` FOREIGN KEY (`ccs1_id`) REFERENCES `dim_dx_ccs1` (`idx`)
Trying to add in child table, in index `ccs1_id_refs_idx_1213764e` tuple:
DATA TUPLE: 2 fields;
0: len 2; hex 310d; asc 1 ;;
1: len 4; hex 80000103; asc ;;
But in parent table `phrat`.`dim_dx_ccs1`, in index `idx`,
the closest match we can find is record:
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 1; hex 31; asc 1;;
1: len 4; hex 80000052; asc R;;
在这种情况下,它应该在父表中搜索值“1”。查看最后 9 行,看起来 MySQL 的 varchar 数据类型在修剪后将父表的 idx 值视为长度为 1,并将其与修剪前长度为 2 的值进行比较?也就是说,给定的十六进制值 310d(decimal:12557) 和 31(decimal:49) 没有任何意义,因为我正在读取的数据应该只在 1 到 18 之间。 1:字段看起来合适,那些将是每个表的主键(ID),第一个条目(外键值将是“1”或“1”)。
我是否在这里遗漏了一些更基本的东西,或者这是问题的根源?如果是这样,我该如何解决?我想我可以切换到 set-length CHAR 值,这可能会解决,但我想确保我了解这里发生了什么。
这里的参考是 SHOW CREATE TABLE 输出
-------------------------------------------------------------------------------------+
dim_dx_ccs1 | CREATE TABLE `dim_dx_ccs1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`idx` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
`idxm` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
`label` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx` (`idx`),
UNIQUE KEY `idxm` (`idxm`)
ENGINE=InnoDB AUTO_INCREMENT=65 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
-------------+--------------------------------------------------------------------------------------
dim_dx_ccs2 | CREATE TABLE `dim_dx_ccs2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`idx` varchar(5) COLLATE utf8_unicode_ci NOT NULL,
`idxm` varchar(5) COLLATE utf8_unicode_ci NOT NULL,
`label` varchar(128) COLLATE utf8_unicode_ci NOT NULL,
`ccs1_id` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx` (`idx`),
UNIQUE KEY `idxm` (`idxm`),
KEY `ccs1_id_refs_idx_1213764e` (`ccs1_id`),
CONSTRAINT `ccs1_id_refs_idx_1213764e` FOREIGN KEY (`ccs1_id`) REFERENCES `dim_dx_ccs1` (`idx`)
ENGINE=InnoDB AUTO_INCREMENT=259 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
-------------+----------------------------------------------------------------------------------------
额外细节:
- 数据表源自 Unix 服务器(SAS 所在的位置),然后作为 .tab 文件导出到 Windows 环境。