【问题标题】:MySQL: Error while creating foreign key, error 150 when it seems rightMySQL:创建外键时出错,看起来正确时出现错误 150
【发布时间】:2019-12-02 14:48:24
【问题描述】:

我必须创建一个数据库,这是 MySQL 代码:

    drop database if EXISTS BibliotecaLello;
create database BibliotecaLello;
use BibliotecaLello; 

create table Lettore
(
    CodiceFiscale varchar(17) PRIMARY KEY not null  
);

create TABLE Tessera 
(
    CodiceLettore varchar(17),
    CodiceTessera integer PRIMARY KEY not null AUTO_INCREMENT,
    Nome varchar(10) not null,
    Cognome varchar(10) not null,
    unique(Nome, Cognome)
);

create table Autori
(
    IDAutore integer PRIMARY KEY NOT null AUTO_INCREMENT,
    Nome varchar(20) not null,
    Cognome varchar(20) not null
);

create table Libro
(
    CodiceLibro integer AUTO_INCREMENT PRIMARY KEY not null,
    IDAutore integer not null,
    Titolo varchar(20) not null
);

create table Copia
(
    CodiceLibro integer not null,
    CodiceCopia integer not null,
    unique(CodiceLibro, CodiceCopia)
);

create table Noleggio
(
    CodiceLettore varchar(17) not null,
    DataInizio date not null,
    DataFine date not null,
    CodiceLibro integer not null,
    CodiceCopia integer not null,
    unique(CodiceLettore, DataInizio, DataFine, CodiceLibro, CodiceCopia)
);

alter table Noleggio add CONSTRAINT fkNolleggioLettore
FOREIGN key (CodiceLettore)
REFERENCES `Lettore`(`CodiceFiscale`) on DELETE CASCADE on UPDATE CASCADE;

alter table Tessera add CONSTRAINT fkTesseraLettori
FOREIGN KEY (`CodiceLettore`) 
REFERENCES `Lettore`(`CodiceFiscale`) on DELETE CASCADE on UPDATE cascade;

alter table Libro add CONSTRAINT fkLibroAutori
FOREIGN KEY (IDAutore)
REFERENCES `Autori`(`IDAutore`)  on DELETE CASCADE on UPDATE cascade;

alter table `Copia` add CONSTRAINT fkCopieLibro
FOREIGN KEY (CodiceLibro) 
REFERENCES Libro(CodiceLibro)  on DELETE CASCADE on UPDATE cascade;

alter table Noleggio add CONSTRAINT fkNoleggioCopiaCopia
FOREIGN KEY (CodiceCopia) 
REFERENCES `Copia`(`CodiceCopia`) on DELETE CASCADE on UPDATE cascade;

alter table Noleggio add CONSTRAINT fkNoleggioCopiaLibro
FOREIGN KEY (CodiceLibro) 
REFERENCES `Copia`(`CodiceLibro`) on DELETE CASCADE on UPDATE cascade;

但是当我执行时

alter table Noleggio add CONSTRAINT fkNoleggioCopiaCopia
FOREIGN KEY (CodiceCopia) 
REFERENCES `Copia`(`CodiceCopia`) on DELETE CASCADE on UPDATE cascade;

我明白了

ERROR 1005 (HY000): Can't create table `BibliotecaLello`.`#sql-2f7_2c2` (errno: 150 "Foreign key constraint is incorrectly formed")

我试过了

SHOW ENGINE INNODB STATUS

这是LATEST FOREIGN KEY ERROR

的结果
2019-12-02 14:37:25 75ea2340 Error in foreign key constraint of table `BibliotecaLello`.`Noleggio`:

FOREIGN KEY (CodiceCopia) 
REFERENCES `Copia`(`CodiceCopia`) on DELETE CASCADE on UPDATE cascade:
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.

我的老师告诉我,这意味着我正在更改错误的表格,但尝试使用两个表格仍然无法正常工作。 你能帮我解决这个问题吗?

【问题讨论】:

    标签: mysql sql database foreign-keys create-table


    【解决方案1】:

    当我运行这段代码时:

    alter table Noleggio add CONSTRAINT fkNoleggioCopiaCopia
    FOREIGN KEY (CodiceCopia) 
    REFERENCES `Copia`(`CodiceCopia`) on DELETE CASCADE on UPDATE cascade;
    

    它给了我错误:

    添加外键约束失败。引用表“Copia”中的约束“fkNoleggioCopiaCopia”缺少索引

    问题是,在引用的表中,列CodiceCopia 被定义为UNIQUE 键中的第二列:

    create table Copia
    (
        CodiceLibro integer not null,
        CodiceCopia integer not null,
        unique(CodiceLibro, CodiceCopia)
    );
    

    这是documented behavior

    外键约束受以下条件和限制:

    MySQL 需要外键和引用键的索引,以便外键检查可以快速且不需要表扫描。在引用表中,必须有一个索引,其中外键列按相同顺序列为 first 列。

    一个简单的解决办法是让它成为约束中的第一列,如下:

    create table Copia
    (
        CodiceLibro integer not null,
        CodiceCopia integer not null,
        unique(CodiceCopia, CodiceLibro)
    );
    

    旁注:最好在该表上设置适当的主键。

    Demo on DB Fiddle

    【讨论】:

    • 您的简单解决方案可能会解决眼前的问题 - 但我认为他的集合中的下一条语句将失败并出现相同的错误,因为现在引用的下一列“CodiceLibro”不是索引。
    • 也许fkNoleggioCopiaLibro 约束应该引用Libro
    猜你喜欢
    • 2022-11-14
    • 2019-05-06
    • 2010-11-30
    相关资源
    最近更新 更多