我有一个包含一个唯一VARCHAR(512)字段的表。我想让另一个表持有对该第一个表的外键引用。两个表都使用InnoDB。 如果我将VARCHAR(512)密钥添加到第二个表并在其上添加外键约束,那么512字节长数据将保持两次吗?
如果是这样,有没有办法只保留对索引的引用而不是varchar本身?
简而言之,我的问题是,在InnoDB中是否有一种将外键保存到长VARCHAR字段的有效方法?
非常感谢,
参见Yaniv
答案 0 :(得分:2)
是的,如果引用表上有VARCHAR(512)
列,则数据将存在两次。
我建议您使引用表的外键引用第一个表的整数主键,而不是512字节数据。这就是规范化的一切。
答案 1 :(得分:2)
我运行了一个简单的测试:创建3个表,一个用于保存数据本身有两列,ID(int)和数据(varchar [120]),另一个表使用ID作为外键和最后一个将数据用作外键的那个:
CREATE TABLE `dados` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(120) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`) USING BTREE,
KEY `idx` (`id`,`name`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `refINT` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`dado` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `id` (`dado`),
CONSTRAINT `id` FOREIGN KEY (`dado`) REFERENCES `dados` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `refSTR` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`dado` varchar(120) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `nome` (`dado`),
CONSTRAINT `nome` FOREIGN KEY (`dado`) REFERENCES `dados` (`name`) ON DELETE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
在每张表中插入100条记录,并比较最终的表格大小:
dados: 192.0 KB
refINT: 32.0 KB
refSTR: 32.0 KB
所以我猜数据不会在varchar外键中复制,至少在MySQL 5.1版本中是这样。
答案 2 :(得分:0)
保持小键大小总是好的。你可以解决一个大VARCHAR
索引的问题,而不是在插入时生成一个额外的校验和列。此校验和字段将包含较大列的散列算法CRC32()
或MD5()
的输出。