无法在MySQL 5.7中添加外键(引用表中缺少约束)
我正在尝试运行外键添加查询,如下所示,外键检查设置为0。两个表中的两列完全相同。而且,两者都是主键。这里的任何解决方案都无助于解决这个问题。我在本地主机上无法在MySQL 5.7中添加外键(引用表中缺少约束),mysql,sql,foreign-keys,rdbms,Mysql,Sql,Foreign Keys,Rdbms,我正在尝试运行外键添加查询,如下所示,外键检查设置为0。两个表中的两列完全相同。而且,两者都是主键。这里的任何解决方案都无助于解决这个问题。我在本地主机上 mysql> alter table deliveryaddress -> add foreign key(oid) references productorder(oid) -> on delete cascade on update restrict; ERROR 1822 (HY000): Failed
mysql> alter table deliveryaddress
-> add foreign key(oid) references productorder(oid)
-> on delete cascade on update restrict;
ERROR 1822 (HY000): Failed to add the foreign key constaint. Missing index for c
onstraint '' in the referenced table 'productorder'
mysql> desc productorder;
+----------------+--------------+------+-----+-------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+-------------------+-------+
| primenumber | varchar(15) | NO | PRI | NULL | |
| oid | varchar(10) | NO | PRI | NULL | |
| orderdatetime | timestamp | NO | | CURRENT_TIMESTAMP | |
| addressname | varchar(30) | NO | | NULL | |
| deliverycharge | decimal(8,2) | YES | | 20.00 | |
+----------------+--------------+------+-----+-------------------+-------+
5 rows in set (0.02 sec)
mysql> desc deliveryaddress;
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| oid | varchar(10) | NO | PRI | NULL | |
| pincode | varchar(8) | NO | | NULL | |
| area | varchar(60) | NO | | NULL | |
| city | varchar(60) | NO | | NULL | |
| state | varchar(60) | NO | | NULL | |
| landmark | varchar(60) | YES | | NULL | |
| phone | varchar(15) | NO | | NULL | |
| locality | varchar(60) | NO | | NULL | |
+----------+-------------+------+-----+---------+-------+
8 rows in set (0.00 sec)
mysql>
您有一个复合主键——它由两个键组成,
(oid,primenumber)
您应该使用两个键来定义外键定义
或者,定义一个自动递增的主键并使用它。它看起来像是
productorder。oid
是多列主键的一部分,而不是主键中最左边的列。(以后,请包括SHOW CREATE TABLE
的结果,因为它比描述多列键等内容更清楚。)
声明外键时,必须引用主键最左边的列
引用多列主键时,外键必须具有相同顺序的相同列数
错误(列不够,引用主键的第二列):
CREATE TABLE parent (x INT, y INT, PRIMARY KEY (x, y));
CREATE TABLE child (y INT, FOREIGN KEY (y) REFERENCES parent(y));
CREATE TABLE parent (x INT, y INT, PRIMARY KEY (x, y));
CREATE TABLE child (x INT, y INT,
FOREIGN KEY (x) REFERENCES parent(x),
FOREIGN KEY (y) REFERENCES parent(y)
);
CREATE TABLE parent (x INT, y INT, PRIMARY KEY (x, y));
CREATE TABLE child (x INT, y INT, FOREIGN KEY (x, y) REFERENCES parent(x, y));
错误(每个外键都引用复合主键的一部分):
CREATE TABLE parent (x INT, y INT, PRIMARY KEY (x, y));
CREATE TABLE child (y INT, FOREIGN KEY (y) REFERENCES parent(y));
CREATE TABLE parent (x INT, y INT, PRIMARY KEY (x, y));
CREATE TABLE child (x INT, y INT,
FOREIGN KEY (x) REFERENCES parent(x),
FOREIGN KEY (y) REFERENCES parent(y)
);
CREATE TABLE parent (x INT, y INT, PRIMARY KEY (x, y));
CREATE TABLE child (x INT, y INT, FOREIGN KEY (x, y) REFERENCES parent(x, y));
右侧(相同列):
CREATE TABLE parent (x INT, y INT, PRIMARY KEY (x, y));
CREATE TABLE child (y INT, FOREIGN KEY (y) REFERENCES parent(y));
CREATE TABLE parent (x INT, y INT, PRIMARY KEY (x, y));
CREATE TABLE child (x INT, y INT,
FOREIGN KEY (x) REFERENCES parent(x),
FOREIGN KEY (y) REFERENCES parent(y)
);
CREATE TABLE parent (x INT, y INT, PRIMARY KEY (x, y));
CREATE TABLE child (x INT, y INT, FOREIGN KEY (x, y) REFERENCES parent(x, y));
请回复您的评论: 我现在想你真正的问题是你的关系颠倒了。您试图在
deliveryaddress
引用productorder
中声明一个外键,但我希望引用指向另一个方向
ALTER TABLE productorder ADD FOREIGN KEY (oid) REFERENCES deliveryaddress (oid);
那么就没有错误了,因为deliveryaddress
的主键只是一列
我相信这种关系在典型的电子商务应用中更有意义。有许多订单可能引用同一地址。相反的关系可能不是您想要的,因为许多地址引用单个产品订单是没有意义的。我重新创建了表,其中索引位于
oid
,这会产生缺少索引的问题
mysql> create table productorder
-> (
-> primenumber varchar(15) not null,
-> oid varchar(10) not null,
-> orderdatetime timestamp not null default current_timestamp,
-> addressname varchar(30) not null,
-> deliverycharge decimal(8,2) not null default 20,
-> primary key(oid, primenumber), index(oid), index(primenumber),
-> foreign key(primenumber) references user(primenumber) on delete cascade
n update restrict
-> );
Query OK, 0 rows affected (1.52 sec)
mysql> alter table deliveryaddress
-> add foreign key(oid) references productorder(oid)
-> on delete cascade on update restrict;
Query OK, 0 rows affected (0.19 sec)
Records: 0 Duplicates: 0 Warnings: 0
当列需要引用不同的父表时,如何添加外键?但我认为这不适合您的应用程序。您已反转外键关系。请看我更新的答案。实际上,此表用于保存送货地址的记录,而不是用户地址的记录。此表仅供内部使用,一旦交付,地址将被删除。然后您需要在
productorder
表中的另一列引用交付地址。它不是两个键一起使用&使用两个键,而是两个列一起使用&使用两个列即一个键。