在具有多个架构的mysql更新中进行软删除

时间:2018-11-28 07:21:41

标签: mysql foreign-keys cascade cascading-deletes

我处于这种情况:

背景

  1. 我有2个数据库模式,分别称为“ prod”和“ stg”。
  2. “产品”包含2个称为“父”和“子”的表
  3. “ stg”仅具有“父”表
  4. “ prod”和“ stg”架构的“父”表定义相同。
  5. 在删除记录的情况下,“父”表被定义为软删除(在逻辑上删除,即将delete_flg设置为“ 1”),而“子”表是真正的删除(在物理上删除记录)

目标

我正在努力实现以下目标: 当且仅当“ prod”。“ parent”和“ stg”。“ parent”都被删除(无论是物理上还是逻辑上,或者不存在于一侧)时,才自动将删除操作(物理删除)级联到记录“ prod”。“ child”表中的“ SP_ID”与“ parent”中的值相匹配。

例如,假设我有

"prod"."parent"
+----+---------+--------+
| SP_ID | SP_NAME | DELETE_FLG |
+----+---------+--------+
|  1 |       1 |      1 |
+----+---------+--------+



"prod"."parent"
+----+---------+--------+
| SP_ID | SP_NAME | DELETE_FLG |
+----+---------+--------+
|  1 |       1 |      1 |
+----+---------+--------+

"stg"."parent"
+----+---------+--------+
| SP_ID | SP_NAME | DELETE_FLG |
+----+---------+--------+
|  1 |       1 |      0 |
+----+---------+--------+


"prod"."child"
+----+---------+
| SP_ID | JOB_KEY |
+----+---------+
|  1 |       key |
+----+---------+

,如果我执行sql更新“ stg”。“父”设置DELETE_FLG = 1,其中SP_ID = 1,这将逻辑删除具有SP_ID 1的“父”表中的最后一个“现有”记录,则“ prod“。” child“也将自动被mysql物理删除。

问题

我一直在考虑将子表中的SP_ID用作引用父级中的SP_ID的外键(https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html) 然而, a)我不知道是否可以在differnet模式中引用多个表,并且 b)似乎mysql仅支持级联相同的操作,即在父级上删除然后删除子级,或者在父级上更新然后再更新子级。但就我而言,我想更新父项,然后删除子项。

有人可以帮我吗? 这可以在mysql中实现吗?还是我必须在应用程序层中做到这一点?

表定义

CREATE TABLE `prod`.`parent` (
  `SP_ID` varchar(20) NOT NULL COMMENT '',
  `SP_NAME` varchar(100) NOT NULL COMMENT '',
  `DELETE_FLG` tinyint(1) NOT NULL DEFAULT '0' COMMENT '',
  PRIMARY KEY (`SP_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=''


CREATE TABLE `prod`.`child` (
  `SP_ID` varchar(20) NOT NULL COMMENT '',
  `JOB_KEY` varchar(11) NOT NULL,
  PRIMARY KEY (`SP_ID`,`JOB_KEY`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=''



CREATE TABLE `stg`.`parent` (
  `SP_ID` varchar(20) NOT NULL COMMENT '',
  `SP_NAME` varchar(100) NOT NULL COMMENT '',
  `DELETE_FLG` tinyint(1) NOT NULL DEFAULT '0' COMMENT '',
  PRIMARY KEY (`SP_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=''

1 个答案:

答案 0 :(得分:0)

提示使用触发器,这是我的有效解决方案: 向prod和stg父表添加2个触发器(一个在更新后,一个在删除后)。

# after update trigger
CREATE DEFINER=`root`@`localhost` TRIGGER `stg`.`parent_AFTER_UPDATE` AFTER UPDATE ON `parent` FOR EACH ROW
BEGIN
IF (
select
count(*)
from(
select 
*
from `prod`.`parent`
where `prod`.`parent`.id = old.id and `prod`.`parent`.delete_flg = 0
Union all
select 
*
from `stg`.`parent`
where `stg`.`parent`.id = old.id and `stg`.`parent`.delete_flg = 0
) as a
) = 0 THEN 
DELETE FROM `prod`.`child` WHERE `prod`.`child`.id = old.id;
END IF;
END



# after delete trigger
CREATE DEFINER=`root`@`localhost` TRIGGER `stg`.`parent_AFTER_DELETE` AFTER DELETE ON `parent` FOR EACH ROW
BEGIN
IF (
select
count(*)
from(
select 
*
from `prod`.`parent`
where `prod`.`parent`.id = old.id and `prod`.`parent`.delete_flg = 0
Union all
select 
*
from `stg`.`parent`
where `stg`.`parent`.id = old.id and `stg`.`parent`.delete_flg = 0
) as a
) = 0 THEN 
DELETE FROM `prod`.`child` WHERE `prod`.`child`.id = old.id;
END IF;
END