由于外键而在创建表期间出错

时间:2015-05-15 13:44:14

标签: mysql sql

我的数据库中已经有了table1。

表1:

CREATE TABLE `product` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `typename` varchar(255) DEFAULT NULL,
  `typecode` varchar(55) DEFAULT NULL,
  `parent1` int(11) DEFAULT NULL,
  `parent2` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `parent1` (`parent1`),
  KEY `parent2` (`parent2`)
) ENGINE=InnoDB AUTO_INCREMENT=396 DEFAULT CHARSET=latin1;

我尝试用外键创建第二个表,该表引用了product.typename

这是我用过的创建查询。

 CREATE TABLE measurements (
    id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    age_group varchar(20) NOT NULL,
    article_type varchar(255) DEFAULT NULL,
    dimension text ,
    createdOn int(11) NOT NULL,
    updatedOn int(11) NOT NULL,
    createdBy text NOT NULL,
    foreign KEY(article_type) references product(typename)
)ENGINE=InnoDB AUTO_INCREMENT=396 DEFAULT CHARSET=latin1;

但是这个表创建失败,出现以下错误。

  

ERROR 1215(HY000):无法添加外键约束

我已完成show engine innodb\g

------------------------
LATEST FOREIGN KEY ERROR
------------------------
2015-05-15 19:03:28 131f71000 Error in foreign key constraint of table db/measurements:
foreign KEY(article_type) references product(typename)
)ENGINE=InnoDB AUTO_INCREMENT=396 DEFAULT CHARSET=latin1:
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html
for correct foreign key definition.

有人可以指出我的问题以及第一列概念是什么?

2 个答案:

答案 0 :(得分:2)

参考列应为Primary key。在这里

foreign KEY(article_type) references product(typename)

您希望引用不是typename的{​​{1}}列。

要以正确的方式执行此操作,您应该像这样创建表PK

ProductType

然后您可以创建这样的参考:

CREATE TABLE `ProductType` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `typename` varchar(255) DEFAULT NULL,
  `typecode` varchar(55) DEFAULT NULL,
) ENGINE=InnoDB AUTO_INCREMENT=396 DEFAULT CHARSET=latin1;

不要忘记使用 CREATE TABLE measurements ( id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, age_group varchar(20) NOT NULL, IdProductType NOT NULL, dimension text , createdOn int(11) NOT NULL, updatedOn int(11) NOT NULL, createdBy text NOT NULL, foreign KEY(IdProductType) references ProductType(Id) )ENGINE=InnoDB AUTO_INCREMENT=396 DEFAULT CHARSET=latin1; 表格。 以上解决方案仅是建议,您必须自己考虑您的表结构。

答案 1 :(得分:0)

外键引用一个键。这通常是主键,但并非必须如此。但是,在您的情况下,您引用了一个未定义为键的列(typename)。这显示了一个设计缺陷。

您决定使用技术ID作为表的主键。你可以这样做。但如果你这样做,请记住两件事:

  1. 您已创建ID以便轻松链接表格。因此,不要通过其他列(例如typename)引用记录,而是通过其ID引用。
  2. 您仍必须确保表格的自然键是唯一的。
  3. 关于第2点:你桌子的自然键是什么?唯一标识记录的字段是什么(或除了技术创建的ID之外)?是typename吗? typename是产品的名称,是否必须是唯一的?或者是这个类型代码?无论是什么,给这个字段一个独特的约束,所以你不能在你的表中两次使用相同的产品。

    如果您根本没有使用技术ID,也许它可以帮助您学习设计数据库。试一试。

    请注意:请注意MySQL有一种使用关键字KEY的奇怪方式:

    create table t (col int key);
    

    这里KEY真正意味着表的主键。 col不能为null,col必须是唯一的。它简称:

    create table t (col int primary key);
    

    然而,

    create table t (col int, key(col));
    

    完全是另一回事。这里,KEY不是PRIMARY KEY的缩写,而是INDEX的同义词。 col可以为null,col不必是唯一的。因此,最好使用同义词INDEX向读者说清楚:

    create table t (col int, index(col));
    

    当您使用其他ID时,您甚至需要唯一索引:

    create table t (id int primary key, col int, unique index(col));
    

    create table t (id int, col int, primary key(id), unique index(col));