添加两个外键时出现1215错误

时间:2015-01-07 20:09:53

标签: mysql foreign-keys

无法解决此问题(希望)最后一次错误

我在创建tournament_table时遇到1215错误但无法解释,是因为我尝试添加2个外键并且我做错了吗?那我该怎么办?我无法在互联网上找到一个令人满意的awnser。

如果我无法修复它,我脑中的堆栈会溢出

create table Poker_event
   (date_time       datetime    not null,
    min_players     int         not null,
    max_players     int         not null,
    house_number    int         not null, 
    postal_code     varchar(6)  not null,
primary key(date_time),
foreign key(house_number, postal_code)   references Location(house_number, postal_code) on delete cascade on update cascade);

create table Tournament
   (date_time   datetime    not null,
    prize       int         not null,
primary key(date_time),
foreign key(date_time)  references Poker_event(date_time) on delete no action on update cascade);

create table Tournament_round
   (round_nr    int       not null,
    date_time   datetime    not null,
primary key(date_time, round_nr),
foreign key(date_time)  references Tournament(date_time) on delete no action on update cascade);

create table Tournament_table
   (winner      int         not null,
    date_time   datetime    not null,
    round_nr    int         not null,
primary key(winner, date_time, round_nr),
foreign key(date_time)  references Tournament(date_time) on delete no action on update cascade,
foreign key(round_nr)   references Tournament_round(round_nr) on delete no action on update cascade)

2 个答案:

答案 0 :(得分:0)

round_nr不是Tournament

中的列

Tournament_table定义的最后一行:

 foreign key(round_nr) references Tournament(round_nr) 
                                  ^^^^^^^^^^^^^^^^^^^^

该引用列,它不存在。看起来您打算Tournament_table成为Tournament_round的孩子。你在Tournament_round上有一个复合主键(ugghhh),外键约束需要包含这两列:

foreign key(date_time, round_nr) references Tournament_round(date_time,round_nr)

此外,在第一个表定义(Tournament)中,有一个对表Poker_event的外键引用。我们没有看到引用的表,所以我们不知道这是否是一个问题。除了这两个问题之外,它看起来应该可行。


<强>后续

CREATE TABLE Tournament
( date_time   DATETIME    NOT NULL
, prize       INT         NOT NULL
, PRIMARY KEY(date_time)
-- , FOREIGN KEY(date_time) REFERENCES Poker_event(date_time) 
--     ON DELETE NO ACTION ON UPDATE CASCADE
);

CREATE TABLE Tournament_round
( round_nr    INT       NOT NULL
, date_time   DATETIME    NOT NULL
, PRIMARY KEY(date_time, round_nr)
, FOREIGN KEY(date_time) REFERENCES Tournament(date_time) 
    ON DELETE NO ACTION ON UPDATE CASCADE
);

CREATE TABLE Tournament_table
( winner      INT         NOT NULL
, date_time   DATETIME    NOT NULL
, round_nr    INT         NOT NULL
, PRIMARY KEY(winner, date_time, round_nr)
-- , FOREIGN KEY(date_time) REFERENCES Tournament(date_time)
--     ON DELETE NO ACTION ON UPDATE CASCADE
, FOREIGN KEY(date_time,round_nr) REFERENCES Tournament_round(date_time,round_nr) 
    ON DELETE NO ACTION ON UPDATE CASCADE
);

(默认存储引擎是InnoDB)

3 queries executed, 3 success, 0 errors, 0 warnings
Query: create table Tournament ( date_time datetime ...
0 row(s) affected
--------------------------------------------------
Query: create table Tournament_round ( round_nr int ...
0 row(s) affected
--------------------------------------------------
Query: create table Tournament_table ( winner int ...
0 row(s) affected

根据我使用关系数据库(DB2,Oracle,SQL Server,MySQL,MariaDB)的经验,我倾向于为每个“实体”表实现一个简单的代理主键。 (我区分“实体”表和其他表,例如“查找”(值列表)表,以及“关系”表,纯粹为解决多对多关系而添加的表。(纯关系表赢了)没有非关键属性,本身不会成为另一种关系中的实体。)

显然,我还没有为您正在处理的特定问题域进行数据分析和实体关系建模。但是根据您显示的表定义,这里是使用代理键的等效表定义的示例。 (在我看来,id列不会违反3NF或BCNF,因为它们将被视为“候选键”,而不是非键属性。请注意非匿名键属性,例如date_time已从子表中删除,因为这些属性 现在违反了3NF(因为它们不依赖于密钥。)

CREATE TABLE poker_event
( id             INT UNSIGNED NOT NULL PRIMARY KEY COMMENT 'pk' 
, location_id    INT UNSIGNED NOT NULL COMMENT 'fk ref location.id'
, date_time      DATETIME     NOT NULL COMMENT 'event start time'
, min_players    INT          NOT NULL COMMENT 'minimum number of players'
, max_players    INT          NOT NULL COMMENT 'maximum number of players'
, UNIQUE KEY poker_event_UX1(date_time)
, CONSTRAINT FK_poker_event_location
    FOREIGN KEY (location_id) REFERENCES location(id)
);

CREATE TABLE tournament
( id             INT UNSIGNED NOT NULL PRIMARY KEY COMMENT 'pk'
, poker_event_id INT UNSIGNED NOT NULL COMMENT 'fk ref poker_event.id'
, prize          INT          NOT NULL COMMENT 'prize'
, CONSTRAINT FK_tournament_poker_event
    FOREIGN KEY (poker_event_id) REFERENCES poker_event(id)
);

CREATE TABLE tournament_round
( id             INT UNSIGNED NOT NULL PRIMARY KEY COMMENT 'pk'
, tournament_id  INT UNSIGNED NOT NULL COMMENT 'fk ref tournament.id'
, round_nr       INT          NOT NULL COMMENT 'round number'
, UNIQUE KEY tournament_round_UX1(tournament_id,round_nr)
, CONSTRAINT FK_tournament_round_tournament
    FOREIGN KEY (tournament_id) REFERENCES tournament(id)
);

CREATE TABLE tournament_table
( id                  INT UNSIGNED NOT NULL PRIMARY KEY COMMENT 'pk'
, tournament_round_id INT UNSIGNED NOT NULL COMMENT 'fk ref tournament_round.id'
, winner              INT NOT NULL COMMENT 'winner'
, UNIQUE KEY tournament_table_UX1(tournament_round_id,winner)
, CONSTRAINT FK_tournament_table_tournament_round
    FOREIGN KEY (tournament_round_id) REFERENCES tournament_round(id)
);

答案 1 :(得分:0)

问题是

create table Tournament_table
   (winner      int         not null,
    date_time   datetime    not null,
    round_nr    int         not null,
primary key(winner, date_time, round_nr),
foreign key(date_time)  references Tournament(date_time) on delete no action on update cascade,
foreign key(round_nr)   references Tournament_round(round_nr) on delete no action on update cascade)

应该是

create table Tournament_table
   (winner      int         not null,
    date_time   datetime    not null,
    round_nr    int         not null,
primary key(winner, date_time, round_nr),
foreign key(date_time, round_nr)   references Tournament_round(date_time, round_nr) on delete no action on update cascade);
显然,这是一个复合键。