[英]MySQL table with a varchar column as foreign key
I am trying to create a table with a varchar column as foreign key but MySql gives me an error while creating the table.我正在尝试使用 varchar 列作为外键创建表,但是 MySql 在创建表时给了我一个错误。 My query is like this:
我的查询是这样的:
CREATE TABLE network_classes (
id TINYINT(1) UNSIGNED NOT NULL AUTO_INCREMENT,
category VARCHAR(80) NOT NULL,
PRIMARY KEY(id),
KEY `key_1` (`id`,`category`)
)
ENGINE=InnoDB;
CREATE TABLE networks (
id TINYINT(3) UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
category VARCHAR(80) NOT NULL,
director_id TINYINT(3) UNSIGNED NULL,
director_name VARCHAR(100) NULL,
description VARCHAR(1000) NULL,
last_modified TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
user_id SMALLINT UNSIGNED NULL,
PRIMARY KEY(id),
KEY `networks_fk1` (`category`),
CONSTRAINT `networks_fk1` FOREIGN KEY (`category`) REFERENCES `network_classes` (`category`) ON DELETE NO ACTION,
INDEX networks_index2471(name),
INDEX networks_index2472(director_id, director_name)
)
ENGINE=InnoDB;
and I get this error:我得到这个错误:
[Err] 1215 - Cannot add foreign key constraint
I am using MySQL 5.6.12.我正在使用 MySQL 5.6.12。 How can I rewrite my query to fix it?
如何重写我的查询来修复它?
You can only have a foreign key referencing a unique field. 您只能使用引用唯一字段的外键。 Modify your network_classes table so that the category field is unique, like below
修改您的network_classes表,以便类别字段是唯一的,如下所示
CREATE TABLE network_classes (
id TINYINT(1) UNSIGNED NOT NULL AUTO_INCREMENT,
category VARCHAR(80) NOT NULL,
PRIMARY KEY(id),
UNIQUE KEY `category_UNIQUE` (`category`),
KEY `key_1` (`id`,`category`)
)
ENGINE=InnoDB;
CREATE TABLE networks (
id TINYINT(3) UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
category VARCHAR(80) NOT NULL,
director_id TINYINT(3) UNSIGNED NULL,
director_name VARCHAR(100) NULL,
description VARCHAR(1000) NULL,
last_modified TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
user_id SMALLINT UNSIGNED NULL,
PRIMARY KEY(id),
KEY `networks_fk1` (`category`),
CONSTRAINT `networks_fk1` FOREIGN KEY (`category`) REFERENCES `network_classes` (`category`) ON DELETE NO ACTION,
INDEX networks_index2471(name),
INDEX networks_index2472(director_id, director_name)
)
ENGINE=InnoDB;
You should then be able to add the foreign key you want 然后,您应该能够添加所需的外键
column types in the table and the referenced table do not match for constraint
表中的列类型和引用的表与约束不匹配
Why 2 varchar columns with same size not match in type? 为什么2个相同大小的varchar列在类型上不匹配? And of course the answer is obvious collation.
当然答案是明显的整理。 Turns out that in the new table the column was UTF-8 instead of ASCII as in the referenced table.
事实证明,在新表中,列是UTF-8而不是引用表中的ASCII。 Changed to ascii and done.
改为ascii并完成。
The target of a FOREIGN KEY
constraint needs to be indexed. 需要索引
FOREIGN KEY
约束的目标。 Usually, it is a PRIMARY KEY
so this isn't an issue, but in your case it's not (although it's part of a composite key, that's not enough) 通常,它是一个
PRIMARY KEY
所以这不是问题,但在你的情况下它不是(虽然它是复合键的一部分,这还不够)
Create an index on your network_classes
. 在
network_classes
上创建索引。 category
field: category
字段:
CREATE INDEX category_idx ON network_classes(category);
Then re-create your networks
table. 然后重新创建您的
networks
表。
in 在
CONSTRAINT `networks_fk1` FOREIGN KEY (`category`)
REFERENCES `network_classess` (`category`) ON DELETE NO ACTION,
you have used network_classess instead of network_classes (as in your create table script), so that table not exists. 您使用了network_classess而不是network_classes (如在您的create table脚本中),因此该表不存在。
EDIT 编辑
Name of your constraint is the same of key (networks_fk1) change ones. 约束的名称与键(networks_fk1)更改约束的名称相同。
I read better your DDL. 我读得更好你的DDL。
Your table network_classes has a primary key ID, so is correct put as foreign key a field to link your id field, the category field mustn't appear in your table network, but I think you must put fk_network_class (as int) linked to id (of network_classes) 你的表network_classes有一个主键ID,所以正确把外键作为一个字段来链接你的id字段,类别字段不能出现在你的表网络中,但我认为你必须把fk_network_class(as int)链接到id (of network_classes)
For me, it was the charset that was missing.对我来说,缺少的是字符集。 Just providing an example for reference.
只是提供一个例子供参考。
CREATE TABLE `client` (
id
int NOT NULL, name
varchar(255) NOT NULL, email
varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, created_at
datetime NOT NULL, created_by
varchar(50) NOT NULL DEFAULT 'admin', updated_at
datetime NOT NULL, updated_by
varchar(50) NOT NULL DEFAULT 'admin', PRIMARY KEY ( id
), UNIQUE KEY name_UNIQUE
( name
), KEY name_idx
( name
) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 id
int NOT NULL, name
varchar(255) NOT NULL, email
varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, created_at
datetime NOT NULL, created_by
varchar(50) NOT NULL DEFAULT 'admin', updated_at
datetime NOT NULL, updated_by
varchar (50) NOT NULL 默认“管理员”,主键( id
),唯一键name_UNIQUE
( name
),键name_idx
( name
))引擎=InnoDB 默认字符集=latin1
create table `usecase` (`id` int NOT NULL AUTO_INCREMENT, `client` varchar(255) NOT NULL, `name` varchar(255), `description` varchar(1000), `rule_file` varchar(255), `parsed_rule_file` varchar(255), `archived` BOOLEAN DEFAULT 0, `state` ENUM('INITIATED','PARSED','UPLOADED', 'COMPLETE','FAILED'), `digest` varchar(255), `created_by` varchar(128) DEFAULT NULL, `created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), `updated_by` varchar(128) DEFAULT NULL, `updated_at` datetime(3) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uniq_usecase_id` (`client`,`name`), FOREIGN KEY (`client`) REFERENCES client(`name`))ENGINE=InnoDB DEFAULT CHARSET=latin1;
I had missed the line DEFAULT CHARSET=latin1我错过了 DEFAULT CHARSET=latin1 这一行
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.