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

问题描述 投票:0回答:3

我正在尝试如下运行外键添加查询,并将外键检查设置为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>
mysql sql foreign-keys rdbms
3个回答
0
投票

您有一个复合主键-它由两个键together(oid, primenumber)组成。

您应该同时使用两个键来定义外键定义。

或者,定义一个自动递增的主键并使用它。


0
投票

似乎productorder.oid是多列主键的一部分,它不是主键中最左边的列。 (将来,请包括SHOW CREATE TABLE <tablename>的结果,因为关于多列键之类的内容比DESCRIBE更清楚。)

声明外键时,必须引用主键的最左列。

当引用多列主键时,外键必须具有相同顺序的相同列数。

错误(列数不足,并且引用了主键的第二列):

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));

发表您的评论:

我现在认为您的真正问题是您的关系被逆转了。您正在尝试在引用deliveryaddressproductorder中声明一个外键,但我希望该引用会朝另一个方向发展。

ALTER TABLE productorder ADD FOREIGN KEY (oid) REFERENCES deliveryaddress (oid);

然后您就没有错误,因为deliveryaddress的主键只是一列。

我相信这种关系在典型的电子商务应用中更有意义。有很多订单可能引用相同的地址。相反的关系可能不是您想要的,因为对于许多地址引用单个产品订单来说,这毫无意义。


0
投票

我在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
© www.soinside.com 2019 - 2024. All rights reserved.