我使用以下查询:
ALTER TABLE recent_article_entry ADD FOREIGN KEY (`article`) REFERENCES article(`id`);
或这个:
ALTER TABLE recent_article_entry ADD CONSTRAINT fk_rae_article FOREIGN KEY (article) REFERENCES article(id);
它说No errors; 1 row affected, taking 127 ms
。
哪一行受到影响?
如果转到information_schema.KEY_COLUMN_USAGE
,则看不到新生成的外键。如果我尝试添加到recent_article_entry
,则不会强制执行约束。
我很困惑 我试图通过将某些值更改为乱码来调试查询。
所以:
ALTER TABLE sldakjfalksdjf ADD FOREIGN KEY (`article`) REFERENCES article(`id`);
失败,并且
ALTER TABLE recent_article_entry ADD FOREIGN KEY (`aslkdjfalksjdf`) REFERENCES article(`id`);
按预期失败。
但是无论出于什么原因
ALTER TABLE recent_article_entry ADD FOREIGN KEY (`article`) REFERENCES aslkdjfdkf(`id`);
成功成功(以及将引用的列更改为乱码)。我以前做过很多外键。为什么MySQL突然忽略我的查询而不创建外键?
编辑根据ray的要求,这是describe语句的输出:
describe recent_article_entry
:
Field |Type |Null|Key|Default|Extra
-------------|-----------|----|---|-------|-----
article |varchar(55)|NO |PRI| |
file_location|varchar(55)|NO |PRI| |
describe article
Field |Type |Null |Key|Default |Extra
--------------|--------------|-----|---|-----------------|-----
id |varchar(55) |NO |PRI| |
title |varchar(255) |YES | |NULL |
author |varchar(55) |NO |MUL| |
translator |varchar(55) |NO |MUL| |
source |varchar(1000) |YES |MUL|0 |
published_flag|tinyint(1) |NO | | |
published |timestamp |YES | |CURRENT_TIMESTAMP|
short_title |varchar(55) |YES | |NULL |
describe file_location
Field |Type |Null |Key|Default |Extra
------|-----------|-----|---|-----------------|-----
id |varchar(55)|NO |PRI| |
views |int(11) |YES | |NULL |
而版本是5.1.56-log
在尝试在表之间创建FK约束时,我经常看到MySQL不够丰富。我几年前就被烧死的一个特定实例是所讨论列的表排序规则和/或字符串编码。它们必须在两个表中匹配。换句话说,您应该验证如果VARCHAR
某个表中的PK列A
正在使用latin1
编码,那么VARCHAR
某些表中的FK列B
也必须正在使用latin1
enconding而不是其他内容,例如utf8
。
在下一部分中,我将重现您的基本设置,但请确保表排序规则和列编码相同。就我而言,它们是默认的,但是您应该检查自己的数据库表以确保。
在旧版本的MySQL(您使用的是5.1,我使用的是5.7)中,默认存储引擎为MyISAM
。此存储引擎不 兼容ACID。因此,它不支持外键约束。您必须确保将每个表的存储引擎都设置为InnoDB。
您可以在MySQL配置文件中将其指定为默认值,也可以将其指定为create table
SQL语句的一部分。当前,这种情况似乎更有可能,因为您说查询没有产生错误消息。话虽如此,我不会立即回忆起先前的可能性是否产生了信息或保持沉默。
在下一部分中,我将证明这正常工作,至少对我来说,包括您提供的查询。
我试图重现您表的一些基础知识,足以在它们之间建立PK和FK。它们转载如下,包括以下create
语句:
mysql> create table `test`.`article` (
`id` varchar(55) not null,
`title` varchar(255) null default null,
primary key (`id`)
);
Query OK, 0 rows affected (0.42 sec)
mysql> create table `test`.`file_location` (
`id` varchar(55) not null,
`views` int(11) null default null,
primary key (`id`)
);
Query OK, 0 rows affected (0.35 sec)
mysql> create table `test`.`recent_article_entry` (
`article` varchar(55) not null,
`file_location` varchar(55) not null,
primary key (`article`, `file_location`)
);
Query OK, 0 rows affected (0.32 sec)
下表是describe
d:
mysql> show tables;
+----------------------+
| Tables_in_test |
+----------------------+
| article |
| file_location |
| recent_article_entry |
+----------------------+
3 rows in set (0.00 sec)
mysql> describe article;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | varchar(55) | NO | PRI | NULL | |
| title | varchar(255) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> describe file_location;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | varchar(55) | NO | PRI | NULL | |
| views | int(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> describe recent_article_entry;
+---------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| article | varchar(55) | NO | PRI | NULL | |
| file_location | varchar(55) | NO | PRI | NULL | |
+---------------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
在这里,我们在添加外键之前检查列的用法,并注意它们不会显示,因为它们尚不存在:
mysql> select TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from information_schema.KEY_COLUMN_USAGE;
+----------------------+---------------+-------------------------+-----------------------+------------------------+
| TABLE_NAME | COLUMN_NAME | REFERENCED_TABLE_SCHEMA | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME |
+----------------------+---------------+-------------------------+-----------------------+------------------------+
| article | id | NULL | NULL | NULL |
| file_location | id | NULL | NULL | NULL |
| recent_article_entry | article | NULL | NULL | NULL |
| recent_article_entry | file_location | NULL | NULL | NULL |
+----------------------+---------------+-------------------------+-----------------------+------------------------+
4 rows in set (0.00 sec)
我继续在测试数据库中使用以下查询创建FK:
alter table `test`.`recent_article_entry`
add constraint `fk_recent_article_entry_article_id`
foreign key (`article`)
references `test`.`article` (`id`)
on delete restrict
on update cascade,
add constraint `fk_recent_article_entry_file_location`
foreign key (`file_location`)
references `test`.`file_location` (`id`)
on delete restrict
on update cascade;
然后information_schema
,我像以前一样检查了。现在,您可以看到列出的约束:
mysql> select TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from information_schema.KEY_COLUMN_USAGE;
+----------------------+---------------+-------------------------+-----------------------+------------------------+
| TABLE_NAME | COLUMN_NAME | REFERENCED_TABLE_SCHEMA | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME |
+----------------------+---------------+-------------------------+-----------------------+------------------------+
| article | id | NULL | NULL | NULL |
| file_location | id | NULL | NULL | NULL |
| recent_article_entry | article | NULL | NULL | NULL |
| recent_article_entry | file_location | NULL | NULL | NULL |
| recent_article_entry | article | test | article | id |
| recent_article_entry | file_location | test | file_location | id |
+----------------------+---------------+-------------------------+-----------------------+------------------------+
6 rows in set (0.00 sec)
我知道我的查询与您的查询看起来有所不同,但是您的查询对我也很好,我将在下面显示。我删除了上面显示的FK,然后尝试输入自己的查询:
mysql> alter table recent_article_entry add foreign key (`article`) references article(`id`);
Query OK, 0 rows affected (0.56 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> select TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from information_schema.KEY_COLUMN_USAGE;
+----------------------+---------------+-------------------------+-----------------------+------------------------+
| TABLE_NAME | COLUMN_NAME | REFERENCED_TABLE_SCHEMA | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME |
+----------------------+---------------+-------------------------+-----------------------+------------------------+
| article | id | NULL | NULL | NULL |
| file_location | id | NULL | NULL | NULL |
| recent_article_entry | article | NULL | NULL | NULL |
| recent_article_entry | file_location | NULL | NULL | NULL |
| recent_article_entry | article | test | article | id |
+----------------------+---------------+-------------------------+-----------------------+------------------------+
如您所见,您自己的查询对我来说效果很好。如果您还有其他问题或发现您认为我可能会错过的问题,请在评论中让我知道。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句