MySQL表只有一个varchar作为外键

时间:2009-08-16 21:46:31

标签: mysql foreign-keys innodb varchar

我有一个包含一个唯一VARCHAR(512)字段的表。我想让另一个表持有对该第一个表的外键引用。两个表都使用InnoDB。 如果我将VARCHAR(512)密钥添加到第二个表并在其上添加外键约束,那么512字节长数据将保持两次吗?

如果是这样,有没有办法只保留对索引的引用而不是varchar本身?

简而言之,我的问题是,在InnoDB中是否有一种将外键保存到长VARCHAR字段的有效方法?

非常感谢,

参见Yaniv

3 个答案:

答案 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()的输出。