我正在尝试如下运行外键添加查询,并将外键检查设置为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>
您有一个复合主键-它由两个键together,(oid, primenumber)
组成。
您应该同时使用两个键来定义外键定义。
或者,定义一个自动递增的主键并使用它。
似乎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));
发表您的评论:
我现在认为您的真正问题是您的关系被逆转了。您正在尝试在引用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