【问题标题】:MySQL REPLACE behaves differently than UPDATE if the PRIMARY KEY is referenced by a FOREIGN KEY如果 PRIMARY KEY 被 FOREIGN KEY 引用,MySQL REPLACE 的行为与 UPDATE 不同
【发布时间】:2012-02-08 12:19:49
【问题描述】:

我有两张桌子:

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;

如果我在 category 表(一行)中创建了一个REPLACE,那么 event 表中的所有条目都会引用 category 中的修改行 表将被丢弃。

但是如果我UPDATE category 表中的一行,那么 event 表中的条目将保持不变。

为什么会出现这种行为,为什么当我 REPLACE 时,所有引用该列的条目都被丢弃了?

我尝试了ON UPDATE CASCADE 和默认的相同行为。

Google 帮不了我。

【问题讨论】:

    标签: mysql replace


    【解决方案1】:

    你有ON DELETE CASCADE 外键,替换只是“删除然后插入新版本” - 似乎触发了 ON DELETE 触发器。

    来自 Mysql 文档:

    REPLACE 的工作方式与 INSERT 完全相同,只是如果 table 与 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

    【讨论】:

      【解决方案2】:

      replace 的行为是删除和重新插入。这在您尝试更新主键时很有用。

      我假设与外键关系,你得到一个删除级联,然后插入到表中,但没有插入到外部表中。

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          【解决方案4】:

          我需要运行一次性升级脚本,所以我的解决方法是:

          1. 删除外键约束
          2. 运行我的“REPLACE INTO”语句
          3. 重新添加外键约束

          这不会作为代码中的永久解决方案,但它确实可以作为一种快速破解。

          【讨论】:

            猜你喜欢
            • 2012-11-20
            • 1970-01-01
            • 1970-01-01
            • 2016-11-12
            • 2023-03-06
            • 2021-05-14
            • 1970-01-01
            相关资源
            最近更新 更多