2012-01-12 69 views
0

引用我有两个表:MySQL的REPLACE行为不同于更新,如果主键是由外键

CREATE TABLE `category` (
    `category_id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `user_id` mediumint(8) unsigned NOT NULL, 
    `name` varchar(20) CHARACTER SET ascii NOT NULL, 
    `description` varchar(100) DEFAULT NULL, 
    `repeat_interval` tinyint(3) unsigned NOT NULL DEFAULT '0', 
    `color` mediumint(8) unsigned NOT NULL, 
    PRIMARY KEY (`category_id`), 
    KEY `id` (`user_id`), 
    CONSTRAINT `category_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

CREATE TABLE `event` (
    `event_id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `category_id` int(10) unsigned NOT NULL, 
    `name` varchar(20) CHARACTER SET ascii NOT NULL, 
    `description` varchar(100) DEFAULT NULL, 
    `repeat_interval` tinyint(3) unsigned NOT NULL DEFAULT '0', 
    `color` mediumint(8) unsigned NOT NULL, 
    `priority` tinyint(3) unsigned NOT NULL DEFAULT '0', 
    `start` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
    `end` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
    `done` tinyint(1) NOT NULL DEFAULT '0', 
    PRIMARY KEY (`event_id`), 
    KEY `category_id` (`category_id`), 
    CONSTRAINT `event_ibfk_1` FOREIGN KEY (`category_id`) REFERENCES `category`  (`category_id`) ON DELETE CASCADE 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

如果我的类别表(1行)进行REPLACE那么所有的条目在事件表中引用类别表中的修改行将被丢弃。

但是,如果我在类别表UPDATE一排,然后在事件表中的条目保持不变。

为什么这种行为,为什么当我REPLACE什么东西所有引用该列的条目都被丢弃?

我试着用ON UPDATE CASCADE和默认的相同的行为。

Google无法帮助我。

回答

2

你有ON DELETE CASCADE外键,而替换就是“删除然后插入新版本” - 看起来ON DELETE触发器被触发。

从MySQL文档:

更换作品酷似INSERT,不同之处在于,如果一个老行的 表具有相同的值PRIMARY KEY或一个UNIQUE 指数,老一新行行在插入新行之前被删除。请参阅 第12.2.5节“INSERT语法”。

我建议你阅读本:http://dev.mysql.com/doc/refman/5.0/en/replace.html

要解决这一点,你可能会想使用ON DUPLICATE KEY UPDATE插入语句:http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

1

取代的行为是删除,然后重新插入。当您尝试更新主键时这很有用。

我推测与foriegn关键的关系,你会得到一个删除层叠,然后插入到表中,但没有插入到外部表中。

1

您可能有ON DELETE CASCADE。 REPLACE删除category表中的记录,然后删除分配给该category的所有event记录。