MySQL table with only a varchar as a foreign key

非 Y 不嫁゛ 提交于 2019-12-22 07:58:30

问题


I have a table with a single unique VARCHAR(512) field. I want to have another table hold a foreign key reference to this first table. Both tables use 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?

If so, is there a way to hold only a reference to the index and not to the varchar itself?

In short, my question is, in InnoDB is there an efficient way to hold foreign keys to long VARCHAR fields?

Thank you very much,

Yaniv


回答1:


Yes, if you have a VARCHAR(512) column on the referencing table, the data will exist twice.

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. This is kind of what normalization is all about.




回答2:


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:

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:

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.




回答3:


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. This checksum field would contain the output of a hashing algorithm CRC32() or maybe MD5() of the larger column.



来源:https://stackoverflow.com/questions/1285417/mysql-table-with-only-a-varchar-as-a-foreign-key

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!