Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 为什么';从表中删除';忽略外键约束?_Mysql_Cascading Deletes - Fatal编程技术网

Mysql 为什么';从表中删除';忽略外键约束?

Mysql 为什么';从表中删除';忽略外键约束?,mysql,cascading-deletes,Mysql,Cascading Deletes,我有表格:作者和奖励(一对多关系)。我想制定下一条规则: 奖励有作者id的链接 如果有作者id外键,则限制删除奖励 当我删除作者时,我想从奖励表中为该作者id级联删除行 我用过 constraint foreign key (author_id) references authors (author_id) on delete cascade on update cascade 但无论如何,我可以从奖励中删除行或所有行。仅当我删除作者时,如何从奖励中删除 创建的表: create tab

我有表格:作者奖励(一对多关系)。我想制定下一条规则:

  • 奖励有作者id的链接
  • 如果有作者id外键,则限制删除奖励
  • 当我删除作者时,我想从奖励表中为该作者id级联删除行
我用过

constraint foreign key (author_id) 
references authors (author_id)
on delete cascade on update cascade
但无论如何,我可以从奖励中删除行或所有行。仅当我删除作者时,如何从奖励中删除

创建的表:

create table authors (
            author_id bigint not null auto_increment,
            birth_date datetime,
            first_name varchar(255),
            last_name varchar(255),
            sex varchar(10),
            primary key (author_id)
        );

create table rewards (
                reward_id bigint not null auto_increment,
                title varchar(255),
                year integer not null,
                author_id bigint not null,
                primary key (reward_id),
                constraint foreign key (author_id) references authors (author_id)
                on delete cascade on update cascade
                );
然后插入值:

    Insert into authors(
birth_date, first_name, last_name, sex) values
('1941-05-24', 'Bob', 'Dylan', 'male'),
('1870-10-22', 'Ivan', 'Bunin', 'male');

Insert into rewards(year, title, author_id) values 
(2016, 'Nobel Prize for Literature', 1),
(1933, 'Nobel Prize for Literature', 2),
(1903, 'Pushkin Prize', 2)
;

使用触发器很容易,但可能需要基于另一个表的覆盖选项

drop trigger if exists delete_rewards;
delimiter $$

CREATE DEFINER=`root`@`localhost` TRIGGER `delete_rewards` BEFORE delete ON `rewards` 
FOR EACH ROW 
begin
    declare msg varchar(100);
    declare found int;
    set found = 0;
    select count(*) into found from authors a where a.author_id = old.author_id;

    if found > 0 then
        set msg = 'Delete Not allowed';
        signal sqlstate '45000' set message_text = msg;
    end if;


END $$

delimiter ;

在制定约束条件时,如果不删除所有奖励,则无法删除作者。但您可以根据需要删除奖励。这是一种典型的一对多关系,one是作者,many是奖励。这是有道理的,因为只要有多个中的任何一个引用它,您就不想删除一个。 级联将起作用

若要防止对奖励记录的操纵,在分配奖励记录后,我建议使用触发器,并可能使用历史记录表


如果你想要一个奖励和多个作者,你必须扭转这种关系。因此,作者必须参考他们的奖励。如果是多对多,您将需要一个额外的表来处理此问题。但是看到您的最后一个条件,我怀疑情况并非如此。

“如果有作者id外键,则限制删除奖励”。由于author_id被定义为NOT NULL,这意味着您不能删除任何奖励,除非您删除整个author。是吗?我不明白这个问题。您会说:“如何避免从奖励中删除?”但就在上面,您指定要级联删除。@GordonLinoff是的,我的意思是我要限制
从奖励中删除,其中..
。并允许从中进行级联删除authors@Progman,是的,你是对的。@Nikolas为什么要阻止删除奖励?比如,你错加了一个奖励,然后你就陷入了“啊,废话……好吧……显然他现在获得了诺贝尔奖,对此我无能为力……”