17

我正在尝试创建一个以 varchar 列作为外键的表,但 MySql 在创建表时给了我一个错误。我的查询是这样的:

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;

我得到这个错误:

[Err] 1215 - Cannot add foreign key constraint

我正在使用 MySQL 5.6.12。如何重写我的查询来修复它?

4

4 回答 4

25

您只能有一个引用唯一字段的外键。修改您的 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;

然后你应该能够添加你想要的外键

于 2013-08-22T15:12:15.570 回答
10

表中的列类型和引用表中的约束不匹配

为什么 2 个大小相同的 varchar 列的类型不匹配?当然,答案是明显的整理。事实证明,在新表中,列是 UTF-8 而不是引用表中的 ASCII。更改为ASCII并完成。

于 2013-08-22T14:37:21.253 回答
3

约束的目标FOREIGN KEY需要被索引。通常,它是一个PRIMARY KEY所以这不是问题,但在你的情况下它不是(虽然它是复合键的一部分,但这还不够)

在您的network_classes. category场地:

CREATE INDEX category_idx ON network_classes(category);

然后重新创建你的networks表。

于 2013-08-22T15:05:47.390 回答
0

CONSTRAINT `networks_fk1` FOREIGN KEY (`category`)
REFERENCES `network_classess` (`category`) ON DELETE NO ACTION,

您使用了network_classess而不是network_classes(如在您的创建表脚本中),因此该表不存在。

编辑

您的约束名称与键 (networks_fk1) 更改名称相同。

我读得更好你的 DDL。

您的表 network_classes 有一个主键 ID,因此正确地将字段作为外键来链接您的 id 字段,类别字段不能出现在您的表网络中,但我认为您必须将 fk_network_class (作为 int)链接到 id (网络类)

于 2013-08-22T14:31:33.137 回答