Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无法在MySQL 5.7中添加外键(引用表中缺少约束)_Mysql_Sql_Foreign Keys_Rdbms - Fatal编程技术网

无法在MySQL 5.7中添加外键(引用表中缺少约束)

无法在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

我正在尝试运行外键添加查询,如下所示,外键检查设置为0。两个表中的两列完全相同。而且,两者都是主键。这里的任何解决方案都无助于解决这个问题。我在本地主机上

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
表中的另一列引用交付地址。它不是两个键一起使用&使用两个键,而是两个列一起使用&使用两个列即一个键。