简体   繁体   English

MySQL表只有一个varchar作为外键

[英]MySQL table with only a varchar as a foreign key

I have a table with a single unique VARCHAR(512) field. 我有一个表有一个唯一的VARCHAR(512)字段。 I want to have another table hold a foreign key reference to this first table. 我想让另一个表持有对该第一个表的外键引用。 Both tables use InnoDB. 两个表都使用InnoDB。 If I add a VARCHAR(512) key to the second table and add a foreign key constraint on it will the 512 bytes long data be held twice? 如果我将VARCHAR(512)键添加到第二个表并在其上添加外键约束,那么512字节长的数据将保持两次?

If so, is there a way to hold only a reference to the index and not to the varchar itself? 如果是这样,有没有办法只保留对索引的引用而不是varchar本身?

In short, my question is, in InnoDB is there an efficient way to hold foreign keys to long VARCHAR fields? 简而言之,我的问题是,在InnoDB中是否有一种将外键保存到长VARCHAR字段的有效方法?

Thank you very much, 非常感谢你,

Yaniv 的Yaniv

Yes, if you have a VARCHAR(512) column on the referencing table, the data will exist twice. 是的,如果引用表上有VARCHAR(512)列,则数据将存在两次。

I recommend that you make the referencing table's foreign key refer to an integer primary key for the first table, not the 512-byte data. 我建议您使引用表的外键引用第一个表的整数主键,而不是512字节数据。 This is kind of what normalization is all about. 这就是规范化的一切。

I ran a simple test: create 3 tables, one to hold the data itself with two columns, and ID (int) and the data (varchar[120]), another table that uses the ID as foreign key and a last one that uses the data as foreign key: 我运行了一个简单的测试:创建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;

Inserted 100 records in each table and compared the final table size: 在每个表中插入100条记录并比较最终的表格大小:

dados:  192.0 KB
refINT: 32.0 KB
refSTR: 32.0 KB

So I guess the data is NOT replicated in varchar foreign key, well, at least in MySQL 5.1 version. 所以我想数据不会在varchar外键中复制,至少在MySQL 5.1版本中是这样。

Keeping the key size small is always good. 保持密钥大小总是好的。 You could get around the problem of having a large VARCHAR indexed by instead having an additional checksum column that you generate at insert time. 你可以解决一个大型VARCHAR索引的问题,而不是在插入时生成一个额外的校验和列。 This checksum field would contain the output of a hashing algorithm CRC32() or maybe MD5() of the larger column. 该校验和字段将包含散列算法CRC32()或更大列的MD5()的输出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM