MySQL不允许我向表添加外键。没有错误讯息

尼克·曼宁

我使用以下查询:

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

code_dredd

可能的原因-归类和编码

在尝试在表之间创建FK约束时,我经常看到MySQL不够丰富。我几年前就被烧死的一个特定实例是所讨论列的表排序规则和/或字符串编码。它们必须在两个表中匹配换句话说,您应该验证如果VARCHAR某个表中的PK列A正在使用latin1编码,那么VARCHAR某些表中FK列B也必须正在使用latin1enconding而不是其他内容,例如utf8

在下一部分中,我将重现您的基本设置,但请确保表排序规则和列编码相同。就我而言,它们是默认的,但是您应该检查自己的数据库表以确保。

可能的原因-存储引擎

在旧版本的MySQL(您使用的是5.1,我使用的是5.7)中,默认存储引擎为MyISAM此存储引擎 兼容ACID因此,它不支持外键约束。您必须确保将每个表的存储引擎都设置为InnoDB

您可以在MySQL配置文件中将其指定为默认值,也可以将其指定为create tableSQL语句的一部分当前,这种情况似乎更有可能,因为您说查询没有产生错误消息。话虽如此,我不会立即回忆起先前的可能性是否产生了信息或保持沉默。

在下一部分中,我将证明这正常工作,至少对我来说,包括您提供的查询。

创建表

我试图重现您表的一些基础知识,足以在它们之间建立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)

下表是described:

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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

SQL 不允许我添加外键?

我在 mysql 函数中有错误?ERROR 不允许从函数返回结果集

不允许添加外键

过时的MySQL WorkBench软件包有错误,不允许升级

映射(连接)创建表不允许外键?

向现有表添加外键

mysql表的列名是否有“不允许的”字符列表?

URLLoader不会从URLRequest加载数据。没有错误讯息

Rails应用程序外键错误:不允许管理用户删除以下用户:

SQL Server Management Studio不允许我为多个主键创建多个外键

sql-alchemy sqlite 数据库问题,不允许我创建外键

Xcode 不允许我添加 Outlets

Scala不允许我添加整数

keras不允许我添加图层

Swift 5破坏了我的本机模块导出,并带有错误Swift类扩展和Swift类上的类别不允许具有+ load方法

当我向django添加新语言时,没有错误,但没有显示我的翻译。为什么?

PrimeNG 数据表不允许向行添加组件

MySQL不允许我删除记录

Excel 2016不允许我向箱形图添加形状

向表添加外键

我无法添加外键:引用表中没有与外键中的引用列列表匹配的主键或候选键

向 DTD 中不允许的 xml 元素添加属性

不允许向类实例添加新属性

SqlParameter不允许使用表名-没有SQL注入攻击的其他选项?

键盘不允许我同时按下某些键

EF尽管我将外键列值设置为Nullable,但不允许Null

即使我添加了 AllowLoadLocalInfile,此 MySQL 版本也不允许使用使用的命令

XML声明之前,“序言中不允许内容”错误但仍然没有

Cython错误:没有GIL不允许来自Python的强制转换